diff --git a/DjVuFile/DjVu.cpp b/DjVuFile/DjVu.cpp index 83230701a6..b20426c129 100644 --- a/DjVuFile/DjVu.cpp +++ b/DjVuFile/DjVu.cpp @@ -121,3 +121,15 @@ BYTE* CDjVuFile::GetLinks (int nPageIndex) return m_pImplementation->GetPageLinks(nPageIndex); return NULL; } + +unsigned char* CDjVuFile::ConvertToPixels( + int nPageIndex, + int nRasterW, int nRasterH, bool bIsFlip, + NSFonts::IFontManager* pFonts, + int nBackgroundColor, bool bIsDarkMode, + int nBackgroundOpacity) +{ + if (m_pImplementation) + return m_pImplementation->ConvertToPixels(nPageIndex, nRasterW, nRasterH, !bIsFlip); + return NULL; +} diff --git a/DjVuFile/DjVu.h b/DjVuFile/DjVu.h index 3c1180e1e8..cd7b6d6a4f 100644 --- a/DjVuFile/DjVu.h +++ b/DjVuFile/DjVu.h @@ -76,4 +76,11 @@ public: virtual BYTE* GetStructure(); virtual BYTE* GetLinks (int nPageIndex); + + virtual unsigned char* ConvertToPixels( + int nPageIndex, + int nRasterW, int nRasterH, bool bIsFlip = false, + NSFonts::IFontManager* pFonts = NULL, + int nBackgroundColor = 0xFFFFFF, bool bIsDarkMode = false, + int nBackgroundOpacity = 0xFF); }; diff --git a/DjVuFile/DjVuFileImplementation.cpp b/DjVuFile/DjVuFileImplementation.cpp index c70ee7a2cd..523c0ab9a9 100644 --- a/DjVuFile/DjVuFileImplementation.cpp +++ b/DjVuFile/DjVuFileImplementation.cpp @@ -247,16 +247,11 @@ void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPag long lRendererType = c_nUnknownRenderer; pRenderer->get_Type(&lRendererType); - if (c_nPDFWriter == lRendererType) - { - XmlUtils::CXmlNode oText = ParseText(pPage); - CreatePdfFrame(pRenderer, pPage, nPageIndex, oText); - } - else - { - XmlUtils::CXmlNode oText = ParseText(pPage); - CreateFrame(pRenderer, pPage, nPageIndex, oText); - } + XmlUtils::CXmlNode text; + if (c_nPDFWriter == lRendererType || c_nHtmlRendrererText == lRendererType) + text = ParseText(pPage); + + CreateFrame(pRenderer, pPage, nPageIndex, text); } catch (...) { @@ -461,9 +456,14 @@ void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP& p } int nDpi = pPage->get_dpi(); - double dPixToMM = 25.4; + if (c_nHtmlRendrererText == lRendererType && text.IsValid()) + { + TextToRenderer(pRenderer, text, dPixToMM / nDpi); + return; + } + double dRendDpiX = 0; double dRendDpiY = 0; @@ -489,150 +489,22 @@ void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP& p LONG lImageWidth = (LONG)(dRendDpiX * dRendWidth / dPixToMM); LONG lImageHeight = (LONG)(dRendDpiY * dRendHeight / dPixToMM); - BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth]; + BYTE* pBufferDst = this->ConvertToPixels(pPage, lImageWidth, lImageHeight, false); + if (!pBufferDst) return; - bool bIsInit = false; - Aggplus::CImage oImage; oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth); - if (pPage->is_legal_photo() || pPage->is_legal_compound()) - { - bIsInit = true; - GRect oRectAll(0, 0, lImageWidth, lImageHeight); - GP pImage = pPage->get_pixmap(oRectAll, oRectAll); - - BYTE* pBuffer = pBufferDst; - for (int j = lImageHeight - 1; j >= 0; --j) - { - GPixel* pLine = pImage->operator [](j); - - for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) - { - pBuffer[0] = pLine->b; - pBuffer[1] = pLine->g; - pBuffer[2] = pLine->r; - pBuffer[3] = 255; - } - } - } - else if (pPage->is_legal_bilevel()) - { - bIsInit = true; - GRect oRectAll(0, 0, lImageWidth, lImageHeight); - GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); - int nPaletteEntries = pBitmap->get_grays(); - - unsigned int* palette = new unsigned int[nPaletteEntries]; - - // Create palette for the bitmap - int color = 0xff0000; - int decrement = color / (nPaletteEntries - 1); - for (int i = 0; i < nPaletteEntries; ++i) - { - BYTE level = (BYTE)(color >> 16); - palette[i] = (0xFF000000 | level << 16 | level << 8 | level); - color -= decrement; - } - - unsigned int* pBuffer = (unsigned int*)pBufferDst; - for (int j = lImageHeight - 1; j >= 0; --j) - { - BYTE* pLine = pBitmap->operator [](j); - - for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) - { - if (*pLine < nPaletteEntries) - { - *pBuffer = palette[*pLine]; - } - else - { - *pBuffer = palette[0]; - } - } - } - - RELEASEARRAYOBJECTS(palette); - } - else - { - // белый фрейм?? - //memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight); - GRect oRectAll(0, 0, lImageWidth, lImageHeight); - GP pImage = pPage->get_pixmap(oRectAll, oRectAll); - - if (NULL != pImage) - { - bIsInit = true; - BYTE* pBuffer = pBufferDst; - for (int j = lImageHeight - 1; j >= 0; --j) - { - GPixel* pLine = pImage->operator [](j); - - for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) - { - pBuffer[0] = pLine->b; - pBuffer[1] = pLine->g; - pBuffer[2] = pLine->r; - pBuffer[3] = 255; - } - } - } - else - { - GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); - - if (NULL != pBitmap) - { - bIsInit = true; - int nPaletteEntries = pBitmap->get_grays(); - - unsigned int* palette = new unsigned int[nPaletteEntries]; - - // Create palette for the bitmap - int color = 0xff0000; - int decrement = color / (nPaletteEntries - 1); - for (int i = 0; i < nPaletteEntries; ++i) - { - BYTE level = (BYTE)(color >> 16); - palette[i] = (0xFF000000 | level << 16 | level << 8 | level); - color -= decrement; - } - - unsigned int* pBuffer = (unsigned int*)pBufferDst; - for (int j = lImageHeight - 1; j >= 0; --j) - { - BYTE* pLine = pBitmap->operator [](j); - - for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) - { - if (*pLine < nPaletteEntries) - { - *pBuffer = palette[*pLine]; - } - else - { - *pBuffer = palette[0]; - } - } - } - - RELEASEARRAYOBJECTS(palette); - } - } - } pRenderer->BeginCommand(c_nPageType); - if (c_nGrRenderer != lRendererType && c_nHtmlRendrerer != lRendererType && c_nHtmlRendrerer2 != lRendererType) + if (text.IsValid()) { TextToRenderer(pRenderer, text, dPixToMM / nDpi); } - if (bIsInit) - pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dRendWidth, dRendHeight); + pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dRendWidth, dRendHeight); pRenderer->EndCommand(c_nPageType); } void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP& pPage, int nPageIndex, XmlUtils::CXmlNode& oText) @@ -847,6 +719,104 @@ void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP pRenderer->EndCommand(c_nPageType); } +unsigned char* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip) +{ + try + { + GP pPage = m_pDoc->get_page(nPageIndex); + //pPage->wait_for_complete_decode(); + pPage->set_rotate(0); + return ConvertToPixels(pPage, nRasterW, nRasterH, bIsFlip); + } + catch (...) + { + } + return NULL; +} + +unsigned char* CDjVuFileImplementation::ConvertToPixels(GP& pPage, int nImageW, int nImageH, bool bFlip) +{ + BYTE* pBufferDst = NULL; + + auto processPixmap = [&](GP pImage, bool bFlip = false) + { + pBufferDst = new BYTE[4 * nImageW * nImageH]; + + unsigned int* pBuffer = (unsigned int*)pBufferDst; + for (int j = 0; j < nImageH; ++j) + { + int nRow = bFlip ? j : (nImageH - 1 - j); + GPixel* pLine = pImage->operator[](nRow); + for (int i = 0; i < nImageW; ++i) + { + *pBuffer++ = 0xFF000000 | pLine->r << 16 | pLine->g << 8 | pLine->b; + ++pLine; + } + } + }; + + auto processBitmap = [&](GP pBitmap, bool bFlip = false) + { + pBufferDst = new BYTE[4 * nImageW * nImageH]; + + int nPaletteEntries = pBitmap->get_grays(); + unsigned int* palette = new unsigned int[nPaletteEntries]; + int color = 0xFF0000; + int decrement = color / (nPaletteEntries - 1); + for (int i = 0; i < nPaletteEntries; ++i) + { + BYTE level = (BYTE)(color >> 16); + palette[i] = (0xFF000000 | level << 16 | level << 8 | level); + color -= decrement; + } + + unsigned int* pBuffer = (unsigned int*)pBufferDst; + for (int j = 0; j < nImageH; ++j) + { + int nRow = bFlip ? j : (nImageH - 1 - j); + BYTE* pLine = pBitmap->operator[](nRow); + for (int i = 0; i < nImageW; ++i) + { + *pBuffer++ = palette[*pLine < nPaletteEntries ? *pLine : 0]; + ++pLine; + } + } + + RELEASEARRAYOBJECTS(palette); + }; + + GRect oRectAll(0, 0, nImageW, nImageH); + + if (pPage->is_legal_photo() || pPage->is_legal_compound()) + { + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + processPixmap(pImage, bFlip); + } + else if (pPage->is_legal_bilevel()) + { + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + processBitmap(pBitmap, bFlip); + } + else + { + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + if (pImage) + { + processPixmap(pImage, bFlip); + } + else + { + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + if (pBitmap) + { + processBitmap(pBitmap, bFlip); + } + } + } + + return pBufferDst; +} + XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP pPage) { XmlUtils::CXmlNode paragraph; diff --git a/DjVuFile/DjVuFileImplementation.h b/DjVuFile/DjVuFileImplementation.h index 946616058b..785fbf8183 100644 --- a/DjVuFile/DjVuFileImplementation.h +++ b/DjVuFile/DjVuFileImplementation.h @@ -79,8 +79,12 @@ public: BYTE* GetPageGlyphs(int nPageIndex); BYTE* GetPageLinks (int nPageIndex); + unsigned char* ConvertToPixels(int nPageIndex, int nRasterW, int nRasterH, bool bIsFlip = false); + private: + unsigned char* ConvertToPixels(GP& pPage, int nRasterW, int nRasterH, bool bIsFlip = false); + void CreateFrame(IRenderer* pRenderer, GP& pImage, int nPage, XmlUtils::CXmlNode& oText); void CreatePdfFrame(IRenderer* pRenderer, GP& pImage, int nPage, XmlUtils::CXmlNode& oText); XmlUtils::CXmlNode ParseText(GP pPage); diff --git a/DjVuFile/libdjvu/DjVuDocument.cpp b/DjVuFile/libdjvu/DjVuDocument.cpp index ba89899d4b..71dee3210c 100644 --- a/DjVuFile/libdjvu/DjVuDocument.cpp +++ b/DjVuFile/libdjvu/DjVuDocument.cpp @@ -1943,15 +1943,15 @@ void DjVuDocument::ReadPageInfo(int nPage, int& width, int& height, int& nDpi) bHasIW44 = true; // Get image dimensions and resolution from bitmap chunk - UINT serial = chunk_stream->read8(); - UINT slices = chunk_stream->read8(); - UINT major = chunk_stream->read8(); - UINT minor = chunk_stream->read8(); + unsigned int serial = chunk_stream->read8(); + unsigned int slices = chunk_stream->read8(); + unsigned int major = chunk_stream->read8(); + unsigned int minor = chunk_stream->read8(); - UINT xhi = chunk_stream->read8(); - UINT xlo = chunk_stream->read8(); - UINT yhi = chunk_stream->read8(); - UINT ylo = chunk_stream->read8(); + unsigned int xhi = chunk_stream->read8(); + unsigned int xlo = chunk_stream->read8(); + unsigned int yhi = chunk_stream->read8(); + unsigned int ylo = chunk_stream->read8(); width = (xhi << 8) | xlo; height = (yhi << 8) | ylo;