mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
1071 lines
27 KiB
C++
1071 lines
27 KiB
C++
#include "stdafx.h"
|
||
#include "OfficeDjVuFile.h"
|
||
#include "Resource.h"
|
||
#include "math.h"
|
||
#include "../Common/TimeMeasurer.h"
|
||
|
||
#define VER_DPI 96
|
||
#define HOR_DPI 96
|
||
|
||
|
||
namespace NSDjvu
|
||
{
|
||
static GUTF8String MakeUTF8String(const CString& strText)
|
||
{
|
||
int nSize;
|
||
|
||
#ifdef _UNICODE
|
||
LPCWSTR pszUnicodeText = strText;
|
||
#else
|
||
nSize = ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strText, -1, NULL, 0);
|
||
if (nSize == 0)
|
||
return "";
|
||
|
||
LPWSTR pszUnicodeText = new WCHAR[nSize];
|
||
::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strText, -1, pszUnicodeText, nSize);
|
||
#endif
|
||
|
||
nSize = ::WideCharToMultiByte(CP_UTF8, 0, pszUnicodeText, -1, NULL, 0, NULL, NULL);
|
||
if (nSize == 0)
|
||
{
|
||
#ifndef _UNICODE
|
||
delete[] pszUnicodeText;
|
||
#endif
|
||
return "";
|
||
}
|
||
|
||
LPSTR pszTextUTF8 = new CHAR[nSize];
|
||
::WideCharToMultiByte(CP_UTF8, 0, pszUnicodeText, -1, pszTextUTF8, nSize, NULL, NULL);
|
||
|
||
GUTF8String utf8String(pszTextUTF8);
|
||
delete[] pszTextUTF8;
|
||
|
||
#ifndef _UNICODE
|
||
delete[] pszUnicodeText;
|
||
#endif
|
||
|
||
return utf8String;
|
||
}
|
||
|
||
|
||
static CString MakeCString(GUTF8String& strText)
|
||
{
|
||
int nSize;
|
||
|
||
LPSTR pszUtf8Text = strText.getbuf();
|
||
|
||
//nSize = ::WideCharToMultiByte(CP_UTF8, 0, pszUtf8Text, -1, NULL, 0, NULL, NULL);
|
||
nSize = ::MultiByteToWideChar(CP_UTF8, 0, pszUtf8Text, -1, NULL, 0);
|
||
|
||
if (nSize == 0)
|
||
{
|
||
return _T("");
|
||
}
|
||
|
||
LPWSTR pszUnicodeText = new WCHAR[nSize];
|
||
::MultiByteToWideChar(CP_UTF8, 0, pszUtf8Text, -1, pszUnicodeText, nSize);
|
||
|
||
CString String(pszUnicodeText);
|
||
delete[] pszUnicodeText;
|
||
|
||
return String;
|
||
}
|
||
}
|
||
|
||
CDjVuFile::CDjVuFile()
|
||
{
|
||
}
|
||
|
||
|
||
HRESULT CDjVuFile::FinalConstruct()
|
||
{
|
||
CString sTempPath;
|
||
GetTempPath(4096, sTempPath.GetBuffer(4096));
|
||
sTempPath.ReleaseBuffer();
|
||
|
||
sTempPath += L"DJVU\\";
|
||
|
||
#ifdef _DEBUG
|
||
sTempPath = _T("C:\\DJVU\\");
|
||
#endif
|
||
|
||
m_strTempDirectory = sTempPath;
|
||
CreateDirectory(m_strTempDirectory, NULL);
|
||
|
||
m_pDocumentRenderer = FALSE;
|
||
|
||
InitializeCriticalSection(&m_oCS);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
void CDjVuFile::FinalRelease()
|
||
{
|
||
if (NULL != m_pDocumentRenderer)
|
||
{
|
||
m_pDocumentRenderer->Release();
|
||
m_pDocumentRenderer = NULL;
|
||
}
|
||
|
||
WIN32_FIND_DATA winFileData;
|
||
HANDLE hFile;
|
||
|
||
CString strFoundPreset = m_strTempDirectory + _T("\\*.*");
|
||
|
||
hFile = FindFirstFile(strFoundPreset, &winFileData);
|
||
if (hFile != INVALID_HANDLE_VALUE)
|
||
{
|
||
DeleteFile(winFileData.cFileName);
|
||
while (FALSE != FindNextFile(hFile, &winFileData))
|
||
{
|
||
DeleteFile(winFileData.cFileName);
|
||
}
|
||
FindClose(hFile);
|
||
}
|
||
RemoveDirectory(m_strTempDirectory);
|
||
|
||
DeleteCriticalSection(&m_oCS);
|
||
}
|
||
|
||
|
||
STDMETHODIMP CDjVuFile::get_PagesCount(LONG* plCount)
|
||
{
|
||
*plCount = m_pDoc->get_pages_num();
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHODIMP CDjVuFile::GetPageInfo(int nPage, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY)
|
||
{
|
||
GP<DjVuImage> pPage = m_pDoc->get_page(nPage);
|
||
|
||
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();
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
STDMETHODIMP CDjVuFile::DrawPage(int nPage, IUnknown* punkRenderer, BOOL* pBreak)
|
||
{
|
||
//CTemporaryCS* pCS = new CTemporaryCS(&m_oCS);
|
||
|
||
try
|
||
{
|
||
GP<DjVuImage> pPage = m_pDoc->get_page(nPage);
|
||
pPage->wait_for_complete_decode();
|
||
pPage->set_rotate(0);
|
||
|
||
//RELEASEOBJECT(pCS);
|
||
|
||
AVSGraphics::IASCGraphicsRenderer* pGrRenderer = NULL;
|
||
punkRenderer->QueryInterface(__uuidof(AVSGraphics::IASCGraphicsRenderer), (void**)&pGrRenderer);
|
||
|
||
if (NULL != pGrRenderer)
|
||
{
|
||
CreateFrame3(pGrRenderer, pPage, pBreak);
|
||
RELEASEINTERFACE(pGrRenderer);
|
||
return S_OK;
|
||
}
|
||
|
||
XmlUtils::CXmlNode text = ParseText(pPage);
|
||
|
||
AVSGraphics::IASCRenderer* renderer;
|
||
punkRenderer->QueryInterface(__uuidof(AVSGraphics::IASCRenderer), (void**)&renderer);
|
||
CreateFrame2(renderer, pPage, nPage, text);
|
||
RELEASEINTERFACE(renderer);
|
||
}
|
||
catch(...)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
return S_OK;
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHODIMP CDjVuFile::LoadFromFile(BSTR sSrcFileName, BSTR sDstPath, BSTR sXMLOptions)
|
||
{
|
||
//CTemporaryCS oCS(&m_oCS);
|
||
|
||
if (NULL == m_pDocumentRenderer)
|
||
return S_FALSE;
|
||
|
||
m_pDoc = NULL;
|
||
try
|
||
{
|
||
GUTF8String utf8;
|
||
GURL url = GURL::Filename::UTF8(NSDjvu::MakeUTF8String(CString(sSrcFileName)));
|
||
m_pDoc = DjVuDocument::create(url);
|
||
m_pDoc->wait_get_pages_num();
|
||
}
|
||
catch (...)
|
||
{
|
||
return S_FALSE;
|
||
}
|
||
/*
|
||
int nPages = pDoc->get_pages_num();
|
||
pDoc->wait_for_complete_init();
|
||
|
||
for (int page = 0; page < nPages; ++page)
|
||
{
|
||
GP<DjVuImage> pPage = pDoc->get_page(page);
|
||
pPage->wait_for_complete_decode();
|
||
pPage->set_rotate(0);
|
||
//
|
||
XmlUtils::CXmlNode text = ParseText(pPage);
|
||
//
|
||
double dWidth = 190;
|
||
double dHeight = 270;
|
||
|
||
CreateFrame(pPage, page, text);
|
||
|
||
SHORT nCancel = c_shProgressContinue;
|
||
LONG lProgress = (c_nMaxProgressPercent * (page + 1)) / nPages;
|
||
OnProgressEx(0, lProgress, &nCancel);
|
||
|
||
if (c_shProgressCancel == nCancel)
|
||
break;
|
||
}
|
||
*/
|
||
|
||
int nPagesCount = m_pDoc->get_pages_num();
|
||
|
||
SAFEARRAYBOUND rgsab;
|
||
rgsab.lLbound = 0;
|
||
rgsab.cElements = 2 * nPagesCount;
|
||
|
||
SAFEARRAY *psaPagesSizes = SafeArrayCreate( VT_R8, 1, &rgsab );
|
||
double *pSizes = (double*)psaPagesSizes->pvData;
|
||
|
||
for (int nPageIndex = 0; nPageIndex < nPagesCount; ++nPageIndex, pSizes += 2)
|
||
{
|
||
int nWidth = 1000;
|
||
int nHeight = 1000;
|
||
|
||
int nDpi = 300;
|
||
|
||
m_pDoc->ReadPageInfo(nPageIndex, nWidth, nHeight, nDpi);
|
||
|
||
double dPixToMM = 25.4;
|
||
|
||
double dW_MM = dPixToMM * nWidth / nDpi;
|
||
double dH_MM = dPixToMM * nHeight / nDpi;
|
||
|
||
pSizes[0] = dW_MM;
|
||
pSizes[1] = dH_MM;
|
||
|
||
/*m_pDocumentRenderer->NewPage();
|
||
m_pDocumentRenderer->put_Width(dW_MM);
|
||
m_pDocumentRenderer->put_Height(dH_MM);
|
||
|
||
IUnknown* punkInst = NULL;
|
||
this->QueryInterface(IID_IUnknown, (void**)&punkInst);
|
||
|
||
m_pDocumentRenderer->SetPageInstance(punkInst);
|
||
|
||
RELEASEINTERFACE(punkInst);
|
||
m_pDocumentRenderer->EndCommand(0x0001);*/
|
||
}
|
||
|
||
IUnknown* punkInst = NULL;
|
||
this->QueryInterface(IID_IUnknown, (void**)&punkInst);
|
||
m_pDocumentRenderer->SetDocumentInstance( punkInst, psaPagesSizes );
|
||
RELEASEINTERFACE(punkInst);
|
||
|
||
SafeArrayDestroy( psaPagesSizes );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
RELEASEINTERFACE(m_pDocumentRenderer);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
STDMETHODIMP CDjVuFile::SaveToFile(BSTR sDstFileName, BSTR sSrcPath, BSTR sXMLOptions)
|
||
{
|
||
return S_OK;
|
||
}
|
||
|
||
void CDjVuFile::CreateFrame(GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
|
||
{
|
||
FILE* file;
|
||
file = fopen("C:\\times.txt", "a+");
|
||
|
||
CTimeMeasurer getPixmapTimer;
|
||
CTimeMeasurer getBitmapTimer;
|
||
CTimeMeasurer save24bitTimer;
|
||
CTimeMeasurer save8bitTimer;
|
||
CTimeMeasurer drawTextTimer;
|
||
|
||
double time;
|
||
|
||
CString strNum;
|
||
strNum.Format(_T("%d"), nPage);
|
||
|
||
CString strFile = m_strTempDirectory + strNum;
|
||
|
||
int nWidth = pPage->get_real_width();
|
||
int nHeight = pPage->get_real_height();
|
||
|
||
int nDpi = pPage->get_dpi();
|
||
|
||
double dW_MM;
|
||
double dH_MM;
|
||
|
||
double dPixToMM = 25.4;
|
||
|
||
dW_MM = dPixToMM * nWidth / nDpi;
|
||
dH_MM = dPixToMM * nHeight / nDpi;
|
||
|
||
GRect oRect(0, 0, nWidth, nHeight);
|
||
|
||
if (pPage->is_legal_photo() || pPage->is_legal_compound())
|
||
{
|
||
GRect oRectAll(0, 0, nWidth * HOR_DPI / nDpi, nHeight * VER_DPI / nDpi);
|
||
getPixmapTimer.Reset();//TIMER
|
||
GP<GPixmap> pImage = pPage->get_pixmap(/*oRect*/oRectAll, oRectAll);
|
||
time = getPixmapTimer.GetTimeInterval();//TIMER
|
||
fprintf(file, "GetPixmap:%lf\n", time);//TIMER
|
||
|
||
strFile += _T(".png");
|
||
save24bitTimer.Reset();//TIMER
|
||
m_oImage.SaveImage24bit(pImage->operator [](0), nWidth * HOR_DPI / nDpi, nHeight * VER_DPI / nDpi, strFile);
|
||
time = save24bitTimer.GetTimeInterval();//TIMER
|
||
fprintf(file, "Save24bit:%lf\n", time);//TIMER
|
||
}
|
||
else if (pPage->is_legal_bilevel())
|
||
{
|
||
getBitmapTimer.Reset();//TIMER
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRect, oRect, 4);
|
||
time = getBitmapTimer.GetTimeInterval();//TIMER
|
||
fprintf(file, "GetBitmap:%lf\n", time);//TIMER
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
LPBITMAPINFO pBMI;
|
||
int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*nPaletteEntries;
|
||
|
||
pBMI = (LPBITMAPINFO) malloc(nSize);
|
||
ZeroMemory(pBMI, nSize);
|
||
|
||
BITMAPINFOHEADER& bmih = pBMI->bmiHeader;
|
||
bmih.biSize = sizeof(bmih);
|
||
bmih.biPlanes = 1;
|
||
bmih.biWidth = nWidth;
|
||
bmih.biHeight = nHeight;
|
||
bmih.biBitCount = 8;
|
||
bmih.biCompression = BI_RGB;
|
||
bmih.biClrUsed = nPaletteEntries;
|
||
|
||
// Create palette for the bitmap
|
||
int color = 0xff0000;
|
||
int decrement = color/(nPaletteEntries - 1);
|
||
for (int i = 0; i < nPaletteEntries; ++i)
|
||
{
|
||
int level = color >> 16;
|
||
pBMI->bmiColors[i].rgbBlue = level;
|
||
pBMI->bmiColors[i].rgbGreen = level;
|
||
pBMI->bmiColors[i].rgbRed = level;
|
||
color -= decrement;
|
||
}
|
||
|
||
strFile += _T(".bmp");
|
||
save8bitTimer.Reset();//TIMER
|
||
m_oImage.SaveImage8bit(pBMI, pBitmap, strFile);
|
||
time = save8bitTimer.GetTimeInterval();//TIMER
|
||
fprintf(file, "Save8bit:%lf\n", time);//TIMER
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>??
|
||
}
|
||
|
||
PageToRenderer(dW_MM, dH_MM);
|
||
|
||
drawTextTimer.Reset();//TIMER
|
||
TextToRenderer(text, dPixToMM / nDpi);
|
||
time = drawTextTimer.GetTimeInterval();//TIMER
|
||
fprintf(file, "Drawtext:%lf\n", time);//TIMER
|
||
|
||
ImageToRenderer(strFile, dW_MM, dH_MM);
|
||
|
||
m_pDocumentRenderer->EndCommand(0x0001); // CompletePage
|
||
fprintf(file, "--------------\n");
|
||
fclose(file);//TIMER
|
||
}
|
||
|
||
|
||
|
||
void CDjVuFile::CreateFrame2(AVSGraphics::IASCRenderer* renderer, 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;
|
||
renderer->get_DpiX(&dRendDpiX);
|
||
renderer->get_DpiY(&dRendDpiY);
|
||
|
||
if (0 >= dRendDpiX)
|
||
dRendDpiX = 72.0;
|
||
if (0 >= dRendDpiY)
|
||
dRendDpiY = 72.0;
|
||
|
||
double dRendWidth = 0;
|
||
double dRendHeight = 0;
|
||
renderer->get_Width(&dRendWidth);
|
||
renderer->get_Height(&dRendHeight);
|
||
|
||
if (0 >= dRendWidth)
|
||
dRendWidth = 200;
|
||
if (0 >= dRendHeight)
|
||
dRendHeight = 300;
|
||
|
||
MediaCore::IAVSUncompressedVideoFrame* pFrame;
|
||
CoCreateInstance(MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_INPROC, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&pFrame);
|
||
|
||
LONG lImageWidth = (LONG)(dRendDpiX * dRendWidth / dPixToMM);
|
||
LONG lImageHeight = (LONG)(dRendDpiY * dRendHeight / dPixToMM);
|
||
|
||
long lRendererType = 0x00; // Unknown renderer
|
||
renderer->get_Type( &lRendererType );
|
||
if ( 0x01 == lRendererType ) // PDF
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> dpi
|
||
lImageWidth = pPage->get_real_width();
|
||
lImageHeight = pPage->get_real_height();
|
||
}
|
||
else if (0x02 == lRendererType)
|
||
{
|
||
// html
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
pFrame->put_Width(lImageWidth);
|
||
pFrame->put_Height(lImageHeight);
|
||
pFrame->put_ColorSpace(CSP_BGRA);
|
||
pFrame->SetDefaultStrides();
|
||
pFrame->AllocateBuffer(-1);
|
||
|
||
BYTE* pBufferDst = NULL;
|
||
pFrame->get_Buffer(&pBufferDst);
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> - <20><> GraphicsRenderer (<28><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||
if (0x02 != lRendererType && 0x06 != lRendererType)
|
||
{
|
||
// <20><><EFBFBD> html <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||
TextToRenderer(renderer, text, dPixToMM / nDpi);
|
||
}
|
||
|
||
renderer->DrawImage((IUnknown*)pFrame, 0, 0, dRendWidth, dRendHeight);
|
||
|
||
RELEASEINTERFACE(pFrame);
|
||
|
||
renderer->EndCommand(0x0001); // CompletePage
|
||
}
|
||
|
||
void CDjVuFile::CreateFrame3(AVSGraphics::IASCGraphicsRenderer* renderer, 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;
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDjVuFile::CreateFrame(AVSGraphics::IASCRenderer* renderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
|
||
{
|
||
CString strNum;
|
||
strNum.Format(_T("%d"), nPage);
|
||
|
||
CString strFile = m_strTempDirectory + strNum;
|
||
|
||
int nWidth = pPage->get_real_width();
|
||
int nHeight = pPage->get_real_height();
|
||
|
||
int nDpi = pPage->get_dpi();
|
||
|
||
double dW_MM;
|
||
double dH_MM;
|
||
|
||
double dPixToMM = 25.4;
|
||
|
||
dW_MM = dPixToMM * nWidth / nDpi;
|
||
dH_MM = dPixToMM * nHeight / nDpi;
|
||
|
||
GRect oRect(0, 0, nWidth, nHeight);
|
||
|
||
if (pPage->is_legal_photo() || pPage->is_legal_compound())
|
||
{
|
||
GRect oRectAll(0, 0, nWidth * HOR_DPI / nDpi, nHeight * VER_DPI / nDpi);
|
||
GP<GPixmap> pImage = pPage->get_pixmap(/*oRect*/oRectAll, oRectAll);
|
||
|
||
strFile += _T(".png");
|
||
m_oImage.SaveImage24bit(pImage->operator [](0), nWidth * HOR_DPI / nDpi, nHeight * VER_DPI / nDpi, strFile);
|
||
|
||
}
|
||
else if (pPage->is_legal_bilevel())
|
||
{
|
||
GP<GBitmap> pBitmap = pPage->get_bitmap(oRect, oRect, 4);
|
||
int nPaletteEntries = pBitmap->get_grays();
|
||
|
||
LPBITMAPINFO pBMI;
|
||
int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*nPaletteEntries;
|
||
|
||
pBMI = (LPBITMAPINFO) malloc(nSize);
|
||
ZeroMemory(pBMI, nSize);
|
||
|
||
BITMAPINFOHEADER& bmih = pBMI->bmiHeader;
|
||
bmih.biSize = sizeof(bmih);
|
||
bmih.biPlanes = 1;
|
||
bmih.biWidth = nWidth;
|
||
bmih.biHeight = nHeight;
|
||
bmih.biBitCount = 8;
|
||
bmih.biCompression = BI_RGB;
|
||
bmih.biClrUsed = nPaletteEntries;
|
||
|
||
// Create palette for the bitmap
|
||
int color = 0xff0000;
|
||
int decrement = color/(nPaletteEntries - 1);
|
||
for (int i = 0; i < nPaletteEntries; ++i)
|
||
{
|
||
int level = color >> 16;
|
||
pBMI->bmiColors[i].rgbBlue = level;
|
||
pBMI->bmiColors[i].rgbGreen = level;
|
||
pBMI->bmiColors[i].rgbRed = level;
|
||
color -= decrement;
|
||
}
|
||
|
||
strFile += _T(".bmp");
|
||
m_oImage.SaveImage8bit(pBMI, pBitmap, strFile);
|
||
}
|
||
else
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>??
|
||
}
|
||
|
||
PageToRenderer(renderer, dW_MM, dH_MM);
|
||
TextToRenderer(renderer, text, dPixToMM / nDpi);
|
||
ImageToRenderer(renderer, strFile, dW_MM, dH_MM);
|
||
|
||
renderer->EndCommand(0x0001); // CompletePage
|
||
}
|
||
|
||
|
||
|
||
CString CDjVuFile::SavePage(int nPageNum, IUnknown* pPage)
|
||
{
|
||
CString strNum;
|
||
strNum.Format(_T("%d"), nPageNum);
|
||
|
||
CString strFile = m_strTempDirectory + strNum + _T(".jpg");
|
||
|
||
CString strXml = _T("<transforms><ImageFile-SaveAsJpeg destinationpath='") +
|
||
strFile + _T("' format='888' quality='100' /></transforms>");
|
||
|
||
ImageStudio::IImageTransforms* pTransforms = NULL;
|
||
CoCreateInstance(ImageStudio::CLSID_ImageTransforms, NULL, CLSCTX_INPROC, ImageStudio::IID_IImageTransforms, (void**)&pTransforms);
|
||
|
||
if (NULL == pTransforms)
|
||
return _T("");
|
||
|
||
VARIANT var;
|
||
var.vt = VT_UNKNOWN;
|
||
var.punkVal = pPage;
|
||
|
||
pTransforms->SetSource(0, var);
|
||
var.punkVal = NULL;
|
||
|
||
VARIANT_BOOL vbRes = VARIANT_FALSE;
|
||
BSTR bsXml = strXml.AllocSysString();
|
||
pTransforms->SetXml(bsXml, &vbRes);
|
||
pTransforms->Transform(&vbRes);
|
||
|
||
pTransforms->Release();
|
||
|
||
return strFile;
|
||
}
|
||
|
||
|
||
XmlUtils::CXmlNode CDjVuFile::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 CDjVuFile::PageToRenderer(double width, double height)
|
||
{
|
||
m_pDocumentRenderer->NewPage();
|
||
m_pDocumentRenderer->put_Width(width);
|
||
m_pDocumentRenderer->put_Height(height);
|
||
}
|
||
|
||
|
||
void CDjVuFile::PageToRenderer(AVSGraphics::IASCRenderer* renderer, double width, double height)
|
||
{
|
||
renderer->NewPage();
|
||
renderer->put_Width(width);
|
||
renderer->put_Height(height);
|
||
}
|
||
|
||
|
||
void CDjVuFile::TextToRenderer(XmlUtils::CXmlNode text, double koef, bool isView)
|
||
{
|
||
|
||
m_pDocumentRenderer->SetShadow(L"<shadow visible='0' />");
|
||
CString p = text.GetXml();
|
||
XmlUtils::CXmlNodes lines_node;
|
||
text.GetNodes(_T("LINE"), lines_node);
|
||
for(int i = 0; i < lines_node.GetCount(); ++i)
|
||
{
|
||
XmlUtils::CXmlNode line_node;
|
||
lines_node.GetAt(i, line_node);
|
||
XmlUtils::CXmlNodes words_node;
|
||
line_node.GetNodes(_T("WORD"), words_node);
|
||
for(int j = 0; j < words_node.GetCount(); ++j)
|
||
{
|
||
XmlUtils::CXmlNode word_node;
|
||
words_node.GetAt(j, word_node);
|
||
CString word = word_node.GetText();
|
||
CString coordsStr = word_node.GetAttribute(_T("coords"));
|
||
double coords[4];
|
||
ParseCoords(coordsStr, coords, koef);
|
||
DrawText(coords, word);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDjVuFile::TextToRenderer(AVSGraphics::IASCRenderer* renderer, XmlUtils::CXmlNode text, double koef, bool isView)
|
||
{
|
||
renderer->put_ShadowVisible(0);
|
||
|
||
// <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>)
|
||
renderer->put_FontName(L"AVSEmptyFont");
|
||
|
||
CString p = text.GetXml();
|
||
XmlUtils::CXmlNodes lines_node;
|
||
text.GetNodes(_T("LINE"), lines_node);
|
||
for(int i = 0; i < lines_node.GetCount(); ++i)
|
||
{
|
||
XmlUtils::CXmlNode line_node;
|
||
lines_node.GetAt(i, line_node);
|
||
XmlUtils::CXmlNodes words_node;
|
||
line_node.GetNodes(_T("WORD"), words_node);
|
||
for(int j = 0; j < words_node.GetCount(); ++j)
|
||
{
|
||
XmlUtils::CXmlNode word_node;
|
||
words_node.GetAt(j, word_node);
|
||
CString word = word_node.GetText();
|
||
CString coordsStr = word_node.GetAttribute(_T("coords"));
|
||
double coords[4];
|
||
ParseCoords(coordsStr, coords, koef);
|
||
DrawText(renderer, coords, word);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDjVuFile::ImageToRenderer(const CString& strName, double width, double height)
|
||
{
|
||
BSTR bsPath = strName.AllocSysString();
|
||
m_pDocumentRenderer->DrawImageFromFile(bsPath, 0, 0, (float)width, (float)height);
|
||
SysFreeString(bsPath);
|
||
}
|
||
|
||
|
||
void CDjVuFile::ImageToRenderer(AVSGraphics::IASCRenderer* renderer, const CString& strName, double width, double height)
|
||
{
|
||
BSTR bsPath = strName.AllocSysString();
|
||
renderer->DrawImageFromFile(bsPath, 0, 0, (float)width, (float)height);
|
||
SysFreeString(bsPath);
|
||
}
|
||
|
||
|
||
void CDjVuFile::ParseCoords(CString& coordsStr, double* coords, double koef)
|
||
{
|
||
CString trimStr = coordsStr + _T(",");
|
||
for(int k = 0; k < 4; ++k)
|
||
{
|
||
coords[k] = XmlUtils::GetInteger(trimStr.Mid(0, trimStr.Find(_T(",")))) * koef;
|
||
if (k != 3)
|
||
{
|
||
trimStr = trimStr.Mid(trimStr.Find(_T(",")) + 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CDjVuFile::DrawRect(double* coords)
|
||
{
|
||
m_pDocumentRenderer->PathCommandMoveTo(coords[0], coords[3]);
|
||
m_pDocumentRenderer->PathCommandLineTo(coords[2], coords[3]);
|
||
m_pDocumentRenderer->PathCommandLineTo(coords[2], coords[1]);
|
||
m_pDocumentRenderer->PathCommandLineTo(coords[0], coords[1]);
|
||
m_pDocumentRenderer->PathCommandClose();
|
||
m_pDocumentRenderer->DrawPath(1);
|
||
m_pDocumentRenderer->PathCommandEnd();
|
||
}
|
||
|
||
|
||
void CDjVuFile::DrawRect(AVSGraphics::IASCRenderer* renderer, double* coords)
|
||
{
|
||
renderer->PathCommandMoveTo(coords[0], coords[3]);
|
||
renderer->PathCommandLineTo(coords[2], coords[3]);
|
||
renderer->PathCommandLineTo(coords[2], coords[1]);
|
||
renderer->PathCommandLineTo(coords[0], coords[1]);
|
||
renderer->PathCommandClose();
|
||
renderer->DrawPath(1);
|
||
renderer->PathCommandEnd();
|
||
}
|
||
|
||
|
||
void CDjVuFile::DrawText(double* coords, CString text)
|
||
{
|
||
CString strFont;
|
||
strFont.Format(_T("<font name='Arial' size='%lf'/>"), min( 100 , max( 1, fabs((float)(coords[3] - coords[1]))) * 72 / 25.4));
|
||
BSTR bsFont = strFont.AllocSysString();
|
||
m_pDocumentRenderer->SetFont(bsFont);
|
||
SysFreeString(bsFont);
|
||
BSTR bsText = text.AllocSysString();
|
||
m_pDocumentRenderer->CommandDrawText(bsText,
|
||
(float)coords[0],
|
||
(float)coords[3],
|
||
(float)(coords[2] - coords[0]),
|
||
(float)(coords[1] - coords[3]),
|
||
(float)(coords[1] - coords[3]));
|
||
SysFreeString(bsText);
|
||
}
|
||
|
||
void CDjVuFile::DrawText(AVSGraphics::IASCRenderer* renderer, double* coords, CString text)
|
||
{
|
||
/*CString strFont;
|
||
strFont.Format(_T("<font name='Arial' size='%lf'/>"), min( 100 , max( 1, fabs((float)(coords[3] - coords[1]))) * 72 / 25.4));
|
||
BSTR bsFont = strFont.AllocSysString();
|
||
renderer->SetFont(bsFont);
|
||
SysFreeString(bsFont);*/
|
||
renderer->put_FontSize(coords[1] - coords[3]);
|
||
BSTR bsText = text.AllocSysString();
|
||
renderer->CommandDrawText(bsText,
|
||
(float)coords[0],
|
||
(float)coords[3],
|
||
(float)(coords[2] - coords[0]),
|
||
(float)(coords[1] - coords[3]),
|
||
(float)(coords[1] - coords[3]));
|
||
SysFreeString(bsText);
|
||
} |