Commit f86579d6 authored by Oleg Korshul's avatar Oleg Korshul

PDFReader: text clip

parent de7511f2
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* 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 Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* 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 _BUILD_IGROBJECT_CROSSPLATFORM_H_
#define _BUILD_IGROBJECT_CROSSPLATFORM_H_
#include "Types.h"
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
class IGrObject
{
protected:
#ifdef __APPLE__
volatile int32_t m_lRef;
#else
ULONG m_lRef;
#endif
public:
IGrObject()
{
m_lRef = 1;
}
virtual ~IGrObject()
{
}
#ifdef __APPLE__
virtual ULONG AddRef()
{
OSAtomicIncrement32(&m_lRef);
return (ULONG)m_lRef;
}
virtual ULONG Release()
{
int32_t ret = OSAtomicDecrement32(&m_lRef);
if (0 == m_lRef)
delete this;
return (ULONG)ret;
}
#else
virtual ULONG AddRef()
{
++m_lRef;
return m_lRef;
}
virtual ULONG Release()
{
ULONG ret = --m_lRef;
if (0 == m_lRef)
delete this;
return ret;
}
#endif
};
#endif //_BUILD_IGROBJECT_CROSSPLATFORM_H_
......@@ -477,7 +477,7 @@ namespace Aggplus
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op)
{
Aggplus::CMatrix m;
return InternalClip(pPath, m_bIntegerGrid ? &m : &m_oFullTransform, op);
return InternalClip(pPath, (m_bIntegerGrid || pPath->m_pTransform != NULL) ? &m : &m_oFullTransform, op);
}
Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op)
......
......@@ -38,6 +38,7 @@ namespace Aggplus
CGraphicsPath::CGraphicsPath() : ISimpleGraphicsPath()
{
m_bEvenOdd = false;
m_pTransform = NULL;
}
CGraphicsPath::~CGraphicsPath()
......@@ -406,14 +407,28 @@ namespace Aggplus
bool CGraphicsPath::_MoveTo(double x, double y)
{
if (NULL != m_pTransform)
{
m_pTransform->TransformPoint(x, y);
}
return (Ok == MoveTo(x, y));
}
bool CGraphicsPath::_LineTo(double x, double y)
{
if (NULL != m_pTransform)
{
m_pTransform->TransformPoint(x, y);
}
return (Ok == LineTo(x, y));
}
bool CGraphicsPath::_CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
if (NULL != m_pTransform)
{
m_pTransform->TransformPoint(x1, y1);
m_pTransform->TransformPoint(x2, y2);
m_pTransform->TransformPoint(x3, y3);
}
return (Ok == CurveTo(x1, y1, x2, y2, x3, y3));
}
bool CGraphicsPath::_Close()
......
......@@ -113,6 +113,8 @@ public:
bool m_bEvenOdd;
bool m_bIsMoveTo;
CMatrix* m_pTransform;
public:
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
......
......@@ -33,6 +33,21 @@
#include <algorithm>
#include "../raster/Metafile/MetaFile.h"
#if 0
static void LOGGING(char* buffer, ...)
{
FILE* f = fopen("path_to_log.txt", "a+");
va_list args;
va_start(args, buffer);
vfprintf(f, buffer, args);
fprintf(f, "\n");
fclose(f);
va_end(args);
}
#endif
////////////////////////////////////////////////////////////////////////////////
Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
......@@ -1114,6 +1129,19 @@ HRESULT CGraphicsRenderer::CommandString(const LONG& lType, const std::wstring&
return S_OK;
}
HRESULT CGraphicsRenderer::StartConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = true;
m_pPath->m_pTransform = m_pRenderer->GetFullTransform();
return S_OK;
}
HRESULT CGraphicsRenderer::EndConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = false;
m_pPath->m_pTransform = NULL;
return S_OK;
}
// common
void CGraphicsRenderer::_SetFont()
{
......
......@@ -247,6 +247,9 @@ public:
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
virtual HRESULT StartConvertCoordsToIdentity();
virtual HRESULT EndConvertCoordsToIdentity();
void put_GlobalAlphaEnabled(const bool& bEnabled, const double& dVal);
inline void put_IntegerGrid(const bool& bEnabled)
{
......
......@@ -34,65 +34,10 @@
#pragma once
#include "../common/Types.h"
#include "../common/IGrObject.h"
#include "Matrix.h"
#include <string>
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
class IGrObject
{
protected:
#ifdef __APPLE__
volatile int32_t m_lRef;
#else
ULONG m_lRef;
#endif
public:
IGrObject()
{
m_lRef = 1;
}
virtual ~IGrObject()
{
}
#ifdef __APPLE__
virtual ULONG AddRef()
{
OSAtomicIncrement32(&m_lRef);
return (ULONG)m_lRef;
}
virtual ULONG Release()
{
int32_t ret = OSAtomicDecrement32(&m_lRef);
if (0 == m_lRef)
delete this;
return (ULONG)ret;
}
#else
virtual ULONG AddRef()
{
++m_lRef;
return m_lRef;
}
virtual ULONG Release()
{
ULONG ret = --m_lRef;
if (0 == m_lRef)
delete this;
return ret;
}
#endif
};
// тип в DrawPath
const long c_nStroke = 0x0001;
const long c_nWindingFillMode = 0x0100;
......@@ -177,6 +122,15 @@ const long c_nHtmlRendrerer3 = 0x0011;
// IRenderer
class IRenderer : public IGrObject
{
public:
bool m_bUseTransformCoordsToIdentity;
public:
IRenderer()
{
m_bUseTransformCoordsToIdentity = false;
}
public:
// тип рендерера-----------------------------------------------------------------------------
virtual HRESULT get_Type(LONG* lType) = 0;
......@@ -333,6 +287,17 @@ public:
virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand) = 0;
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand) = 0;
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand) = 0;
virtual HRESULT StartConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = true;
return S_OK;
}
virtual HRESULT EndConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = false;
return S_OK;
}
};
#define PROPERTY_RENDERER(NameBase, Name, Type) \
......
......@@ -173,6 +173,9 @@ namespace NSHtmlRenderer
virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand);
virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand);
virtual HRESULT StartConvertCoordsToIdentity();
virtual HRESULT EndConvertCoordsToIdentity();
// owner params ----------------------------------------------------------------------
virtual HRESULT get_Mode(LONG *plMode);
virtual HRESULT put_Mode(LONG lMode);
......
......@@ -1206,6 +1206,21 @@ namespace NSHtmlRenderer
return S_OK;
}
HRESULT CASCHTMLRenderer3::StartConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = true;
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.StartConvertCoordsToIdentity();
return S_OK;
}
HRESULT CASCHTMLRenderer3::EndConvertCoordsToIdentity()
{
m_bUseTransformCoordsToIdentity = false;
if (m_pInternal->m_bIsGraphicsDumperMode)
return m_pInternal->m_oDumper.EndConvertCoordsToIdentity();
return S_OK;
}
// owner params ----------------------------------------------------------------------
HRESULT CASCHTMLRenderer3::get_Mode(LONG *plMode)
{
......
......@@ -811,6 +811,19 @@ namespace NSHtmlRenderer
return m_pRenderer->put_ClipMode(lMode);
return S_OK;
}
inline virtual HRESULT StartConvertCoordsToIdentity()
{
if (m_pRenderer)
m_pRenderer->StartConvertCoordsToIdentity();
return S_OK;
}
inline virtual HRESULT EndConvertCoordsToIdentity()
{
if (m_pRenderer)
m_pRenderer->EndConvertCoordsToIdentity();
return S_OK;
}
};
......
......@@ -46,7 +46,7 @@
//#define ONLINE_WORD_TO_PDF
//#define TO_PDF
#define TO_HTML_RENDERER
#define ONLY_TEXT
//#define ONLY_TEXT
int main(int argc, char *argv[])
{
......@@ -97,8 +97,18 @@ int main(int argc, char *argv[])
//std::wstring sFile = L"D:\\bankomats.xps";
//std::wstring sFile = L"\\\\kirillov8\\_Office\\DJVU\\Основы разработки приложений на платформе Microsoft .NET Framework. Учебный курс Microsoft экзамен 70-536.djvu";
//std::wstring sFile = L"D:\\TESTFILES\\Алгоритмы - построение и анализ.djvu";
std::wstring sFile = L"D:\\TESTFILES\\PDF 1-7 (756p).pdf";
#ifndef WIN32
std::wstring sFile = L"/home/oleg/GIT/ddd/ZfAvCwDsowJALpClgmE_/source/ZfAvCwDsowJALpClgmE_.pdf";
#else
//std::wstring sFile = L"D:\\ddd\\ZfAvCwDsowJALpClgmE_\\source\\ZfAvCwDsowJALpClgmE_.pdf";
std::wstring sFile = L"D:\\ddd\\knopk5_0.pdf";
#endif
#ifdef WIN32
std::wstring sDst = L"D:\\test\\Document";
#else
std::wstring sDst = L"/home/oleg/test/Document";
#endif
//std::wstring sFile = L"/home/oleg/activex/Android intro(2p).pdf";
//std::wstring sFile = L"/home/oleg/activex/Pi(1p).pdf";
......@@ -114,6 +124,8 @@ int main(int argc, char *argv[])
pReader->SetTempDirectory(sDst);
pReader->LoadFromFile(sFile);
//pReader->ConvertToRaster(0, L"D:\\111.png", 4);
#ifdef TO_HTML_RENDERER
NSHtmlRenderer::CASCHTMLRenderer3 oRenderer;
#ifdef ONLY_TEXT
......
......@@ -25,42 +25,20 @@ INCLUDEPATH += \
TEMPLATE = app
############### destination path ###############
DESTINATION_SDK_PATH = $$PWD/../../build/lib
# WINDOWS
win32:contains(QMAKE_TARGET.arch, x86_64):{
CONFIG(debug, debug|release) {
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/win_64/DEBUG
} else {
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/win_64
}
}
win32:!contains(QMAKE_TARGET.arch, x86_64):{
CONFIG(debug, debug|release) {
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/win_32/DEBUG
} else {
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/win_32
}
}
linux-g++:contains(QMAKE_HOST.arch, x86_64):{
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/linux_64
}
linux-g++:!contains(QMAKE_HOST.arch, x86_64):{
DESTINATION_SDK_PATH = $$DESTINATION_SDK_PATH/linux_32
}
LIBS += -L$$DESTINATION_SDK_PATH -lgraphics
LIBS += -L$$DESTINATION_SDK_PATH -lOfficeUtils
LIBS += -L$$DESTINATION_SDK_PATH -lHtmlRenderer
LIBS += -L$$DESTINATION_SDK_PATH -lPdfReader
LIBS += -L$$DESTINATION_SDK_PATH -lDjVuFile
LIBS += -L$$DESTINATION_SDK_PATH -lXpsFile
LIBS += -L$$DESTINATION_SDK_PATH -lPdfWriter
LIBS += -L$$DESTINATION_SDK_PATH -lUnicodeConverter
LIBS += -L$$PWD/../../build/bin/icu/win_64
CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lgraphics
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lOfficeUtils
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lHtmlRenderer
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lPdfReader
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lDjVuFile
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lXpsFile
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lPdfWriter
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lUnicodeConverter
include($$PWD/../../Common/3dParty/icu/icu.pri)
win32 {
LIBS += -lgdi32 \
......
......@@ -2827,12 +2827,31 @@ namespace PdfReader
double dShiftX = 0, dShiftY = 0;
DoTransform(pMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionUnion);
m_pRenderer->PathCommandEnd();
m_pRenderer->put_FontStringGID(true);
m_pRenderer->PathCommandText(wsText, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
m_pRenderer->EndCommand(c_nClipType);
// TODO: нужна нормальная конвертация
int nLen = (int)wsText.length();
const wchar_t* pDataSrc = wsText.c_str();
if (1 == wsText.length())
m_pRenderer->PathCommandTextExCHAR(0, (LONG)pDataSrc[0], PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
else if (0 != nLen)
{
unsigned int* pGids = new unsigned int[nLen];
for (int nIndex = 0; nIndex < nLen; ++nIndex)
pGids[nIndex] = (unsigned int)pDataSrc[nIndex];
m_pRenderer->PathCommandTextEx(L"", pGids, nLen, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
RELEASEARRAYOBJECTS(pGids);
}
}
void RendererOutputDev::EndTextObject(GrState *pGState)
{
if (NULL != m_pBufferTextClip)
{
UpdateClip(pGState);
RELEASEOBJECT(m_pBufferTextClip);
}
}
void RendererOutputDev::BeginStringOperator(GrState *pGState)
{
......@@ -2846,9 +2865,7 @@ namespace PdfReader
// Обработка Clip
if (nRenderMode >= 4)
{
if (m_pBufferTextClip)
delete m_pBufferTextClip;
RELEASEOBJECT(m_pBufferTextClip);
m_pBufferTextClip = new GrTextClip();
}
......@@ -2879,17 +2896,6 @@ namespace PdfReader
if (m_pBufferTextClip)
pGState->GetClip()->AppendTextClip(m_pBufferTextClip);
for (int nIndex = 0; nIndex < m_pBufferTextClip->GetTextsCount(); nIndex++)
{
WString wsFontName, wsFontPath;
int nFontStyle;
double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0;
WString wsText = m_pBufferTextClip->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &nFontStyle);
double *pMatrix = m_pBufferTextClip->GetMatrix(nIndex);
ClipToText(std::wstring(wsFontName), std::wstring(wsFontPath), dFontSize, nFontStyle, pMatrix, std::wstring(wsText), dX, dY, dWidth, dHeight, dBaseLineOffset);
}
UpdateFont(pGState);
}
......@@ -3670,12 +3676,12 @@ namespace PdfReader
// return;
//}
if (-1 == nPathIndex)
{
int nPathIndexStart = (-1 == nPathIndex) ? 0 : nPathIndex;
m_pRenderer->BeginCommand(c_nResetClipType);
m_pRenderer->EndCommand(c_nResetClipType);
for (int nIndex = 0; nIndex < pClip->GetPathsCount(); nIndex++)
for (int nIndex = nPathIndexStart; nIndex < pClip->GetPathsCount(); nIndex++)
{
GrPath *pPath = pClip->GetPath(nIndex);
int nFlag = pClip->GetFlag(nIndex);
......@@ -3689,9 +3695,17 @@ namespace PdfReader
DoPath(pGState, pPath, pGState->GetPageHeight(), pMatrix);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
m_pRenderer->PathCommandEnd();
}
for (int nIndex = 0; nIndex < pClip->GetTextsCount(); nIndex++)
int nTextClipCount = pClip->GetTextsCount();
if (-1 == nPathIndex && nTextClipCount > 0)
{
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect);
m_pRenderer->StartConvertCoordsToIdentity();
for (int nIndex = 0; nIndex < nTextClipCount; nIndex++)
{
WString wsFontName, wsFontPath;
int lFontStyle;
......@@ -3707,33 +3721,36 @@ namespace PdfReader
double dShiftX = 0, dShiftY = 0;
DoTransform(pClip->GetTextMatrix(nIndex), &dShiftX, &dShiftY, true);
int nFlags = 0;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionUnion);
m_pRenderer->PathCommandEnd();
m_pRenderer->put_FontStringGID(true);
m_pRenderer->PathCommandText(wsText, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
m_pRenderer->EndCommand(c_nClipType);
}
}
else
// TODO: нужна нормальная конвертация
int nLen = 0;
WString wsTextTmp = wsText;
if (wsTextTmp)
{
for (int nIndex = nPathIndex; nIndex < pClip->GetPathsCount(); nIndex++)
while (*wsTextTmp)
++wsTextTmp;
nLen = (int)(wsTextTmp - wsText);
}
if (1 == nLen)
m_pRenderer->PathCommandTextExCHAR(0, (LONG)wsText[0], PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
else if (0 != nLen)
{
GrPath *pPath = pClip->GetPath(nIndex);
int nFlag = pClip->GetFlag(nIndex);
double *pMatrix = pClip->GetMatrix(nIndex);
unsigned int* pGids = new unsigned int[nLen];
for (int nIndex = 0; nIndex < nLen; ++nIndex)
pGids[nIndex] = (unsigned int)wsText[nIndex];
int nClipFlag = GrClipEOFlag == nFlag ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding;
nClipFlag |= c_nClipRegionIntersect;
m_pRenderer->PathCommandTextEx(L"", pGids, nLen, PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight));
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(nClipFlag);
DoPath(pGState, pPath, pGState->GetPageHeight(), pMatrix);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
RELEASEARRAYOBJECTS(pGids);
}
}
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
m_pRenderer->PathCommandEnd();
m_pRenderer->EndConvertCoordsToIdentity();
}
if (m_pClip)
......
......@@ -240,6 +240,7 @@ namespace PdfReader
virtual void ClipToStrokePath(GrState *pGState);
virtual void ClipToPath(GrState *pGState, GrPath *pPath, double *pMatrix, bool bEO);
//----- Вывод текста
virtual void EndTextObject(GrState *pGState);
virtual void BeginStringOperator(GrState *pGState);
virtual void EndStringOperator(GrState *pGState);
virtual void DrawString(GrState *pGState, StringExt *seString);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment