mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63314 954022d7-b5bf-4e40-9824-e11837661b57
911 lines
24 KiB
C++
911 lines
24 KiB
C++
#include "DjVuFileImplementation.h"
|
||
|
||
#include "../DesktopEditor/common/File.h"
|
||
#include "../DesktopEditor/common/Directory.h"
|
||
#include "../DesktopEditor/graphics/IRenderer.h"
|
||
#include "../DesktopEditor/raster/BgraFrame.h"
|
||
#include "../DesktopEditor/graphics/Image.h"
|
||
#include "../DesktopEditor/common/String.h"
|
||
|
||
#include "../DesktopEditor/fontengine/FontManager.h"
|
||
#include "../DesktopEditor/fontengine/ApplicationFonts.h"
|
||
#include "../DesktopEditor/raster/BgraFrame.h"
|
||
#include "../DesktopEditor/graphics/GraphicsRenderer.h"
|
||
|
||
#include "../PdfWriter/PdfRenderer.h"
|
||
#include "../DesktopEditor/raster/JBig2/source/Encoder/jbig2enc.h"
|
||
#include "../DesktopEditor/raster/JBig2/source/LeptonLib/allheaders.h"
|
||
|
||
#define VER_DPI 96
|
||
#define HOR_DPI 96
|
||
|
||
#include <vector>
|
||
|
||
namespace NSDjvu
|
||
{
|
||
static GUTF8String MakeUTF8String(const std::wstring& wsText)
|
||
{
|
||
std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsText);
|
||
GUTF8String utf8String(sText.c_str());
|
||
return utf8String;
|
||
}
|
||
static CString MakeCString(GUTF8String& strText)
|
||
{
|
||
std::string sString(strText.getbuf());
|
||
std::wstring wsString = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sString.c_str(), sString.length());
|
||
return CString(wsString.c_str());
|
||
}
|
||
static int GetInteger(const std::wstring& wsString)
|
||
{
|
||
if (wsString.size() < 1)
|
||
return 0;
|
||
|
||
try
|
||
{
|
||
return _ttoi(wsString.c_str());
|
||
}
|
||
catch (...)
|
||
{
|
||
}
|
||
|
||
try
|
||
{
|
||
return static_cast<int>(_wtoi64(wsString.c_str()));
|
||
}
|
||
catch (...)
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
CDjVuFileImplementation::CDjVuFileImplementation()
|
||
{
|
||
m_pDoc = NULL;
|
||
std::wstring wsTempPath = NSFile::CFileBinary::GetTempPath();
|
||
wsTempPath += L"DJVU\\";
|
||
m_wsTempDirectory = wsTempPath;
|
||
NSDirectory::CreateDirectory(m_wsTempDirectory);
|
||
}
|
||
CDjVuFileImplementation::~CDjVuFileImplementation()
|
||
{
|
||
NSDirectory::DeleteDirectory(m_wsTempDirectory);
|
||
}
|
||
bool CDjVuFileImplementation::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXMLOptions)
|
||
{
|
||
m_pDoc = NULL;
|
||
try
|
||
{
|
||
GUTF8String utf8;
|
||
GURL url = GURL::Filename::UTF8(NSDjvu::MakeUTF8String(wsSrcFileName));
|
||
m_pDoc = DjVuDocument::create(url);
|
||
m_pDoc->wait_get_pages_num();
|
||
}
|
||
catch (...)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
void CDjVuFileImplementation::Close()
|
||
{
|
||
}
|
||
std::wstring CDjVuFileImplementation::GetTempDirectory() const
|
||
{
|
||
return m_wsTempDirectory;
|
||
}
|
||
void CDjVuFileImplementation::SetTempDirectory(const std::wstring& wsDirectory)
|
||
{
|
||
NSDirectory::DeleteDirectory(m_wsTempDirectory);
|
||
|
||
m_wsTempDirectory = wsDirectory;
|
||
m_wsTempDirectory += L"\\DJVU\\";
|
||
NSDirectory::CreateDirectory(m_wsTempDirectory);
|
||
}
|
||
int CDjVuFileImplementation::GetPagesCount() const
|
||
{
|
||
if (!m_pDoc)
|
||
return 0;
|
||
|
||
return m_pDoc->get_pages_num();
|
||
}
|
||
void CDjVuFileImplementation::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const
|
||
{
|
||
if (!m_pDoc)
|
||
{
|
||
*pdWidth = 0;
|
||
*pdHeight = 0;
|
||
|
||
*pdDpiX = 96;
|
||
*pdDpiY = 96;
|
||
}
|
||
|
||
GP<DjVuImage> pPage = m_pDoc->get_page(nPageIndex);
|
||
|
||
pPage->wait_for_complete_decode();
|
||
pPage->set_rotate(0);
|
||
|
||
*pdWidth = pPage->get_real_width();
|
||
*pdHeight = pPage->get_real_height();
|
||
|
||
*pdDpiX = pPage->get_dpi();
|
||
*pdDpiY = pPage->get_dpi();
|
||
}
|
||
void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak)
|
||
{
|
||
if (!m_pDoc)
|
||
return;
|
||
|
||
try
|
||
{
|
||
GP<DjVuImage> pPage = m_pDoc->get_page(nPageIndex);
|
||
pPage->wait_for_complete_decode();
|
||
pPage->set_rotate(0);
|
||
|
||
long lRendererType = c_nUnknownRenderer;
|
||
pRenderer->get_Type(&lRendererType);
|
||
if (false)//c_nGrRenderer == lRendererType)
|
||
{
|
||
CreateGrFrame(pRenderer, pPage, pBreak);
|
||
}
|
||
else 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);
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
}
|
||
void CDjVuFileImplementation::ConvertToRaster(CApplicationFonts* pAppFonts, int nPageIndex, const std::wstring& wsDstPath, int nImageType)
|
||
{
|
||
CFontManager *pFontManager = pAppFonts->GenerateFontManager();
|
||
CFontsCache* pFontCache = new CFontsCache();
|
||
pFontCache->SetStreams(pAppFonts->GetStreams());
|
||
pFontManager->SetOwnerCache(pFontCache);
|
||
|
||
CGraphicsRenderer oRenderer;
|
||
oRenderer.SetFontManager(pFontManager);
|
||
|
||
double dPageDpiX, dPageDpiY;
|
||
double dWidth, dHeight;
|
||
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiX);
|
||
|
||
int nWidth = (int)dWidth * 96 / dPageDpiX;
|
||
int nHeight = (int)dHeight * 96 / dPageDpiX;
|
||
|
||
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
|
||
if (!pBgraData)
|
||
return;
|
||
|
||
memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||
CBgraFrame oFrame;
|
||
oFrame.put_Data(pBgraData);
|
||
oFrame.put_Width(nWidth);
|
||
oFrame.put_Height(nHeight);
|
||
oFrame.put_Stride(-4 * nWidth);
|
||
|
||
oRenderer.CreateFromBgraFrame(&oFrame);
|
||
oRenderer.SetSwapRGB(false);
|
||
oRenderer.put_Width(dWidth);
|
||
oRenderer.put_Height(dHeight);
|
||
|
||
bool bBreak = false;
|
||
DrawPageOnRenderer(&oRenderer, nPageIndex, &bBreak);
|
||
|
||
oFrame.SaveFile(wsDstPath, nImageType);
|
||
RELEASEINTERFACE(pFontManager);
|
||
}
|
||
void CDjVuFileImplementation::ConvertToPdf(CApplicationFonts* pAppFonts, const std::wstring& wsDstPath)
|
||
{
|
||
CPdfRenderer oPdf(pAppFonts);
|
||
|
||
bool bBreak = false;
|
||
for (int nPageIndex = 0, nPagesCount = GetPagesCount(); nPageIndex < nPagesCount; nPageIndex++)
|
||
{
|
||
oPdf.NewPage();
|
||
|
||
double dPageDpiX, dPageDpiY;
|
||
double dWidth, dHeight;
|
||
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);
|
||
dWidth *= 25.4 / dPageDpiX;
|
||
dHeight *= 25.4 / dPageDpiY;
|
||
oPdf.put_Width(dWidth);
|
||
oPdf.put_Height(dHeight);
|
||
|
||
DrawPageOnRenderer(&oPdf, nPageIndex, &bBreak);
|
||
#ifdef _DEBUG
|
||
printf("%d of %d pages\n", nPageIndex + 1, nPagesCount);
|
||
#endif
|
||
}
|
||
|
||
oPdf.SaveToFile(wsDstPath);
|
||
}
|
||
void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
|
||
{
|
||
int nWidth = pPage->get_real_width();
|
||
int nHeight = pPage->get_real_height();
|
||
|
||
int nDpi = pPage->get_dpi();
|
||
|
||
double dPixToMM = 25.4;
|
||
|
||
double dRendDpiX = 0;
|
||
double dRendDpiY = 0;
|
||
|
||
pRenderer->get_DpiX(&dRendDpiX);
|
||
pRenderer->get_DpiY(&dRendDpiY);
|
||
|
||
if (0 >= dRendDpiX)
|
||
dRendDpiX = 72.0;
|
||
if (0 >= dRendDpiY)
|
||
dRendDpiY = 72.0;
|
||
|
||
double dRendWidth = 0;
|
||
double dRendHeight = 0;
|
||
|
||
pRenderer->get_Width(&dRendWidth);
|
||
pRenderer->get_Height(&dRendHeight);
|
||
|
||
if (0 >= dRendWidth)
|
||
dRendWidth = 200;
|
||
if (0 >= dRendHeight)
|
||
dRendHeight = 300;
|
||
|
||
LONG lImageWidth = (LONG)(dRendDpiX * dRendWidth / dPixToMM);
|
||
LONG lImageHeight = (LONG)(dRendDpiY * dRendHeight / dPixToMM);
|
||
|
||
long lRendererType = c_nUnknownRenderer;
|
||
pRenderer->get_Type(&lRendererType);
|
||
if (c_nPDFWriter == lRendererType)
|
||
{
|
||
lImageWidth = pPage->get_real_width();
|
||
lImageHeight = pPage->get_real_height();
|
||
}
|
||
else if (c_nHtmlRendrerer == lRendererType)
|
||
{
|
||
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// pRenderer->GetMaxImageSize();
|
||
//VARIANT var;
|
||
//renderer->GetAdditionalParam(L"MaxImageSize", &var);
|
||
//LONG lMaxWidth = var.lVal;
|
||
//if ((lImageWidth > lMaxWidth) || (lImageHeight > lMaxWidth))
|
||
//{
|
||
// double dAspect = (double)(lImageWidth) / lImageHeight;
|
||
// if (lImageWidth > lImageHeight)
|
||
// {
|
||
// lImageWidth = lMaxWidth;
|
||
// lImageHeight = (LONG)(lImageHeight / dAspect);
|
||
// }
|
||
// else
|
||
// {
|
||
// lImageHeight = lMaxWidth;
|
||
// lImageWidth = (LONG)(dAspect * lImageHeight);
|
||
// }
|
||
//}
|
||
}
|
||
|
||
BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth];
|
||
if (!pBufferDst)
|
||
return;
|
||
|
||
Aggplus::CImage oImage;
|
||
oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth);
|
||
if (pPage->is_legal_photo() || pPage->is_legal_compound())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> 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())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
DWORD* palette = new DWORD[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;
|
||
}
|
||
|
||
DWORD* pBuffer = (DWORD*)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
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>??
|
||
//memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight);
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||
|
||
if (NULL != pImage)
|
||
{
|
||
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<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
|
||
if (NULL != pBitmap)
|
||
{
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
DWORD* palette = new DWORD[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;
|
||
}
|
||
|
||
DWORD* pBuffer = (DWORD*)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)
|
||
{
|
||
TextToRenderer(pRenderer, text, dPixToMM / nDpi);
|
||
}
|
||
|
||
pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dRendWidth, dRendHeight);
|
||
pRenderer->EndCommand(c_nPageType);
|
||
}
|
||
void CDjVuFileImplementation::CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPageIndex, XmlUtils::CXmlNode& oText)
|
||
{
|
||
double dPageDpiX, dPageDpiY;
|
||
double dWidth, dHeight;
|
||
GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);
|
||
dWidth *= 25.4 / dPageDpiX;
|
||
dHeight *= 25.4 / dPageDpiY;
|
||
|
||
pRenderer->BeginCommand(c_nPageType);
|
||
|
||
TextToRenderer(pRenderer, oText, 25.4 / pPage->get_dpi());
|
||
|
||
LONG lImageWidth = pPage->get_real_width();
|
||
LONG lImageHeight = pPage->get_real_height();
|
||
|
||
CPdfRenderer* pPdf = (CPdfRenderer*)pRenderer;
|
||
|
||
if (pPage->is_legal_photo())
|
||
{
|
||
BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth];
|
||
if (!pBufferDst)
|
||
return;
|
||
|
||
Aggplus::CImage oImage;
|
||
oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth);
|
||
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> 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;
|
||
}
|
||
}
|
||
pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight);
|
||
}
|
||
else if (pPage->is_legal_compound())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<IW44Image> pIW44Image = pPage->get_bg44();
|
||
if (NULL != pIW44Image)
|
||
{
|
||
int nBgWidth = pIW44Image->get_width();
|
||
int nBgHeight = pIW44Image->get_height();
|
||
|
||
GP<GPixmap> pBgImage = pIW44Image->get_pixmap();
|
||
if (NULL != pBgImage)
|
||
{
|
||
BYTE* pBgBuffer = new BYTE[4 * nBgWidth * nBgHeight];
|
||
if (!pBgBuffer)
|
||
return;
|
||
|
||
Aggplus::CImage oBgImage;
|
||
oBgImage.Create(pBgBuffer, nBgWidth, nBgHeight, 4 * nBgWidth);
|
||
|
||
BYTE* pBuffer = pBgBuffer;
|
||
for (int j = nBgHeight - 1; j >= 0; --j)
|
||
{
|
||
GPixel* pLine = pBgImage->operator [](j);
|
||
|
||
for (int i = 0; i < nBgWidth; ++i, pBuffer += 4, ++pLine)
|
||
{
|
||
pBuffer[0] = pLine->b;
|
||
pBuffer[1] = pLine->g;
|
||
pBuffer[2] = pLine->r;
|
||
pBuffer[3] = 255;
|
||
}
|
||
}
|
||
pRenderer->DrawImage((IGrObject*)&oBgImage, 0, 0, dWidth, dHeight);
|
||
}
|
||
}
|
||
|
||
GP<GPixmap> pImage = pPage->get_fgpm();
|
||
if (NULL == pImage)
|
||
pImage = pPage->get_fg_pixmap(oRectAll);
|
||
|
||
if (NULL != pImage)
|
||
{
|
||
unsigned int unPixmapH = pImage->rows();
|
||
unsigned int unPixmapW = pImage->columns();
|
||
BYTE* pBufferDst = new BYTE[4 * unPixmapH * unPixmapW];
|
||
if (!pBufferDst)
|
||
return;
|
||
|
||
Aggplus::CImage oImage;
|
||
oImage.Create(pBufferDst, unPixmapW, unPixmapH, 4 * unPixmapW);
|
||
|
||
BYTE* pBuffer = pBufferDst;
|
||
for (int j = unPixmapH - 1; j >= 0; --j)
|
||
{
|
||
GPixel* pLine = pImage->operator [](j);
|
||
|
||
for (int i = 0; i < unPixmapW; ++i, pBuffer += 4, ++pLine)
|
||
{
|
||
pBuffer[0] = pLine->b;
|
||
pBuffer[1] = pLine->g;
|
||
pBuffer[2] = pLine->r;
|
||
pBuffer[3] = 255;
|
||
}
|
||
}
|
||
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
Pix* pPix = pixCreate(lImageWidth, lImageHeight, 1);
|
||
if (pPix)
|
||
{
|
||
for (int nY = 0; nY < lImageHeight; nY++)
|
||
{
|
||
BYTE* pLine = pBitmap->operator [](nY);
|
||
for (int nX = 0; nX < lImageWidth; nX++, pLine++)
|
||
{
|
||
pixSetPixel(pPix, nX, lImageHeight - 1 - nY, *pLine);
|
||
}
|
||
}
|
||
|
||
pPdf->DrawImageWith1bppMask((IGrObject*)&oImage, pPix, lImageWidth, lImageHeight, 0, 0, dWidth, dHeight);
|
||
pixDestroy(&pPix);
|
||
}
|
||
}
|
||
}
|
||
else if (pPage->is_legal_bilevel())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
|
||
Pix* pPix = pixCreate(lImageWidth, lImageHeight, 1);
|
||
if (pPix)
|
||
{
|
||
for (int nY = 0; nY < lImageHeight; nY++)
|
||
{
|
||
BYTE* pLine = pBitmap->operator [](nY);
|
||
for (int nX = 0; nX < lImageWidth; nX++, pLine++)
|
||
{
|
||
pixSetPixel(pPix, nX, lImageHeight - 1 - nY, *pLine);
|
||
}
|
||
}
|
||
|
||
pPdf->DrawImage1bpp(pPix, lImageWidth, lImageHeight, 0, 0, dWidth, dHeight);
|
||
pixDestroy(&pPix);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>??
|
||
//memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight);
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||
|
||
if (NULL != pImage)
|
||
{
|
||
BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth];
|
||
if (pBufferDst)
|
||
{
|
||
Aggplus::CImage oImage;
|
||
oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth);
|
||
|
||
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;
|
||
}
|
||
}
|
||
pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
if (NULL != pBitmap)
|
||
{
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
if (nPaletteEntries <= 2)
|
||
{
|
||
Pix* pPix = pixCreate(lImageWidth, lImageHeight, 1);
|
||
if (pPix)
|
||
{
|
||
for (int nY = 0; nY < lImageHeight; nY++)
|
||
{
|
||
BYTE* pLine = pBitmap->operator [](nY);
|
||
for (int nX = 0; nX < lImageWidth; nX++, pLine++)
|
||
{
|
||
pixSetPixel(pPix, nX, lImageHeight - 1 - nY, *pLine);
|
||
}
|
||
}
|
||
|
||
pPdf->DrawImage1bpp(pPix, lImageWidth, lImageHeight, 0, 0, dWidth, dHeight);
|
||
pixDestroy(&pPix);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth];
|
||
if (!pBufferDst)
|
||
return;
|
||
|
||
Aggplus::CImage oImage;
|
||
oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth);
|
||
|
||
DWORD* palette = new DWORD[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;
|
||
}
|
||
|
||
DWORD* pBuffer = (DWORD*)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->DrawImage((IGrObject*)&oImage, 0, 0, dWidth, dHeight);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
pRenderer->EndCommand(c_nPageType);
|
||
}
|
||
void CDjVuFileImplementation::CreateGrFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, bool* pBreak)
|
||
{
|
||
int nWidth = pPage->get_real_width();
|
||
int nHeight = pPage->get_real_height();
|
||
|
||
BYTE* pBufferDst = NULL;
|
||
LONG lImageWidth = 0;
|
||
LONG lImageHeight = 0;
|
||
|
||
// TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
//VARIANT var;
|
||
//renderer->GetAdditionalParam(L"Pixels", &var);
|
||
//pBufferDst = (BYTE*)var.lVal;
|
||
|
||
//renderer->GetAdditionalParam(L"PixelsWidth", &var);
|
||
//lImageWidth = var.lVal;
|
||
//renderer->GetAdditionalParam(L"PixelsHeight", &var);
|
||
//lImageHeight = var.lVal;
|
||
|
||
volatile bool* pCancel = pBreak;
|
||
|
||
if ((NULL != pCancel) && (TRUE == *pCancel))
|
||
return;
|
||
|
||
if (pPage->is_legal_photo() || pPage->is_legal_compound())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||
|
||
BYTE* pBuffer = pBufferDst;
|
||
for (int j = 0; j < lImageHeight; ++j)
|
||
{
|
||
GPixel* pLine = pImage->operator [](j);
|
||
|
||
if ((NULL != pCancel) && (TRUE == *pCancel))
|
||
return;
|
||
|
||
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())
|
||
{
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
DWORD* palette = new DWORD[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;
|
||
}
|
||
|
||
DWORD* pBuffer = (DWORD*)pBufferDst;
|
||
for (int j = 0; j < lImageHeight; ++j)
|
||
{
|
||
BYTE* pLine = pBitmap->operator [](j);
|
||
|
||
if ((NULL != pCancel) && (TRUE == *pCancel))
|
||
return;
|
||
|
||
for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine)
|
||
{
|
||
if (*pLine < nPaletteEntries)
|
||
{
|
||
*pBuffer = palette[*pLine];
|
||
}
|
||
else
|
||
{
|
||
*pBuffer = palette[0];
|
||
}
|
||
}
|
||
}
|
||
|
||
RELEASEARRAYOBJECTS(palette);
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>??
|
||
//memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight);
|
||
GRect oRectAll(0, 0, lImageWidth, lImageHeight);
|
||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||
|
||
if (NULL != pImage)
|
||
{
|
||
BYTE* pBuffer = pBufferDst;
|
||
for (int j = 0; j < lImageHeight; ++j)
|
||
{
|
||
GPixel* pLine = pImage->operator [](j);
|
||
|
||
if ((NULL != pCancel) && (TRUE == *pCancel))
|
||
return;
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4);
|
||
|
||
if (NULL != pBitmap)
|
||
{
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
DWORD* palette = new DWORD[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;
|
||
}
|
||
|
||
DWORD* pBuffer = (DWORD*)pBufferDst;
|
||
for (int j = 0; j < lImageHeight; ++j)
|
||
{
|
||
BYTE* pLine = pBitmap->operator [](j);
|
||
|
||
if ((NULL != pCancel) && (TRUE == *pCancel))
|
||
return;
|
||
|
||
for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine)
|
||
{
|
||
if (*pLine < nPaletteEntries)
|
||
{
|
||
*pBuffer = palette[*pLine];
|
||
}
|
||
else
|
||
{
|
||
*pBuffer = palette[0];
|
||
}
|
||
}
|
||
}
|
||
|
||
RELEASEARRAYOBJECTS(palette);
|
||
}
|
||
}
|
||
}
|
||
XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP<DjVuImage> pPage)
|
||
{
|
||
XmlUtils::CXmlNode paragraph;
|
||
const GP<DjVuText> text(DjVuText::create());
|
||
const GP<ByteStream> text_str(pPage->get_text());
|
||
if (text_str)
|
||
{
|
||
text->decode(text_str);
|
||
GUTF8String pageText = text->get_xmlText(pPage->get_height());
|
||
XmlUtils::CXmlNode hiddenText;
|
||
XmlUtils::CXmlNode pageColumn;
|
||
XmlUtils::CXmlNode region;
|
||
hiddenText.FromXmlString(NSDjvu::MakeCString(pageText));
|
||
hiddenText.GetNode(_T("PAGECOLUMN"), pageColumn);
|
||
pageColumn.GetNode(_T("REGION"), region);
|
||
region.GetNode(_T("PARAGRAPH"), paragraph);
|
||
}
|
||
return paragraph;
|
||
}
|
||
void CDjVuFileImplementation::TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode oTextNode, double dKoef, bool isView)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>)
|
||
pRenderer->put_FontName(L"DjvuEmptyFont");
|
||
CString csText = oTextNode.GetXml();
|
||
XmlUtils::CXmlNodes oLinesNodes;
|
||
oTextNode.GetNodes(L"LINE", oLinesNodes);
|
||
for (int nLineIndex = 0; nLineIndex < oLinesNodes.GetCount(); ++nLineIndex)
|
||
{
|
||
XmlUtils::CXmlNode oLineNode;
|
||
oLinesNodes.GetAt(nLineIndex, oLineNode);
|
||
XmlUtils::CXmlNodes oWordsNodes;
|
||
oLineNode.GetNodes(L"WORD", oWordsNodes);
|
||
for (int nWordIndex = 0; nWordIndex < oWordsNodes.GetCount(); ++nWordIndex)
|
||
{
|
||
XmlUtils::CXmlNode oWordNode;
|
||
oWordsNodes.GetAt(nWordIndex, oWordNode);
|
||
CString csWord = oWordNode.GetText();
|
||
CString csCoords = oWordNode.GetAttribute(L"coords");
|
||
double arrCoords[4];
|
||
ParseCoords(csCoords.GetBuffer(), arrCoords, dKoef);
|
||
DrawPageText(pRenderer, arrCoords, csWord.GetBuffer());
|
||
}
|
||
}
|
||
}
|
||
void CDjVuFileImplementation::DrawPageText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText)
|
||
{
|
||
pRenderer->put_FontSize(pdCoords[1] - pdCoords[3]);
|
||
pRenderer->CommandDrawText(wsText,
|
||
(float)(pdCoords[0]),
|
||
(float)(pdCoords[3]),
|
||
(float)(pdCoords[2] - pdCoords[0]),
|
||
(float)(pdCoords[1] - pdCoords[3]),
|
||
(float)(pdCoords[1] - pdCoords[3]));
|
||
}
|
||
void CDjVuFileImplementation::ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef)
|
||
{
|
||
std::vector<std::wstring> vCoords = NSString::Split(wsCoordsStr, L',');
|
||
if (vCoords.size() >= 4)
|
||
{
|
||
for (int nIndex = 0; nIndex < 4; nIndex++)
|
||
{
|
||
pdCoords[nIndex] = NSDjvu::GetInteger(vCoords.at(nIndex)) * dKoef;
|
||
}
|
||
}
|
||
}
|