mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
8330 lines
479 KiB
C++
8330 lines
479 KiB
C++
// PDFWriter.h : Declaration of the CPDFWriter
|
||
|
||
#pragma once
|
||
|
||
#ifndef _ONLY_PDF_WRITER_INTERFACE
|
||
|
||
#include "resource.h" // main symbols
|
||
|
||
#include "../ASCImageStudio3/ASCGraphics/Interfaces/ASCRenderer.h"
|
||
#include "../Common/xmlutils.h"
|
||
#include "../ASCImageStudio3/ASCGraphics/Objects/Structures.h"
|
||
|
||
#include "../ASCImageStudio3/ASCGraphics/Interfaces/FileDownloader.h"
|
||
#include "../Common/GdiplusEx.h"
|
||
#include "../Common/ASCUtils.h"
|
||
#include "Base64.h"
|
||
|
||
#ifdef BUILD_CONFIG_FULL_VERSION
|
||
#include "../../../../../../Common/Registration.h"
|
||
#endif
|
||
|
||
#include "Document.h"
|
||
#include "Image.h"
|
||
#include "Font.h"
|
||
#include "Streams.h"
|
||
#include "Utils.h"
|
||
#include "Errors.h"
|
||
#include "MemoryManager.h"
|
||
#include "List.h"
|
||
#include "Streams.h"
|
||
#include "Objects.h"
|
||
#include "Annotation.h"
|
||
#include "Destination.h"
|
||
#include "GraphicState.h"
|
||
#include "MetaData.h"
|
||
#include "Outline.h"
|
||
#include "PageOperations.h"
|
||
#include "Pages.h"
|
||
#include "Catalog.h"
|
||
#include "PDF.h"
|
||
#include "Encoder.h"
|
||
#include "EncryptDictionary.h"
|
||
#include "LZWEncoder.h"
|
||
#include "ImageExt.h"
|
||
|
||
#include "Common.h"
|
||
|
||
//#ifdef _DEBUG
|
||
//
|
||
//#define _CRTDBG_MAP_ALLOC
|
||
//#include <stdlib.h>
|
||
//#include <crtdbg.h>
|
||
//
|
||
//#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||
//
|
||
//#define new DEBUG_NEW
|
||
//
|
||
//#endif
|
||
|
||
#endif
|
||
|
||
#include "OnlineOfficeBinToPdf.h"
|
||
|
||
// IPDFWriter
|
||
[
|
||
object,
|
||
uuid("BDA96253-29C4-4C62-98DC-D9718695883C"),
|
||
dual, helpstring("IPDFWriter Interface"),
|
||
pointer_default(unique)
|
||
]
|
||
__interface IPDFWriter : IDispatch
|
||
{
|
||
//----- Основные функции для работы с документом ---------------------------------------------------
|
||
|
||
[id(11)]HRESULT CreatePDF();
|
||
[id(12)]HRESULT DeletePDF();
|
||
[id(13)]HRESULT SaveToFile([in] BSTR bsPath);
|
||
|
||
[id(21)]HRESULT SetPDFPageMode([in]long nMode);
|
||
[id(22)]HRESULT GetPDFPageMode([out, retval]long *pnMode);
|
||
[id(23)]HRESULT SetPDFPageLayout([in]long nLayout);
|
||
[id(24)]HRESULT GetPDFPageLayout([out, retval]long *pnLayout);
|
||
[id(25)]HRESULT SetPDFViewerPreference([in]long nValue );
|
||
[id(26)]HRESULT GetPDFViewerPreference([out, retval]long *pnValue);
|
||
|
||
[id(30)]HRESULT SetPDFCompressionMode([in]long nMode);
|
||
[id(31)]HRESULT SetPDFOpenAction([in]long nAction);
|
||
|
||
[id(50)]HRESULT GetLastErrorCode([out, retval]long *pnErrorCode);
|
||
[id(51)]HRESULT GetLastErrorString([out, retval]BSTR *pbsErrorString);
|
||
|
||
|
||
//----- Функции для работы со страницами -----------------------------------------------------------
|
||
|
||
[id(101)]HRESULT AddNewPage();
|
||
[id(102)]HRESULT GetPagesCount([out, retval] long *pnCount);
|
||
[id(103)]HRESULT SetCurrentPage([in] long nIndex);
|
||
[id(104)]HRESULT GetCurrentPageIndex([out, retval] long *pnIndex);
|
||
|
||
[id(105)]HRESULT SetPageWidth([in]float fValue);
|
||
[id(106)]HRESULT SetPageHeight([in]float fValue);
|
||
[id(107)]HRESULT GetWidth([out, retval]float *pfValue);
|
||
[id(108)]HRESULT GetHeight([out, retval]float *pfValue);
|
||
[id(109)]HRESULT SetSize([in]long nSize, [in]long nDirection);
|
||
[id(110)]HRESULT SetRotate([in]long nAngle);
|
||
|
||
[id(120)]HRESULT AddLabel([in]long nPageNum, [in]long nNumStyle, [in]long nFirstPage, [in]BSTR bsPrefix );
|
||
|
||
|
||
|
||
//----- Функции рисования и вывода текста ----------------------------------------------------------
|
||
|
||
[id(201)]HRESULT SetLineWidth([in] float fLineWidth );
|
||
[id(202)]HRESULT GetLineWidth([out, retval] float *pfLineWidth);
|
||
|
||
[id(203)]HRESULT SetLineCap([in] long nLineCap);
|
||
[id(204)]HRESULT GetLineCap([out, retval] long *pnLineCap);
|
||
|
||
[id(205)]HRESULT SetLineJoin([in]long nLineJoin);
|
||
[id(206)]HRESULT GetLineJoin([out, retval]long *pnLineJoin);
|
||
|
||
[id(207)]HRESULT SetMiterLimit([in]float fMiterLimit);
|
||
[id(208)]HRESULT GetMiterLimit([out, retval]float *pfMiterLimit);
|
||
|
||
[id(209)]HRESULT SetDash([in, satype("float")] SAFEARRAY** ppnDashPtn, [in] long nNumParam, [in] float fPhase);
|
||
[id(210)]HRESULT GetDash([out, satype("float")] SAFEARRAY** ppnDashPtn, [out]long *pnNumParam, [out]float *pfPhase);
|
||
|
||
[id(211)]HRESULT SetFlat([in] float fFlatness);
|
||
[id(212)]HRESULT GetFlat([out, retval]float *pfFlatness);
|
||
|
||
[id(213)]HRESULT NewExtGraphicsState();
|
||
[id(214)]HRESULT ExtGraphicsStateSetAlphaStroke([in]float fValue);
|
||
[id(215)]HRESULT ExtGraphicsStateSetAlphaFill([in]float fValue);
|
||
[id(216)]HRESULT ExtGraphicsStateSetBlendMode([in]long nBlendMode);
|
||
[id(217)]HRESULT ExtGraphicsStateSetStrokeAdjustment([in]int nFlag);
|
||
[id(218)]HRESULT SetExtGraphicsState();
|
||
[id(219)]HRESULT GSave();
|
||
[id(220)]HRESULT GRestore();
|
||
|
||
[id(221)]HRESULT GetGStateDepth([out, retval]long *pnDepth);
|
||
[id(222)]HRESULT GetGMode([out, retval]long *pnGMode);
|
||
|
||
[id(223)]HRESULT Concat([in]float fA, [in]float fB, [in]float fC, [in]float fD, [in]float fX, [in]float fY);
|
||
|
||
[id(224)]HRESULT MoveTo([in]float fX, [in]float fY);
|
||
[id(225)]HRESULT GetCurrentPosition([out] float *pfX, [out] float *pfY);
|
||
|
||
[id(226)]HRESULT LineTo([in]float fX, [in]float fY);
|
||
[id(227)]HRESULT CurveTo ([in]float fX1, [in]float fY1, [in]float fX2, [in]float fY2, [in]float fX3, [in]float fY3);
|
||
[id(228)]HRESULT CurveTo2([in]float fX2, [in]float fY2, [in]float fX3, [in]float fY3);
|
||
[id(229)]HRESULT CurveTo3([in]float fX1, [in]float fY1, [in]float fX3, [in]float fY3);
|
||
[id(230)]HRESULT ClosePath();
|
||
[id(231)]HRESULT AppendRectangle([in]float fX, [in]float fY, [in]float fWidth, [in]float fHeight);
|
||
|
||
[id(232)]HRESULT Stroke();
|
||
[id(233)]HRESULT GetStrokingColorSpace([out, retval]long *pnColorSpace);
|
||
|
||
[id(234)]HRESULT ClosePathStroke();
|
||
|
||
[id(235)]HRESULT Fill();
|
||
[id(236)]HRESULT GetFillingColorSpace([out, retval]long *pnColorSpace);
|
||
[id(237)]HRESULT EoFill();
|
||
[id(238)]HRESULT FillStroke();
|
||
[id(239)]HRESULT EoFillStroke();
|
||
[id(240)]HRESULT ClosePathFillStroke();
|
||
[id(241)]HRESULT ClosePathEoFillStroke();
|
||
[id(242)]HRESULT EndPath();
|
||
[id(243)]HRESULT Clip();
|
||
[id(244)]HRESULT EoClip();
|
||
[id(245)]HRESULT BeginText();
|
||
[id(246)]HRESULT EndText();
|
||
|
||
[id(247)]HRESULT SetCharSpace([in] float fValue);
|
||
[id(248)]HRESULT GetCharSpace([out, retval]float *pfValue);
|
||
|
||
[id(249)]HRESULT SetWordSpace([in]float fValue);
|
||
[id(250)]HRESULT GetWordSpace([out, retval]float *pfValue);
|
||
|
||
[id(251)]HRESULT SetHorizontalScalling([in]float fValue);
|
||
[id(252)]HRESULT GetHorizontalScalling([out, retval]float *pfValue);
|
||
|
||
[id(253)]HRESULT SetTextLeading([in]float fValue);
|
||
[id(254)]HRESULT GetTextLeading([out, retval]float *pfValue);
|
||
|
||
[id(255)]HRESULT SetFontAndSizeToGState([in]float fSize);
|
||
[id(256)]HRESULT GetCurrentFontFromGState([out]BSTR *pbsFontName, [out]BSTR *pbsEncodingName);
|
||
[id(257)]HRESULT GetCurrentFontSizeFromGState([out, retval]float *pfSize);
|
||
|
||
[id(258)]HRESULT SetTextRenderingMode([in]long nMode);
|
||
[id(259)]HRESULT GetTextRenderingMode([out, retval]long *pnMode);
|
||
|
||
[id(260)]HRESULT SetTextRise([in]float fValue);
|
||
[id(261)]HRESULT GetTextRise([out, retval]float *pfValue);
|
||
|
||
[id(262)]HRESULT MoveTextPos([in]float fX, [in]float fY);
|
||
[id(263)]HRESULT MoveTextPos2([in]float fX, [in]float fY);
|
||
[id(264)]HRESULT GetCurrentTextPosition([out] float *pfX, [out] float *pfY);
|
||
|
||
[id(265)]HRESULT SetTextMatrix([in] float fA, [in] float fB, [in] float fC, [in] float fD, [in] float fX, [in] float fY);
|
||
[id(266)]HRESULT GetTextMatrix([out]float* pfA, [out]float* pfB, [out]float* pfC, [out]float* pfD, [out] float* pfX, [out]float* pfY);
|
||
|
||
[id(267)]HRESULT MoveToNextLine();
|
||
|
||
[id(268)]HRESULT ShowText([in] BSTR bsText);
|
||
[id(269)]HRESULT ShowTextNextLine([in] BSTR bsText);
|
||
[id(270)]HRESULT ShowTextNextLineEx([in]float fWordSpace, [in]float fCharSpace, [in]BSTR bsText);
|
||
|
||
[id(271)]HRESULT SetGrayStroke([in] float fGray);
|
||
[id(272)]HRESULT GetGrayStroke([out, retval]float *pfGray);
|
||
|
||
[id(273)]HRESULT SetGrayFill([in] float fGray);
|
||
[id(274)]HRESULT GetGrayFill([out, retval]float *pfGray);
|
||
|
||
[id(275)]HRESULT SetRGBStroke([in ]float fR, [in] float fG, [in] float fB);
|
||
[id(276)]HRESULT GetRGBStroke([out]float *pfR, [out]float *pfG, [out]float *pfB);
|
||
|
||
[id(277)]HRESULT SetRGBFill([in] float fR, [in] float fG, [in] float fB);
|
||
[id(278)]HRESULT GetRGBFill([out]float *pfR, [out]float *pfG, [out]float *pfB);
|
||
|
||
[id(279)]HRESULT SetCMYKStroke([in] float fC, [in] float fM, [in] float fY, [in] float fK);
|
||
[id(280)]HRESULT GetCMYKStroke([out]float *pfC, [out]float *pfM, [out]float *pfY, [out]float *pfK);
|
||
|
||
[id(281)]HRESULT SetCMYKFill([in] float fC, [in] float fM, [in] float fY, [in] float fK);
|
||
[id(282)]HRESULT GetCMYKFill([out]float *pfC, [out]float *pfM, [out]float *pfY, [out]float *pfK);
|
||
|
||
[id(283)]HRESULT ExecuteXObject();
|
||
|
||
[id(284)]HRESULT AppendCircle ([in]float fX, [in]float fY, [in]float fRay);
|
||
[id(285)]HRESULT AppendEllipse ([in]float fX, [in]float fY, [in]float fXRad, [in]float fYRad);
|
||
[id(286)]HRESULT AppendArc ([in]float fX, [in]float fY, [in]float fRad, [in]float fAngle1, [in]float fAngle2);
|
||
[id(287)]HRESULT AppendEllipseArc([in]float fX, [in]float fY, [in]float fXRad, [in]float fYRad, [in]float fAngle1, [in]float fAngle2, [in]BOOL bClockDirection = FALSE);
|
||
[id(288)]HRESULT TextOut([in]float fXPos, [in]float fYPos, [in] BSTR bsText);
|
||
[id(289)]HRESULT TextRect([in]float fLeft, [in]float fTop, [in]float fRight, [in]float fBottom, [in] BSTR bsText, [in]long nAlign, [in, out]unsigned int *pnLen);
|
||
[id(290)]HRESULT SetSlideShow(long nType, float fDispTime, float fTransTime);
|
||
[id(291)]HRESULT GetTextWidth([in]BSTR bsText, [out, retval] float *pfResult);
|
||
[id(292)]HRESULT MeasureText([in]BSTR bsText, [in]float fWidth, [in]BOOL bWordWrap, [in, out]float *pfRealWidth, [out, retval]long *pnLength);
|
||
|
||
[id(293)]HRESULT SetExtGraphicsState2(BSTR bsXmlOptions);
|
||
|
||
//----- Функции для работы с фонтами ---------------------------------------------------------------
|
||
|
||
[id(301)]HRESULT LoadT1FFromFile([in]BSTR bsAFMFileName, [in]BSTR bsDataFileName, [out, retval]BSTR *bsFontName);
|
||
[id(302)]HRESULT LoadTTFFromFile([in]BSTR bsFileName, [in]BOOL bEmbedding, [in] BSTR bsEncodingName, [out, retval] BSTR *bsFontName);
|
||
[id(303)]HRESULT LoadTTCFromFile([in]BSTR bsFileName, [in]long nIndex, [in] BOOL bEmbedding, [out, retval] BSTR *bsFontName);
|
||
[id(304)]HRESULT SetCurrentFont([in] BSTR bsFontName, [in] BSTR bsEncodingName, [in]BOOL bNameIsUnicodeArray, [in]BSTR bsToUnicodeName);
|
||
[id(305)]HRESULT GetCurrentFont([out]BSTR *pbsFontName, [out]BSTR *pbsEncodingName);
|
||
[id(306)]HRESULT GetFontUnicodeWidth ([in]long nCode, [out, retval]long *pnUnicode);
|
||
[id(307)]HRESULT GetFontBBox ([out]float *pfLeft, [out]float *pfBottom, [out]float *pfRight, [out]float *pfTop);
|
||
[id(308)]HRESULT GetFontAscent ([out, retval]long *pnAscent);
|
||
[id(309)]HRESULT GetFontDescent ([out, retval]long *pnDescent);
|
||
[id(310)]HRESULT GetFontXHeight ([out, retval]long *pnXHeight);
|
||
[id(311)]HRESULT GetFontCapHeight ([out, retval]long *pnCapHeight);
|
||
|
||
//----- Функции для работы с кодировкой -----------------------------------------------------------
|
||
|
||
[id(401)]HRESULT SetCurrentEncoder([in]BSTR bsEncodingName);
|
||
[id(402)]HRESULT GetCurrentEncoder([out, retval]BSTR *pbsEncodingName);
|
||
[id(403)]HRESULT GetEncoderUnicode([in]long nCode, [out, retval]long *pnUnicode);
|
||
[id(404)]HRESULT GetEncoderByteType([in]BSTR bsText, [in]long nIndex, [out, retval]long *pnByteType);
|
||
[id(405)]HRESULT GetEncoderType([out, retval]long *pnEncoderType);
|
||
[id(406)]HRESULT GetEncoderWritingMode([out, retval]long *pnWritingMode);
|
||
|
||
//----- Функции для работы с Annotation ------------------------------------------------------------
|
||
|
||
[id(501)]HRESULT CreateTextAnnot ([in]float fLeft, [in]float fBottom, [in]float fRight, [in]float fTop, [in]BSTR bsText, [in]BSTR bsEncoder);
|
||
[id(502)]HRESULT CreateLinkAnnot ([in]float fLeft, [in]float fBottom, [in]float fRight, [in]float fTop);
|
||
[id(503)]HRESULT CreateUriLinkAnnot ([in]float fLeft, [in]float fBottom, [in]float fRight, [in]float fTop, [in]BSTR bsUrl);
|
||
[id(504)]HRESULT ArbAnnotationSetBorderStyle ([in]long nSubtype, [in]float fWidth, [in]long nDashOn, [in]long nDashOff, [in]long nDashPhase);
|
||
[id(505)]HRESULT LinkAnnotationSetBorderStyle ([in]float fWidth, [in]long nDashOn, [in]long nDashOff );
|
||
[id(506)]HRESULT LinkAnnotationSetHighlightMode([in]long nMode);
|
||
[id(507)]HRESULT TextAnnotationSetIcon ([in]long nIcon);
|
||
[id(508)]HRESULT TextAnnotationSetOpened ([in]BOOL bOpened);
|
||
[id(509)]HRESULT SetCurrentAnnot([in]long nIndex);
|
||
[id(510)]HRESULT GetCurrentAnnotIndex([out, retval]long *pnIndex);
|
||
[id(511)]HRESULT MakeAnnotationFromXml([in]BSTR bsXML);
|
||
|
||
//----- Функции для работы с Destination -----------------------------------------------------------
|
||
|
||
[id(601)]HRESULT CreateNewDestination();
|
||
[id(602)]HRESULT DestSetXYZ ([in]float fLeft, [in]float fTop, [in]float fZoom);
|
||
[id(603)]HRESULT DestSetFit ();
|
||
[id(604)]HRESULT DestSetFitH ([in]float fTop);
|
||
[id(605)]HRESULT DestSetFitV ([in]float fLeft);
|
||
[id(606)]HRESULT DestSetFitR ([in]float fLeft, [in]float fBottom, [in]float fRight, [in]float fTop);
|
||
[id(607)]HRESULT DestSetFitB ();
|
||
[id(608)]HRESULT DestSetFitBH([in]float fTop);
|
||
[id(609)]HRESULT DestSetFitBV([in]float fLeft);
|
||
[id(610)]HRESULT SetCurrentDest([in]long nIndex);
|
||
[id(611)]HRESULT GetCurrentDestIndex([out, retval]long *pnIndex);
|
||
|
||
//----- Функции для работы с Outline ---------------------------------------------------------------
|
||
|
||
[id(701)]HRESULT CreateNewOutline( [in]long nParentIndex, [in]BSTR bsTitle, [in]BSTR bsEncoder);
|
||
[id(702)]HRESULT OutlineSetCurrentDestination();
|
||
[id(703)]HRESULT SetOutlineOpened([in]BOOL bOpened);
|
||
[id(704)]HRESULT SetCurrentOutline([in]long nIndex);
|
||
[id(705)]HRESULT GetCurrentOutlineIndex([out, retval]long *pnIndex);
|
||
[id(706)]HRESULT MakeOutlineFromXml([in]BSTR bsXML);
|
||
|
||
//----- Функции для работы с картинками -----------------------------------------------------------
|
||
|
||
[id(801)]HRESULT LoadJpegFromFile([in]BSTR bsFileName);
|
||
[id(802)]HRESULT LoadJpxFromFile([in]BSTR bsFileName, [in]long nFlag);
|
||
[id(803)]HRESULT LoadImageFromFile ([in]BSTR bsFileName, [in]long nWidth, [in]long nHeight, [in]long nColorSpace);
|
||
[id(804)]HRESULT LoadImageFromArray([in, satype("byte")]SAFEARRAY **ppImage, [in]long nWidth, [in]long nHeight, [in]long nColorSpace, [in]long nBitsPerComponent);
|
||
[id(805)]HRESULT LoadImageFromInterface([in]IUnknown **pInterface, [in] BOOL bAlpha = FALSE);
|
||
[id(806)]HRESULT DrawCurrentImage([in]float fX, [in]float fY, [in]float fWidth, [in]float fHeight);
|
||
[id(807)]HRESULT GetImageBitsPerComponent([out, retval]long *pnBitsPerComponent);
|
||
[id(808)]HRESULT GetImageColorSpace([out, retval]long *pnColorSpace);
|
||
[id(809)]HRESULT GetImageHeight([out, retval]long *pnHeight);
|
||
[id(810)]HRESULT GetImageWidth([out, retval]long *pnWidth);
|
||
[id(811)]HRESULT SetImageColorMask([in]long nRMin, [in]long nRMax, [in]long nGMin, [in]long nGMax, [in]long nBMin, [in]long nBMax);
|
||
[id(812)]HRESULT SetImageMaskImage([in]long nMaskImageIndex);
|
||
[id(813)]HRESULT SetCurrentImage([in]long nIndex);
|
||
[id(814)]HRESULT GetCurrentImageIndex([out, retval]long *pnIndex);
|
||
|
||
|
||
//----- Функции для работы с шифрованием ----------------------------------------------------------
|
||
|
||
[id(901)]HRESULT SetEncryptOn ();
|
||
[id(902)]HRESULT SetPDFPassword ([in]BSTR bsOwnerPassword, [in]BSTR bsUserPassword);
|
||
[id(903)]HRESULT SetPDFPermission ([in]long nPermission);
|
||
[id(904)]HRESULT SetPDFEncryptionMode ([in]long nMode, [in]long nKeyLen);
|
||
[id(905)]HRESULT SetEncryptOff ();
|
||
|
||
//----- Функции для работы с метаданными ----------------------------------------------------------
|
||
|
||
[id(1001)]HRESULT GetInfoItem([in]long nDataType, [out, retval]BSTR *pbsItem);
|
||
[id(1002)]HRESULT SetInfoItem([in]long nDataType, [in]BSTR bsData);
|
||
[id(1003)]HRESULT SetInfoDateItem([in]long nType, [in]long nYear, [in]long nMonth, [in]long nDay, [in]long nHour, [in]long nMinutes, [in]long nSeconds, [in]long nInd, [in]long nOffHour, [in]long nOffMinutes);
|
||
|
||
//----- Для дополнительных функций ----------------------------------------------------------------
|
||
|
||
[id(10001)] HRESULT SetAdditionalParam([in] BSTR ParamName, [in] VARIANT ParamValue);
|
||
[id(10002)] HRESULT GetAdditionalParam([in] BSTR ParamName, [out] VARIANT * ParamValue);
|
||
|
||
};
|
||
|
||
#ifndef _ONLY_PDF_WRITER_INTERFACE
|
||
|
||
// IPDFRenderer
|
||
[
|
||
object,
|
||
uuid("D08C792F-6989-4a55-8F78-C962FE895BA6"),
|
||
dual, helpstring("IPDFRenderer Interface"),
|
||
pointer_default(unique)
|
||
]
|
||
__interface IPDFRenderer : IASCRenderer
|
||
{
|
||
|
||
};
|
||
|
||
// IOnlineWordToPDFWriter
|
||
[
|
||
object,
|
||
uuid("3B5E1A55-58E8-4458-A5D2-6709F4BC3E99"),
|
||
dual, helpstring("IOnlineWordToPDFWriter Interface"),
|
||
pointer_default(unique)
|
||
]
|
||
__interface IOnlineWordToPDFWriter: IDispatch
|
||
{
|
||
[id(10101)] HRESULT OnlineWordToPdf (BSTR sPathXml, BSTR sDstFile, BSTR sHtmlPlace, LONG nReg);
|
||
};
|
||
|
||
|
||
// CPDFWriter
|
||
|
||
[
|
||
coclass,
|
||
default(IPDFWriter),
|
||
threading(apartment),
|
||
vi_progid("AVSOfficePDFWriter.PDFWriter"),
|
||
progid("AVSOfficePDFWriter.PDFWriter.1"),
|
||
version(1.0),
|
||
uuid("D2F0543F-2CEC-4A57-A579-8059EBF71EE0"),
|
||
helpstring("PDFWriter Class")
|
||
]
|
||
class ATL_NO_VTABLE CPDFWriter
|
||
: public IPDFWriter
|
||
, public IPDFRenderer
|
||
, public IOnlineWordToPDFWriter
|
||
{
|
||
|
||
private:
|
||
|
||
// для IPDFWriter
|
||
|
||
Doc m_pDocument;
|
||
FontDict m_pCurrentFont;
|
||
ExtGState m_pCurrentExtGState;
|
||
|
||
XObject m_pCurrentXObject;
|
||
List m_pXObjectList;
|
||
|
||
Annotation m_pCurrentAnnotation;
|
||
List m_pAnnotList;
|
||
|
||
Destination m_pCurrentDestination;
|
||
List m_pDestList;
|
||
|
||
Outline m_pCurrentOutline;
|
||
List m_pOutlineList;
|
||
|
||
List m_pFontEncodingList;
|
||
|
||
PDF::PatternStorage m_oPatterns; // add patterns in commands
|
||
PDF::PaintState m_oPatternState; // current pattern
|
||
|
||
PDF::XForm* m_XForm;
|
||
CString m_MaskWithFormCommands;
|
||
int m_BlockCommandsStart;
|
||
BOOL m_IsStrokeShape;
|
||
|
||
// для вырезки, хардкор
|
||
|
||
CString m_strPatternFill;
|
||
CString m_strPatternStroke;
|
||
|
||
// для IPDFRenderer
|
||
|
||
NSStructures::CPen m_oPen;
|
||
NSStructures::CBrush m_oBrush;
|
||
NSStructures::CFont m_oFont;
|
||
NSStructures::CShadow m_oShadow;
|
||
NSStructures::CEdgeText m_oEdgeText;
|
||
|
||
Gdiplus::GraphicsPath m_oCurPath;
|
||
|
||
double m_dCharSpace;
|
||
|
||
BOOL m_bStartSubPath;
|
||
BOOL m_bGStateChange;
|
||
|
||
BOOL m_bClipPath;
|
||
TMatrix m_oClipCTM;
|
||
TMatrix m_oBaseTransform;
|
||
TCommandParams m_oCommandParams;
|
||
TCommandType* m_pCurCommand;
|
||
|
||
CFindFonts* m_pFindFonts;
|
||
CGdiPath* m_pCurPath;
|
||
BOOL m_bUseTextureRect; // Используем ли рект для текстурной заливки (заданный в m_oBrush)
|
||
BOOL m_bUseImageTransform; // Заглушка для функции DrawImage (использовать ли там трансформ)
|
||
|
||
CFontLoader m_oFontLoader;
|
||
HANDLE m_hSynchMutex;
|
||
CString m_wsTempDir;
|
||
|
||
#ifdef BUILD_CONFIG_OPENSOURCE_VERSION
|
||
OfficeCore::IWinFonts* m_pFontManager;
|
||
#else
|
||
AVSGraphics::IASCFontManager* m_pFontManager;
|
||
#endif
|
||
|
||
BOOL m_bIsWhiteBackImage;
|
||
BOOL m_bUseImageTextureAlpha;
|
||
|
||
CMatrix m_oTransform; // Текущая матрица преобразования
|
||
CContiniousText m_oContiniousText;
|
||
CRendererState m_oRendererState;
|
||
BOOL m_bFirstMoveTo;
|
||
|
||
CGdiPlusInit m_oGdiplusInit;
|
||
|
||
BOOL m_bIsFontsInitialize;
|
||
|
||
public:
|
||
CPDFWriter()
|
||
{
|
||
#ifdef _DEBUG
|
||
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW );
|
||
#endif
|
||
m_oGdiplusInit.Init();
|
||
}
|
||
|
||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||
|
||
HRESULT FinalConstruct()
|
||
{
|
||
#ifdef BUILD_CONFIG_OPENSOURCE_VERSION
|
||
CoCreateInstance( OfficeCore::CLSID_CWinFonts, NULL, CLSCTX_ALL, OfficeCore::IID_IWinFonts, (void**)&m_pFontManager );
|
||
#else
|
||
CoCreateInstance( __uuidof( AVSGraphics::CASCFontManager ), NULL, CLSCTX_ALL, __uuidof( AVSGraphics::IASCFontManager ), (void**)&m_pFontManager );
|
||
#endif
|
||
|
||
m_bIsFontsInitialize = FALSE;
|
||
|
||
m_pFindFonts = NULL;
|
||
|
||
m_hSynchMutex = CreateMutex(NULL, FALSE, _T("AVSPDFWriterMutex") );
|
||
|
||
m_pDocument = NULL;
|
||
m_pCurrentFont = NULL;
|
||
m_pCurrentExtGState = NULL;
|
||
m_pCurrentXObject = NULL;
|
||
m_pXObjectList = NULL;
|
||
m_pOutlineList = NULL;
|
||
m_pDestList = NULL;
|
||
m_pCurrentDestination = NULL;
|
||
m_pAnnotList = NULL;
|
||
m_pCurrentAnnotation = NULL;
|
||
|
||
m_pFontEncodingList = NULL;
|
||
|
||
m_bStartSubPath = FALSE;
|
||
m_bGStateChange = FALSE;
|
||
|
||
m_oCommandParams.dAngle = 0;
|
||
m_oCommandParams.dHeight = -1;
|
||
m_oCommandParams.dLeft = -1;
|
||
m_oCommandParams.dTop = -1;
|
||
m_oCommandParams.dWidth = -1;
|
||
m_oCommandParams.nFlag = 0;
|
||
m_oCommandParams.oMatrix.fA = 1.0f;
|
||
m_oCommandParams.oMatrix.fB = 0.0f;
|
||
m_oCommandParams.oMatrix.fC = 0.0f;
|
||
m_oCommandParams.oMatrix.fD = 1.0f;
|
||
m_oCommandParams.oMatrix.fE = 0.0f;
|
||
m_oCommandParams.oMatrix.fF = 0.0f;
|
||
|
||
m_oShadow.Visible = FALSE;
|
||
|
||
m_oFont.Name = CString( _T("Arial") );
|
||
m_oFont.Size = 12.0;
|
||
|
||
m_dCharSpace = 0.0;
|
||
|
||
m_pCurCommand = NULL;
|
||
|
||
m_pCurPath = NULL;
|
||
|
||
m_bClipPath = FALSE;
|
||
|
||
m_wsTempDir = _T("");
|
||
|
||
m_bIsWhiteBackImage = FALSE;
|
||
m_bUseTextureRect = FALSE;
|
||
m_bUseImageTransform = TRUE;
|
||
m_bUseImageTextureAlpha = FALSE;
|
||
|
||
m_XForm = NULL;
|
||
m_IsStrokeShape = FALSE;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
void FinalRelease()
|
||
{
|
||
FreePDF();
|
||
|
||
if ( m_pFindFonts )
|
||
delete m_pFindFonts;
|
||
|
||
RELEASEHANDLE( m_hSynchMutex );
|
||
RELEASEINTERFACE( m_pFontManager );
|
||
}
|
||
|
||
private:
|
||
|
||
void FreePDF()
|
||
{
|
||
|
||
m_pCurrentFont = NULL;
|
||
m_pCurrentExtGState = NULL;
|
||
m_pCurrentXObject = NULL;
|
||
|
||
if ( m_pOutlineList )
|
||
ListFree2( m_pOutlineList );
|
||
m_pOutlineList = NULL;
|
||
m_pCurrentOutline = NULL;
|
||
|
||
if ( m_pDestList )
|
||
ListFree2( m_pDestList );
|
||
m_pDestList = NULL;
|
||
m_pCurrentDestination = NULL;
|
||
|
||
if ( m_pAnnotList )
|
||
ListFree2( m_pAnnotList );
|
||
m_pAnnotList = NULL;
|
||
m_pCurrentAnnotation = NULL;
|
||
|
||
if ( m_pXObjectList )
|
||
ListFree2( m_pXObjectList );
|
||
m_pXObjectList = NULL;
|
||
m_pCurrentXObject = NULL;
|
||
|
||
if ( m_pFontEncodingList )
|
||
ListFree( m_pFontEncodingList );
|
||
m_pFontEncodingList = NULL;
|
||
|
||
// Документ освобождаем в конце, т.к. все списки строились
|
||
// через m_pDocument->oMMgr
|
||
|
||
if ( m_pDocument )
|
||
Free( m_pDocument );
|
||
m_pDocument = NULL;
|
||
|
||
while( m_pCurCommand )
|
||
{
|
||
TCommandType *pPrev = m_pCurCommand->pPrev;
|
||
delete m_pCurCommand;
|
||
m_pCurCommand = pPrev;
|
||
}
|
||
|
||
if ( m_pCurPath )
|
||
{
|
||
delete m_pCurPath;
|
||
m_pCurPath = NULL;
|
||
}
|
||
|
||
}
|
||
|
||
TFontEncodingPair *FindFontEncodingPair( char* sFontName, char* sEncodingName = NULL )
|
||
{
|
||
if ( NULL == m_pFontEncodingList )
|
||
return NULL;
|
||
|
||
for ( int nIndex = 0; nIndex < m_pFontEncodingList->nCount; nIndex++ )
|
||
{
|
||
TFontEncodingPair *pPair = (TFontEncodingPair *)ListItemAt( m_pFontEncodingList, nIndex );
|
||
if ( NULL == sEncodingName )
|
||
{
|
||
if ( 0 == UtilsStrCmp( pPair->sRealFontName, sFontName ) )
|
||
return pPair;
|
||
}
|
||
else
|
||
{
|
||
if ( 0 == UtilsStrCmp( pPair->sRealFontName, sFontName ) && 0 == UtilsStrCmp( pPair->sEncodingName, sEncodingName ) )
|
||
return pPair;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
unsigned long FontFromFileToPdfFont()
|
||
{
|
||
USES_CONVERSION;
|
||
unsigned long nRet = OK;
|
||
|
||
if ( _T("") != m_oFont.Path )
|
||
{
|
||
CString wsFontName, wsEncodingName, wsToUnicodeName;
|
||
if ( m_oFontLoader.Find( m_oFont.Path, &wsFontName, &wsEncodingName, &wsToUnicodeName ) )
|
||
{
|
||
BSTR bsFontName = NULL;
|
||
if ( wsFontName.GetLength() <= 0 )
|
||
{
|
||
bsFontName = ::SysAllocString( _T("Helvetica") );
|
||
nRet = SetCurrentFont( _T("Helvetica"), NULL, FALSE, NULL );
|
||
::SysFreeString( bsFontName );
|
||
|
||
return nRet;
|
||
}
|
||
|
||
bsFontName = wsFontName.AllocSysString();
|
||
BSTR bsEncoding = NULL, bsToUnicode = NULL;
|
||
if ( wsEncodingName.GetLength() > 0 ) bsEncoding = wsEncodingName.AllocSysString();
|
||
if ( wsToUnicodeName.GetLength() > 0 ) bsToUnicode = wsToUnicodeName.AllocSysString();
|
||
|
||
nRet = SetCurrentFont( bsFontName, bsEncoding, FALSE, bsToUnicode );
|
||
|
||
::SysFreeString( bsFontName );
|
||
if ( bsEncoding ) ::SysFreeString( bsEncoding );
|
||
if ( bsToUnicode ) ::SysFreeString( bsToUnicode );
|
||
|
||
return nRet;
|
||
}
|
||
|
||
wchar_t wsExt[MAX_PATH], wsFileName[MAX_PATH];
|
||
_wsplitpath( m_oFont.Path.GetBuffer(), NULL, NULL, wsFileName, wsExt );
|
||
CStringW sExt( wsExt ), sFileName( wsFileName );
|
||
sExt.MakeLower();
|
||
|
||
BSTR bsPath = m_oFont.Path.AllocSysString();
|
||
BSTR bsPDFFontName = NULL;
|
||
|
||
BOOL bEmb = TRUE, bCIDfont = FALSE;
|
||
if ( _T(".non") == sExt )
|
||
bEmb = FALSE;
|
||
else if ( _T(".cid_non") == sExt )
|
||
{
|
||
bEmb = FALSE;
|
||
bCIDfont = TRUE;
|
||
}
|
||
else if ( _T(".n022003l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_COURIER) ).AllocSysString();
|
||
else if ( _T(".n022004l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_COURIER_BOLD) ).AllocSysString();
|
||
else if ( _T(".n022024l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_COURIER_BOLD_OBLIQUE) ).AllocSysString();
|
||
else if ( _T(".n022023l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_COURIER_OBLIQUE) ).AllocSysString();
|
||
else if ( _T(".n019003l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_HELVETICA) ).AllocSysString();
|
||
else if ( _T(".n019004l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_HELVETICA_BOLD) ).AllocSysString();
|
||
else if ( _T(".n019024l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_HELVETICA_BOLD_OBLIQUE) ).AllocSysString();
|
||
else if ( _T(".n019023l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_HELVETICA_OBLIQUE) ).AllocSysString();
|
||
else if ( _T(".s050000l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_SYMBOL) ).AllocSysString();
|
||
else if ( _T(".n021004l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_TIMES_BOLD) ).AllocSysString();
|
||
else if ( _T(".n021024l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_TIMES_BOLD_ITALIC) ).AllocSysString();
|
||
else if ( _T(".n021023l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_TIMES_ITALIC) ).AllocSysString();
|
||
else if ( _T(".n021003l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_TIMES_ROMAN) ).AllocSysString();
|
||
else if ( _T(".d050000l") == sExt )
|
||
bsPDFFontName = CString( _T(FONT_ZAPF_DINGBATS) ).AllocSysString();
|
||
else if ( _T(".pfb") == sExt || _T(".pfa") == sExt || _T(".pfb_t1") == sExt || _T(".pfb_t1c") == sExt || _T(".pfb_t1cot") == sExt )
|
||
{
|
||
// Значит шрифт не один из 14 стандартных
|
||
|
||
CStringW wsPFBpath(bsPath);
|
||
// Ищем файл *.afm, с тем же именем, что и *.pfb
|
||
wchar_t wsDrive[MAX_PATH], wsDir[MAX_PATH], wsFilename[MAX_PATH];
|
||
_wsplitpath( wsPFBpath.GetBuffer(), wsDrive, wsDir, wsFilename, NULL );
|
||
CStringW wsAFMpath = CStringW( wsDrive ) + CStringW( wsDir ) + CStringW( wsFilename ) + CStringW( _T(".afm") );
|
||
BSTR bsAFMpath = wsAFMpath.AllocSysString();
|
||
|
||
unsigned long nRes = LoadT1FFromFile( bsAFMpath, bsPath, &bsPDFFontName );
|
||
|
||
::SysFreeString( bsAFMpath );
|
||
::SysFreeString( bsPath );
|
||
if ( OK != nRes )
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( _T(FONT_HELVETICA), _T("CP1251"), FALSE, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
}
|
||
else if ( _T(".ttf") == sExt || _T(".otf") == sExt )
|
||
{
|
||
unsigned long nRes = LoadTTFFromFile( bsPath, TRUE, NULL, &bsPDFFontName );
|
||
::SysFreeString( bsPath );
|
||
|
||
if ( OK != nRes )
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( _T(FONT_HELVETICA), _T("CP1251"), FALSE, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
}
|
||
else if ( _T(".cid_0") == sExt || _T(".cid_0c") == sExt || _T(".cid_0cot") == sExt || _T(".cid_2") == sExt || _T(".cid_2ot") == sExt )
|
||
{
|
||
bCIDfont = TRUE;
|
||
}
|
||
else
|
||
{
|
||
::SysFreeString( bsPath );
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( _T(FONT_HELVETICA), _T("CP1251"), FALSE, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
|
||
// Шрифт загружен, нужно установить кодировку, которая должна лежать рядом с файлом, с таким же названием и расширением ".enc"
|
||
|
||
wchar_t wsDrive[MAX_PATH], wsDir[MAX_PATH], wsFilename[MAX_PATH];
|
||
_wsplitpath( m_oFont.Path.GetBuffer(), wsDrive, wsDir, wsFilename, NULL );
|
||
CString wsEncodingPath = CString(wsDrive) + CString(wsDir) + CString(wsFileName) + CString(_T(".enc"));
|
||
|
||
if ( !FileExist( wsEncodingPath ) )
|
||
return SetCurrentFont( bsPDFFontName, NULL, FALSE, NULL );
|
||
|
||
XmlUtils::CXmlNode oMainNode;
|
||
oMainNode.FromXmlFile( wsEncodingPath );
|
||
if ( _T("PDF-resources") == oMainNode.GetName() )
|
||
{
|
||
if ( !bCIDfont )
|
||
{
|
||
CString wsEncodingName, wsToUnicodeName;
|
||
|
||
XmlUtils::CXmlNode oNode;
|
||
|
||
if ( oMainNode.GetNode( _T("FontBase"), oNode ) )
|
||
{
|
||
CString sValue = oNode.GetAttribute( _T("value"), _T("Helvetica") );
|
||
if ( !bEmb )
|
||
{
|
||
bsPDFFontName = ::SysAllocString( sValue.GetBuffer() );
|
||
}
|
||
else if ( _T("") == CString( bsPDFFontName ) )
|
||
{
|
||
::SysFreeString( bsPDFFontName );
|
||
bsPDFFontName = ::SysAllocString( sValue.GetBuffer() );
|
||
}
|
||
}
|
||
|
||
if ( oMainNode.GetNode( _T("Encoding"), oNode ) )
|
||
{
|
||
CString sValue;
|
||
sValue = oNode.GetAttribute( _T("type"), _T("-1") );
|
||
int nEncodingType = XmlUtils::GetInteger( sValue );
|
||
sValue = oNode.GetAttribute( _T("base"), _T("-1") );
|
||
int nBaseEncoding = XmlUtils::GetInteger( sValue );
|
||
|
||
if ( -1 != nEncodingType )
|
||
{
|
||
char *sBaseName;
|
||
switch ( nBaseEncoding )
|
||
{
|
||
case 0: sBaseName = ENCODING_MAC_ROMAN; break;
|
||
case 1: sBaseName = ENCODING_MAC_EXPERT; break;
|
||
case 2: sBaseName = ENCODING_WIN_ANSI; break;
|
||
default: sBaseName = ENCODING_FONT_SPECIFIC; break;
|
||
}
|
||
|
||
Encoder pEncoding = BasicEncoderNew( m_pDocument->oMMgr, sBaseName );
|
||
strcpy( pEncoding->sName, W2A( wsFileName ) );
|
||
|
||
if ( 1 == nEncodingType )
|
||
{
|
||
BasicEncoderAttr pAttr = (BasicEncoderAttr)pEncoding->pAttr;
|
||
pAttr->bHasDifferences = TRUE;
|
||
|
||
XmlUtils::CXmlNode oDiff;
|
||
if( oNode.GetNode( _T("Differences"), oDiff ) )
|
||
{
|
||
int nCount = XmlUtils::GetInteger( oDiff.GetAttribute( _T("count"), _T("0") ) );
|
||
XmlUtils::CXmlNodes oDiffNodes;
|
||
oDiff.GetNodes( _T("*"), oDiffNodes );
|
||
|
||
int nCode = 0;
|
||
for ( int nIndex = 0; nIndex < nCount; nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oCurNode;
|
||
oDiffNodes.GetAt( nIndex, oCurNode );
|
||
if ( _T("Code") == oCurNode.GetName() )
|
||
{
|
||
nCode = XmlUtils::GetInteger( oCurNode.GetAttribute( _T("value"), _T("0") ) );
|
||
}
|
||
else if ( _T("Name") == oCurNode.GetName() )
|
||
{
|
||
if ( nCode < BASIC_ENCODER_MAX_CHAR_INDEX )
|
||
{
|
||
pAttr->anDifferences[nCode] = 1;
|
||
char * sName = W2A( oCurNode.GetAttribute( _T("value"), _T(".notdef") ) );
|
||
pAttr->anUnicodeMap[nCode] = GlyphNameToUnicode( sName );
|
||
strcpy( (char *)pAttr->asGlyphNameMap[nCode], sName );
|
||
nCode++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
unsigned long nRes = DocRegisterEncoder( m_pDocument, pEncoding );
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_DUPLICATE_REGISTRATION == nRes )
|
||
ResetError( m_pDocument );
|
||
else if ( OK != nRes )
|
||
return nRes;
|
||
|
||
wsEncodingName = CString( wsFileName ).AllocSysString();
|
||
}
|
||
}
|
||
|
||
if ( oMainNode.GetNode( _T("ToUnicode"), oNode ) )
|
||
{
|
||
USES_CONVERSION;
|
||
CStringA sValue = W2A( oNode.GetText() );
|
||
|
||
CBase64 oBase64;
|
||
oBase64.Decode( (BYTE *)sValue.GetBuffer(), (unsigned int)sValue.GetLength() );
|
||
PToUnicode pToUnicode = GetToUnicode( m_pDocument, (BYTE *)oBase64.GetBuffer(), oBase64.GetSize() );
|
||
|
||
wsToUnicodeName = CStringW( pToUnicode->sName );
|
||
}
|
||
|
||
if ( NULL != bsPDFFontName )
|
||
m_oFontLoader.Add( m_oFont.Path, CStringW( bsPDFFontName ), wsEncodingName, wsToUnicodeName );
|
||
else
|
||
m_oFontLoader.Add( m_oFont.Path, _T(""), wsEncodingName, wsToUnicodeName );
|
||
|
||
BSTR bsToUnicodeName = NULL, bsEncodingName = NULL;
|
||
if ( wsToUnicodeName.GetLength() > 0 ) bsToUnicodeName = wsToUnicodeName.AllocSysString();
|
||
if ( wsEncodingName.GetLength() > 0 ) bsEncodingName = wsEncodingName.AllocSysString();
|
||
|
||
nRet = SetCurrentFont( bsPDFFontName, bsEncodingName, FALSE, bsToUnicodeName );
|
||
|
||
if ( bsToUnicodeName ) ::SysFreeString( bsToUnicodeName );
|
||
if ( bsEncodingName ) ::SysFreeString( bsEncodingName );
|
||
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
if ( oMainNode.GetNode( _T("FontDescriptor"), oNode ) )
|
||
{
|
||
FontAttr pFontAttr = (FontAttr)m_pCurrentFont->pAttr;
|
||
|
||
XmlUtils::CXmlNode oCurNode;
|
||
if ( oNode.GetNode( _T("Ascent"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nAscent = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("Descent"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nDescent = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("Flags"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nFlags = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("FontBBox"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value0") );
|
||
short nValue0 = XmlUtils::GetInteger( sValue );
|
||
sValue = oCurNode.GetAttribute( _T("value1") );
|
||
short nValue1 = XmlUtils::GetInteger( sValue );
|
||
sValue = oCurNode.GetAttribute( _T("value2") );
|
||
short nValue2 = XmlUtils::GetInteger( sValue );
|
||
sValue = oCurNode.GetAttribute( _T("value3") );
|
||
short nValue3 = XmlUtils::GetInteger( sValue );
|
||
pFontAttr->pFontDef->oFontBox = ToBox( nValue0, nValue1, nValue2, nValue3 );
|
||
}
|
||
if ( oNode.GetNode( _T("ItalicAngle"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nItalicAngle = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("StemV"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nStemV = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("AvgWidth"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nAvgWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("MaxWidth"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nMaxWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("MissingWidth"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nMissingWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("StemH"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nStemH = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("XHeight"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nXHeight = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("CapHeight"), oCurNode ) )
|
||
{
|
||
CString sValue = oCurNode.GetAttribute( _T("value") );
|
||
pFontAttr->pFontDef->nCapHeight = XmlUtils::GetInteger( sValue );
|
||
}
|
||
}
|
||
if ( oMainNode.GetNode( _T("Widths"), oNode ) )
|
||
{
|
||
FontAttr pFontAttr = (FontAttr)m_pCurrentFont->pAttr;
|
||
|
||
pFontAttr->oExternWidths.bUse = true;
|
||
|
||
CString sValue;
|
||
sValue = oNode.GetAttribute( _T("FirstChar"), _T("0") );
|
||
pFontAttr->oExternWidths.nFirstChar = XmlUtils::GetInteger( sValue );
|
||
|
||
sValue = oNode.GetAttribute( _T("LastChar"), _T("0") );
|
||
pFontAttr->oExternWidths.nLastChar = XmlUtils::GetInteger( sValue );
|
||
|
||
XmlUtils::CXmlNodes oWidthNodes;
|
||
oNode.GetNodes( _T("Width"), oWidthNodes );
|
||
pFontAttr->oExternWidths.anWidths = (short *)GetMem( m_pDocument->oMMgr, sizeof(short) * oWidthNodes.GetCount() );
|
||
for ( int nIndex = 0; nIndex < oWidthNodes.GetCount(); nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oWidthNode;
|
||
oWidthNodes.GetAt( nIndex, oWidthNode );
|
||
sValue = oWidthNode.GetAttribute( _T("value") );
|
||
pFontAttr->oExternWidths.anWidths[nIndex] = XmlUtils::GetInteger( sValue );
|
||
}
|
||
}
|
||
|
||
return nRet;
|
||
}
|
||
else //if ( bCIDfont )
|
||
{
|
||
CString wsEncodingName, wsToUnicodeName;
|
||
XmlUtils::CXmlNode oType0Node;
|
||
|
||
if ( oMainNode.GetNode( _T("Type0"), oType0Node ) )
|
||
{
|
||
CString sValue = oType0Node.GetAttribute( _T("value") );
|
||
bsPDFFontName = ::SysAllocString( sValue.GetBuffer() );
|
||
|
||
XmlUtils::CXmlNode oNode;
|
||
|
||
if ( oType0Node.GetNode( _T("ToUnicode"), oNode ) )
|
||
{
|
||
USES_CONVERSION;
|
||
CStringA sValue = W2A( oNode.GetText() );
|
||
|
||
CBase64 oBase64;
|
||
oBase64.Decode( (BYTE *)sValue.GetBuffer(), (unsigned int)sValue.GetLength() );
|
||
PToUnicode pToUnicode = GetToUnicode( m_pDocument, (BYTE *)oBase64.GetBuffer(), oBase64.GetSize() );
|
||
|
||
wsToUnicodeName = CStringW( pToUnicode->sName );
|
||
}
|
||
|
||
if ( oType0Node.GetNode( _T("Encoding"), oNode ) )
|
||
{
|
||
int nType = 0;
|
||
wsEncodingName = oNode.GetAttribute( _T("name") );
|
||
Stream pStream = NULL, pUseCMapStream = NULL;
|
||
|
||
CStringW wsCMapName, wsRegistry, wsOrdering, wsUseCMap;
|
||
int nSupplement = 0, nWMode = 0;
|
||
|
||
if ( _T("") == wsEncodingName )
|
||
{
|
||
nType = 1;
|
||
|
||
XmlUtils::CXmlNode oEncNode;
|
||
|
||
if ( oNode.GetNode( _T("CMapName"), oEncNode ) )
|
||
{
|
||
wsCMapName = oEncNode.GetAttribute( _T("name") );
|
||
wsEncodingName = wsCMapName;
|
||
}
|
||
if ( oNode.GetNode( _T("CIDSystemInfo"), oEncNode ) )
|
||
{
|
||
XmlUtils::CXmlNode oInfo;
|
||
if ( oEncNode.GetNode( _T("Registry"), oInfo ) )
|
||
{
|
||
wsRegistry = oInfo.GetAttribute( _T("string") );
|
||
}
|
||
if ( oEncNode.GetNode( _T("Ordering"), oInfo ) )
|
||
{
|
||
wsOrdering = oInfo.GetAttribute( _T("string") );
|
||
}
|
||
if ( oEncNode.GetNode( _T("Supplement"), oInfo ) )
|
||
{
|
||
sValue = oInfo.GetAttribute( _T("integer") );
|
||
nSupplement = XmlUtils::GetInteger( sValue );
|
||
}
|
||
}
|
||
if ( oNode.GetNode( _T("WMode"), oEncNode ) )
|
||
{
|
||
sValue = oEncNode.GetAttribute( _T("integer") );
|
||
nWMode = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oNode.GetNode( _T("UseCMap"), oEncNode ) )
|
||
{
|
||
wsUseCMap = oEncNode.GetAttribute( _T("name") );
|
||
USES_CONVERSION;
|
||
CStringA sText = W2A( oEncNode.GetText() );
|
||
if ( sText.GetLength() > 0 )
|
||
{
|
||
CBase64 oBase64;
|
||
oBase64.Decode( (BYTE *)sText.GetBuffer(), (unsigned int)sText.GetLength() );
|
||
pUseCMapStream = TempFileStreamNew( m_pDocument->oMMgr );
|
||
if ( pUseCMapStream )
|
||
{
|
||
StreamSeek( pUseCMapStream, 0, SeekSet );
|
||
StreamWrite( pUseCMapStream, (BYTE *)oBase64.GetBuffer(), oBase64.GetSize(), true );
|
||
}
|
||
}
|
||
}
|
||
if ( oNode.GetNode( _T("Stream"), oEncNode ) )
|
||
{
|
||
USES_CONVERSION;
|
||
CStringA sText = W2A( oEncNode.GetText() );
|
||
if ( sText.GetLength() > 0 )
|
||
{
|
||
CBase64 oBase64;
|
||
oBase64.Decode( (BYTE *)sText.GetBuffer(), (unsigned int)sText.GetLength() );
|
||
pStream = TempFileStreamNew( m_pDocument->oMMgr );
|
||
if ( pStream )
|
||
{
|
||
StreamSeek( pStream, 0, SeekSet );
|
||
StreamWrite( pStream, (BYTE *)oBase64.GetBuffer(), oBase64.GetSize(), true );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Encoder pEncoder = CMapEncoderStreamNew( m_pDocument->oMMgr, nType, W2A(wsEncodingName), pStream );
|
||
if ( !pEncoder )
|
||
return AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM;
|
||
|
||
//// Ищем Cmap файл и парсим его
|
||
|
||
//CString wsCMapPath = CString(wsDrive) + CString(wsDir) + CString(wsFileName) + CString(_T(".cmap"));
|
||
|
||
//if ( FileExist( wsCMapPath ) )
|
||
// CMapEncoderStreamLoadVector( pEncoder, wsCMapPath );
|
||
|
||
CMapEncoderStreamSetAttrs( pEncoder, W2A( wsCMapName ), W2A( wsRegistry ), W2A( wsOrdering), nSupplement, (WritingMode)nWMode, W2A( wsUseCMap ), pUseCMapStream );
|
||
nRet = DocRegisterEncoder( m_pDocument, pEncoder );
|
||
if ( nRet == AVS_OFFICEPDFWRITER_ERROR_DUPLICATE_REGISTRATION )
|
||
ResetError( m_pDocument);
|
||
}
|
||
|
||
if ( oType0Node.GetNode( _T("DescendantFonts"), oNode ) )
|
||
{
|
||
XmlUtils::CXmlNode oDescNode;
|
||
int nCIDtype = 0; // 0 - Type 0, 2 - Type 2
|
||
CStringW wsBaseFont;
|
||
|
||
if ( oNode.GetNode( _T("Subtype"), oDescNode ) )
|
||
{
|
||
sValue = oDescNode.GetAttribute( _T("name") );
|
||
if ( _T("CIDFontType0") == sValue ) nCIDtype = 0;
|
||
else if ( _T("CIDFontType2") == sValue ) nCIDtype = 2;
|
||
}
|
||
if ( oNode.GetNode( _T("BaseFont"), oDescNode ) )
|
||
{
|
||
wsBaseFont = oDescNode.GetAttribute( _T("name") );
|
||
}
|
||
|
||
// Создаем FontDef с данным именем
|
||
FontDef pFontDef = CIDFontDefNew( m_pDocument->oMMgr, W2A( bsPDFFontName/*wsBaseFont*/ ), NULL );
|
||
|
||
// Добовляем в него CIDSystemInfo
|
||
if ( oNode.GetNode( _T("CIDSystemInfo"), oDescNode ) )
|
||
{
|
||
XmlUtils::CXmlNode oInfo;
|
||
CStringW wsRegistry, wsOrdering;
|
||
int nSupplement = 0;
|
||
|
||
if ( oDescNode.GetNode( _T("Registry"), oInfo ) )
|
||
{
|
||
wsRegistry = oInfo.GetAttribute( _T("string") );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Ordering"), oInfo ) )
|
||
{
|
||
wsOrdering = oInfo.GetAttribute( _T("string") );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Supplement"), oInfo ) )
|
||
{
|
||
sValue = oInfo.GetAttribute( _T("integer") );
|
||
nSupplement = XmlUtils::GetInteger( sValue );
|
||
}
|
||
|
||
CIDFontDefSetInfoSys( pFontDef, W2A( wsRegistry.GetBuffer() ), W2A( wsOrdering.GetBuffer() ), nSupplement );
|
||
}
|
||
|
||
// Записываем всевозможные настройки FontDescriptor
|
||
if ( oNode.GetNode( _T("FontDescriptor"), oDescNode ) )
|
||
{
|
||
XmlUtils::CXmlNode oFDNode;
|
||
|
||
if ( oDescNode.GetNode( _T("FontName"), oFDNode ) )
|
||
{
|
||
CString wsFontName = oFDNode.GetAttribute( _T("name") );
|
||
}
|
||
if ( oDescNode.GetNode( _T("FontStretch"), oFDNode ) )
|
||
{
|
||
CString wsStretch = oFDNode.GetAttribute( _T("name") );
|
||
}
|
||
if ( oDescNode.GetNode( _T("FontWeight"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
int nWeight = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Flags"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("integer") );
|
||
pFontDef->nFlags = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("FontBBox"), oFDNode ) )
|
||
{
|
||
short shValue[4];
|
||
sValue = oFDNode.GetAttribute( _T("value0") );
|
||
shValue[0] = XmlUtils::GetInteger( sValue );
|
||
sValue = oFDNode.GetAttribute( _T("value1") );
|
||
shValue[1] = XmlUtils::GetInteger( sValue );
|
||
sValue = oFDNode.GetAttribute( _T("value2") );
|
||
shValue[2] = XmlUtils::GetInteger( sValue );
|
||
sValue = oFDNode.GetAttribute( _T("value3") );
|
||
shValue[3] = XmlUtils::GetInteger( sValue );
|
||
|
||
pFontDef->oFontBox = ToBox( shValue[0], shValue[1], shValue[2], shValue[3] );
|
||
}
|
||
if ( oDescNode.GetNode( _T("ItalicAngle"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nItalicAngle = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Ascent"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nAscent = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Descent"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nDescent = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("Leading"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
int nLeading = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("CapHeight"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nCapHeight = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("XHeight"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nXHeight = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("StemV"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nStemV = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("StemH"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nStemH = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("AvgWidth"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nAvgWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("MaxWidth"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nMaxWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oDescNode.GetNode( _T("MissingWidth"), oFDNode ) )
|
||
{
|
||
sValue = oFDNode.GetAttribute( _T("number") );
|
||
pFontDef->nMissingWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
}
|
||
|
||
// Записываем файл с шрифтом и устанавливаем его тип
|
||
|
||
CIDFontFileType eType;
|
||
|
||
if ( _T(".cid_0" ) == sExt ) eType = cidType0;
|
||
else if ( _T(".cid_0c" ) == sExt ) eType = cidType0C;
|
||
else if ( _T(".cid_0cot") == sExt ) eType = cidType0COT;
|
||
else if ( _T(".cid_2" ) == sExt ) eType = cidType2;
|
||
else if ( _T(".cid_2ot" ) == sExt ) eType = cidType2OT;
|
||
else
|
||
{
|
||
if ( 0 == nCIDtype )
|
||
eType = cidType0;
|
||
else
|
||
eType = cidType2;
|
||
}
|
||
|
||
if ( bEmb )
|
||
{
|
||
if ( OK != ( nRet = CIDFontDefLoadFontData( pFontDef, m_oFont.Path.GetBuffer(), eType ) ) )
|
||
return nRet;
|
||
}
|
||
else
|
||
{
|
||
if ( OK != ( nRet = CIDFontDefLoadFontData( pFontDef, NULL, eType ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
// Пишим ширины
|
||
if ( oNode.GetNode( _T("DW"), oDescNode ) )
|
||
{
|
||
sValue = oDescNode.GetAttribute( _T("integer") );
|
||
int nDW = XmlUtils::GetInteger( sValue );
|
||
CIDFontDefSetDW( pFontDef, nDW );
|
||
}
|
||
if ( oNode.GetNode( _T("W"), oDescNode ) )
|
||
{
|
||
int nPrevType = -1; // -1 - ничего, 0 - cid, 1 - cid_last, 2 - array, 3 - width
|
||
int nCid_first = 0, nCid_last = 0, nWidth = 0;
|
||
CIDWidth oWidth;
|
||
|
||
XmlUtils::CXmlNodes oNodesW;
|
||
// Забираем все ноды
|
||
oDescNode.GetNodes( _T("*"), oNodesW );
|
||
for ( int nIndex = 0; nIndex < oNodesW.GetCount(); nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oNodeW;
|
||
if ( oNodesW.GetAt( nIndex, oNodeW ) )
|
||
{
|
||
if ( _T("Int") == oNodeW.GetName() )
|
||
{
|
||
sValue = oNodeW.GetAttribute( _T("value") );
|
||
if ( -1 == nPrevType || 2 == nPrevType || 3 == nPrevType )
|
||
{
|
||
nPrevType = 0;
|
||
nCid_first = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else if ( 0 == nPrevType )
|
||
{
|
||
nPrevType = 1;
|
||
nCid_last = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else // if ( 1 == nPrevType )
|
||
{
|
||
nPrevType = 3;
|
||
nWidth = XmlUtils::GetInteger( sValue );
|
||
|
||
oWidth.unCid_First = nCid_first;
|
||
oWidth.unCid_Last = nCid_last;
|
||
oWidth.shWidth = nWidth;
|
||
|
||
CIDFontDefAddWidth( pFontDef, oWidth );
|
||
}
|
||
}
|
||
else if ( _T("Array") == oNodeW.GetName() )
|
||
{
|
||
nPrevType = 2;
|
||
|
||
XmlUtils::CXmlNodes oArrayNodes;
|
||
oNodeW.GetNodes( _T("Int"), oArrayNodes );
|
||
for ( int nArrayIndex = 0; nArrayIndex < oArrayNodes.GetCount(); nArrayIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oArrayItem;
|
||
if ( oArrayNodes.GetAt( nArrayIndex, oArrayItem ) )
|
||
{
|
||
sValue = oArrayItem.GetAttribute( _T("value") );
|
||
nWidth = XmlUtils::GetInteger( sValue );
|
||
|
||
oWidth.unCid_First = nCid_first;
|
||
oWidth.unCid_Last = nCid_first;
|
||
oWidth.shWidth = nWidth;
|
||
|
||
nCid_first++;
|
||
|
||
CIDFontDefAddWidth( pFontDef, oWidth );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if ( oNode.GetNode( _T("DW2"), oDescNode ) )
|
||
{
|
||
int anDW2[2];
|
||
sValue = oDescNode.GetAttribute( _T("value0") );
|
||
anDW2[0] = XmlUtils::GetInteger( sValue );
|
||
sValue = oDescNode.GetAttribute( _T("value1") );
|
||
anDW2[1] = XmlUtils::GetInteger( sValue );
|
||
CIDFontDefSetDW2( pFontDef, anDW2 );
|
||
}
|
||
if ( oNode.GetNode( _T("W2"), oDescNode ) )
|
||
{
|
||
int nPrevType = -1; // -1 - ничего, 0 - cid, 1 - cid_last, 2 - array, 3 - W, 4 - Vx, 5 - Vy
|
||
int nCid_first = 0, nCid_last = 0, nWidth = 0, nVx = 0, nVy = 0;
|
||
CIDWidth2 oWidth2;
|
||
|
||
XmlUtils::CXmlNodes oNodesW;
|
||
// Забираем все ноды
|
||
oDescNode.GetNodes( _T("*"), oNodesW );
|
||
for ( int nIndex = 0; nIndex < oNodesW.GetCount(); nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oNodeW;
|
||
if ( oNodesW.GetAt( nIndex, oNodeW ) )
|
||
{
|
||
if ( _T("Int") == oNodeW.GetName() )
|
||
{
|
||
sValue = oNodeW.GetAttribute( _T("value") );
|
||
if ( -1 == nPrevType || 2 == nPrevType || 5 == nPrevType )
|
||
{
|
||
nPrevType = 0;
|
||
nCid_first = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else if ( 0 == nPrevType )
|
||
{
|
||
nPrevType = 1;
|
||
nCid_last = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else if ( 1 == nPrevType )
|
||
{
|
||
nPrevType = 3;
|
||
nWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else if ( 3 == nPrevType )
|
||
{
|
||
nPrevType = 4;
|
||
nVx = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else // if ( 4 == nPrevType )
|
||
{
|
||
nPrevType = 5;
|
||
nVy = XmlUtils::GetInteger( sValue );
|
||
|
||
oWidth2.unCid_First = nCid_first;
|
||
oWidth2.unCid_Last = nCid_last;
|
||
oWidth2.shW = nWidth;
|
||
oWidth2.shVx = nVx;
|
||
oWidth2.shVy = nVy;
|
||
|
||
CIDFontDefAddWidth2( pFontDef, oWidth2 );
|
||
}
|
||
}
|
||
else if ( _T("Array") == oNodeW.GetName() )
|
||
{
|
||
nPrevType = 2;
|
||
|
||
int nWidthPrevType = -1; // -1 - ничего, 0 - W, 1 - Vx, 2 - Vy
|
||
|
||
XmlUtils::CXmlNodes oArrayNodes;
|
||
oNodeW.GetNodes( _T("Int"), oArrayNodes );
|
||
for ( int nArrayIndex = 0; nArrayIndex < oArrayNodes.GetCount(); nArrayIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oArrayItem;
|
||
if ( oArrayNodes.GetAt( nArrayIndex, oArrayItem ) )
|
||
{
|
||
sValue = oArrayItem.GetAttribute( _T("value") );
|
||
|
||
if ( -1 == nWidthPrevType || 2 == nWidthPrevType )
|
||
{
|
||
nWidthPrevType = 0;
|
||
nWidth = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else if ( 0 == nWidthPrevType )
|
||
{
|
||
nWidthPrevType = 1;
|
||
nVx = XmlUtils::GetInteger( sValue );
|
||
}
|
||
else // if ( 1 == nWidthPrevType )
|
||
{
|
||
nWidthPrevType = 2;
|
||
nVy = XmlUtils::GetInteger( sValue );
|
||
|
||
oWidth2.unCid_First = nCid_first;
|
||
oWidth2.unCid_Last = nCid_first;
|
||
oWidth2.shW = nWidth;
|
||
oWidth2.shVx = nVx;
|
||
oWidth2.shVy = nVy;
|
||
|
||
nCid_first++;
|
||
|
||
CIDFontDefAddWidth2( pFontDef, oWidth2 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if ( oNode.GetNode( _T("CIDToGIDMap"), oDescNode ) )
|
||
{
|
||
sValue = oDescNode.GetAttribute( _T("name"), _T("") );
|
||
if ( _T("") != sValue )
|
||
{
|
||
CIDFontDefSetCIDtoGID( pFontDef, W2A( sValue.GetBuffer() ) );
|
||
}
|
||
else
|
||
{
|
||
USES_CONVERSION;
|
||
CStringA sText = W2A( oDescNode.GetText() );
|
||
if ( sText.GetLength() > 0 )
|
||
{
|
||
CBase64 oBase64;
|
||
oBase64.Decode( (BYTE *)sText.GetBuffer(), (unsigned int)sText.GetLength() );
|
||
CIDFontDefSetCIDtoGID( pFontDef, (BYTE *)oBase64.GetBuffer(), oBase64.GetSize() );
|
||
}
|
||
}
|
||
}
|
||
|
||
Encoder pEncoder = GetEncoder( m_pDocument, W2A( wsEncodingName ) );
|
||
PToUnicode pToUnicode = GetToUnicode( m_pDocument, W2A( wsToUnicodeName ) );
|
||
FontDict pFont = Type0FontNew2( m_pDocument->oMMgr, pFontDef, pEncoder, m_pDocument->pXref, pToUnicode);
|
||
|
||
// Регистрируем FontDef и Font в документе
|
||
if ( pFontDef )
|
||
ListAdd( m_pDocument->pFontDefList, pFontDef );
|
||
|
||
if ( pFont )
|
||
ListAdd( m_pDocument->pFontManager, pFont );
|
||
|
||
if ( NULL != bsPDFFontName )
|
||
m_oFontLoader.Add( m_oFont.Path, CStringW( bsPDFFontName ), wsEncodingName, wsToUnicodeName );
|
||
else
|
||
m_oFontLoader.Add( m_oFont.Path, _T(""), wsEncodingName, wsToUnicodeName );
|
||
|
||
BSTR bsToUnicodeName = NULL, bsEncodingName = NULL;
|
||
if ( wsToUnicodeName.GetLength() > 0 ) bsToUnicodeName = wsToUnicodeName.AllocSysString();
|
||
if ( wsEncodingName.GetLength() > 0 ) bsEncodingName = wsEncodingName.AllocSysString();
|
||
|
||
nRet = SetCurrentFont( bsPDFFontName, bsEncodingName, FALSE, bsToUnicodeName );
|
||
|
||
if ( bsToUnicodeName ) ::SysFreeString( bsToUnicodeName );
|
||
if ( bsEncodingName ) ::SysFreeString( bsEncodingName );
|
||
|
||
return nRet;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( NULL != bsPDFFontName )
|
||
nRet = SetCurrentFont( bsPDFFontName, NULL, FALSE, NULL );
|
||
|
||
return nRet;
|
||
}
|
||
|
||
return OK;
|
||
}
|
||
unsigned long GdiFontToPdfFont(BSTR bsEncodingName = L"CP1251", BOOL bNameIsUnicodeArray = FALSE)
|
||
{
|
||
BSTR bsDefaultFont = L"Helvetica";
|
||
BSTR bsDefaultEncoding = L"CP1251";
|
||
USES_CONVERSION;
|
||
|
||
BOOL bBold = m_oFont.Bold;
|
||
BOOL bItalic = m_oFont.Italic;
|
||
|
||
wchar_t wsDisplayName[1000];
|
||
wchar_t wsFontName[1000];
|
||
|
||
// получаем фонт по его названию
|
||
BSTR bsFileName;
|
||
if ( !m_pFindFonts->Find( m_oFont.Name, &bsFileName, &bBold, &bItalic ) )
|
||
{
|
||
BOOL bOldBold = bBold;
|
||
BOOL bOldItalic = bItalic;
|
||
|
||
if ( !GetFontFile( &m_oFont, (LPCTSTR)m_oFont.Name.GetBuffer(), (LPTSTR)wsDisplayName, 1000, (LPTSTR)wsFontName, 1000, &bBold, &bItalic ) )
|
||
{
|
||
m_pFindFonts->Add( m_oFont.Name, CString(_T("")), bOldBold, bOldItalic, bBold, bItalic );
|
||
|
||
SetCurrentFont( bsDefaultFont, bsDefaultEncoding, bNameIsUnicodeArray, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
|
||
m_pFindFonts->Add( m_oFont.Name, CString(wsFontName), bOldBold, bOldItalic, bBold, bItalic );
|
||
|
||
}
|
||
else
|
||
{
|
||
CString sFName = CString( bsFileName );
|
||
if ( sFName.GetLength() <= 0 || sFName.GetLength() >= 1000 )
|
||
{
|
||
SetCurrentFont( bsDefaultFont, bsDefaultEncoding, bNameIsUnicodeArray, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
else
|
||
{
|
||
_tcscpy( wsFontName, sFName.GetBuffer() );
|
||
}
|
||
}
|
||
char *sDisplayName = W2A( wsDisplayName );
|
||
char *sFontFile = W2A( wsFontName );
|
||
|
||
m_oFont.Bold = bBold;
|
||
m_oFont.Italic = bItalic;
|
||
|
||
// пока фонт не включаем в документ
|
||
// TO DO: 1. Сначала пытаемся включить фонт в документ
|
||
// 2. Если этого сделать нельзя, тогда загружаем фонт не включая его в документ.
|
||
BSTR bsPDFFontName = ::SysAllocString( _T("Embedded") );
|
||
BSTR bsFontFile = A2W( sFontFile );
|
||
|
||
unsigned long nRes = LoadTTFFromFile( bsFontFile, TRUE, bsEncodingName, &bsPDFFontName );
|
||
if ( OK == nRes )
|
||
{
|
||
nRes = SetCurrentFont( bsPDFFontName, bsEncodingName, bNameIsUnicodeArray, NULL );
|
||
::SysFreeString( bsPDFFontName );
|
||
return nRes;
|
||
}
|
||
else if ( AVS_OFFICEPDFWRITER_ERROR_FILE_OPEN_ERROR == nRes )
|
||
ResetError( m_pDocument );
|
||
else
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( bsDefaultFont, bsDefaultEncoding, bNameIsUnicodeArray, NULL );
|
||
::SysFreeString( bsPDFFontName );
|
||
return nRes;
|
||
}
|
||
|
||
// Скорее всего фонт не загрузился из-за того, что sFontFile содержит не полный путь
|
||
char *pValue;
|
||
size_t len;
|
||
errno_t err = _dupenv_s( &pValue, &len, "windir" );
|
||
CString sFontFilePath(pValue);
|
||
free( pValue );
|
||
sFontFilePath += "\\Fonts\\";
|
||
sFontFilePath += sFontFile;
|
||
bsFontFile = sFontFilePath.AllocSysString();
|
||
|
||
nRes = LoadTTFFromFile( bsFontFile, TRUE, bsEncodingName, &bsPDFFontName );
|
||
if ( OK == nRes )
|
||
{
|
||
nRes = SetCurrentFont( bsPDFFontName, bsEncodingName, bNameIsUnicodeArray, NULL );
|
||
::SysFreeString( bsPDFFontName );
|
||
::SysFreeString( bsFontFile );
|
||
return nRes;
|
||
}
|
||
else
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( bsDefaultFont, bsDefaultEncoding, bNameIsUnicodeArray, NULL );
|
||
::SysFreeString( bsFontFile );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
}
|
||
unsigned long GdiFontToPdfFont2(BSTR bsToUnicodeName = NULL, BSTR bsEncodingName = NULL)
|
||
{
|
||
BSTR bsDefaultFont = L"Helvetica";
|
||
USES_CONVERSION;
|
||
|
||
BOOL bBold = m_oFont.Bold;
|
||
BOOL bItalic = m_oFont.Italic;
|
||
|
||
wchar_t wsDisplayName[1000];
|
||
wchar_t wsFontName[1000];
|
||
|
||
// получаем фонт по его названию
|
||
BSTR bsFileName;
|
||
|
||
BOOL bPath = ( m_oFont.Path != _T("") ? TRUE : FALSE );
|
||
if ( bPath )
|
||
m_oFont.Name = m_oFont.Path;
|
||
|
||
if ( !m_pFindFonts->Find( m_oFont.Name, &bsFileName, &bBold, &bItalic ) )
|
||
{
|
||
BOOL bOldBold = bBold;
|
||
BOOL bOldItalic = bItalic;
|
||
|
||
if ( !bPath )
|
||
{
|
||
if ( !GetFontFile2( &m_oFont, (LPCTSTR)m_oFont.Name.GetBuffer(), (LPTSTR)wsDisplayName, 1000, (LPTSTR)wsFontName, 1000, &bBold, &bItalic, m_pFontManager ) )
|
||
{
|
||
m_pFindFonts->Add( m_oFont.Name, CString(_T("")), bOldBold, bOldItalic, bBold, bItalic );
|
||
|
||
SetCurrentFont( bsDefaultFont, NULL, FALSE, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int nTempLen = min( 499, m_oFont.Path.GetLength() );
|
||
::memcpy( wsFontName, m_oFont.Path.GetBuffer(), sizeof(wchar_t) * nTempLen );
|
||
wsFontName[nTempLen + 0] = 0;
|
||
wsFontName[nTempLen + 1] = 0;
|
||
|
||
::memcpy( wsDisplayName, m_oFont.Path.GetBuffer(), sizeof(wchar_t) * nTempLen );
|
||
wsDisplayName[nTempLen + 0] = 0;
|
||
wsDisplayName[nTempLen + 1] = 0;
|
||
}
|
||
|
||
m_pFindFonts->Add( m_oFont.Name, CString(wsFontName), bOldBold, bOldItalic, bBold, bItalic );
|
||
|
||
}
|
||
else
|
||
{
|
||
CString sFName = CString( bsFileName );
|
||
if ( sFName.GetLength() <= 0 || sFName.GetLength() >= 1000 )
|
||
{
|
||
SetCurrentFont( bsDefaultFont, NULL, FALSE, NULL );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
else
|
||
{
|
||
_tcscpy( wsFontName, sFName.GetBuffer() );
|
||
}
|
||
}
|
||
char *sDisplayName = W2A( wsDisplayName );
|
||
char *sFontFile = W2A( wsFontName );
|
||
|
||
m_oFont.Bold = bBold;
|
||
m_oFont.Italic = bItalic;
|
||
|
||
// пока фонт не включаем в документ
|
||
// TO DO: 1. Сначала пытаемся включить фонт в документ
|
||
// 2. Если этого сделать нельзя, тогда загружаем фонт не включая его в документ.
|
||
BSTR bsPDFFontName = ::SysAllocString( _T("Embedded") );
|
||
BSTR bsFontFile = A2W( sFontFile );
|
||
|
||
unsigned long nRes = LoadTTFFromFile( bsFontFile, TRUE, bsToUnicodeName, &bsPDFFontName );
|
||
if ( OK == nRes )
|
||
{
|
||
nRes = SetCurrentFont( bsPDFFontName, bsEncodingName, FALSE, bsToUnicodeName );
|
||
::SysFreeString( bsPDFFontName );
|
||
return nRes;
|
||
}
|
||
else if ( AVS_OFFICEPDFWRITER_ERROR_FILE_OPEN_ERROR == nRes )
|
||
ResetError( m_pDocument );
|
||
else
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( bsDefaultFont, NULL, FALSE, NULL );
|
||
::SysFreeString( bsPDFFontName );
|
||
return nRes;
|
||
}
|
||
|
||
// Скорее всего фонт не загрузился из-за того, что sFontFile содержит не полный путь
|
||
char *pValue;
|
||
size_t len;
|
||
errno_t err = _dupenv_s( &pValue, &len, "windir" );
|
||
CString sFontFilePath(pValue);
|
||
free( pValue );
|
||
sFontFilePath += "\\Fonts\\";
|
||
sFontFilePath += sFontFile;
|
||
bsFontFile = sFontFilePath.AllocSysString();
|
||
|
||
nRes = LoadTTFFromFile( bsFontFile, TRUE, bsEncodingName, &bsPDFFontName );
|
||
if ( OK == nRes )
|
||
{
|
||
nRes = SetCurrentFont( bsPDFFontName, bsEncodingName, FALSE, bsToUnicodeName );
|
||
::SysFreeString( bsPDFFontName );
|
||
::SysFreeString( bsFontFile );
|
||
return nRes;
|
||
}
|
||
else
|
||
{
|
||
ResetError( m_pDocument );
|
||
SetCurrentFont( bsDefaultFont, NULL, FALSE, NULL );
|
||
::SysFreeString( bsFontFile );
|
||
return AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND;
|
||
}
|
||
}
|
||
unsigned long GdiDashToPDFDash( int nDashStyle = 0, double *pDashPattern = NULL, int nDashPatternSize = 0, float fDashOffset = 0 )
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
float fWidth = PageGetLineWidth( m_pDocument->pCurPage );
|
||
|
||
// Константы для стилей от 1 до 4 вычислены на основе MicrosoftOfficePowerPoint
|
||
if ( 0 == nDashStyle ) // Solid
|
||
{
|
||
nRet = PageSetDash( m_pDocument->pCurPage, NULL, 0, 0 );
|
||
}
|
||
else if ( 1 == nDashStyle )
|
||
{
|
||
double arrDashPtn[2] = { 4 * fWidth, 3 * fWidth };
|
||
nRet = PageSetDash( m_pDocument->pCurPage, arrDashPtn, 2, fDashOffset );
|
||
}
|
||
else if ( 2 == nDashStyle )
|
||
{
|
||
double arrDashPtn[2] = { fWidth, fWidth };
|
||
nRet = PageSetDash( m_pDocument->pCurPage, arrDashPtn, 2, fDashOffset );
|
||
}
|
||
else if ( 3 == nDashStyle )
|
||
{
|
||
double arrDashPtn[4] = { 4 * fWidth, 3 * fWidth, fWidth, 3 * fWidth };
|
||
nRet = PageSetDash( m_pDocument->pCurPage, arrDashPtn, 4, fDashOffset );
|
||
}
|
||
else if ( 4 == nDashStyle )
|
||
{
|
||
double arrDashPtn[6] = { 8 * fWidth, 3 * fWidth, fWidth, 3 * fWidth, fWidth, 3 * fWidth };
|
||
nRet = PageSetDash( m_pDocument->pCurPage, arrDashPtn, 6, fDashOffset );
|
||
}
|
||
else if ( 5 == nDashStyle ) // Custom
|
||
{
|
||
nRet = PageSetDash( m_pDocument->pCurPage, pDashPattern, nDashPatternSize, fDashOffset );
|
||
}
|
||
|
||
return nRet;
|
||
}
|
||
unsigned long ReadOutlineChilds(CString sXml, int nRootIndex)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
XmlUtils::CXmlNode oNode;
|
||
oNode.FromXmlString(sXml);
|
||
|
||
XmlUtils::CXmlNodes oNodes;
|
||
oNode.GetNodes( _T("Chapter"), oNodes);
|
||
|
||
for ( int nIndex = 0; nIndex < oNodes.GetCount(); nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oCurNode;
|
||
oNodes.GetAt( nIndex, oCurNode );
|
||
if ( -1 != oCurNode.GetName().Find( _T("Chapter") ) )
|
||
{
|
||
CStringA sName = (CStringA)oCurNode.GetAttribute( _T("name") );
|
||
CStringA sPage = (CStringA)oCurNode.GetAttribute( _T("page") );
|
||
int nPageNum = UtilsAToI( sPage.GetBuffer() );
|
||
|
||
if ( FAILED ( hRes = SetCurrentPage( nPageNum ) ) )
|
||
return hRes;
|
||
|
||
BSTR bsName = sName.AllocSysString();
|
||
CString sNode = oNode.GetXml();
|
||
|
||
if ( FAILED ( hRes = CreateNewOutline( nRootIndex, bsName, NULL ) ) )
|
||
return hRes;
|
||
if ( FAILED ( hRes = CreateNewDestination() ) )
|
||
return hRes;
|
||
if ( FAILED ( hRes = OutlineSetCurrentDestination() ) )
|
||
return hRes;
|
||
if ( FAILED ( hRes = SetOutlineOpened( FALSE ) ) )
|
||
return hRes;
|
||
::SysFreeString( bsName );
|
||
long nCurrentIndex = -1;
|
||
if ( FAILED ( hRes = GetCurrentOutlineIndex(&nCurrentIndex) ) )
|
||
return hRes;
|
||
if ( FAILED ( hRes = ReadOutlineChilds( oCurNode.GetXml(), nCurrentIndex ) ) )
|
||
return hRes;
|
||
}
|
||
}
|
||
return S_OK;
|
||
}
|
||
unsigned long UpdateGState()
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
if ( ! ( NULL != m_pCurCommand->pPrev && c_nClipType == m_pCurCommand->pPrev->nType ) )
|
||
{
|
||
if ( FAILED( hRes = GSave() ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = UpdateCoordSpace() ) )
|
||
return hRes;
|
||
|
||
long nColor = m_oBrush.Color1;
|
||
float fR = ( nColor & 0xFF ) / 255.0f;
|
||
float fG = ( ( nColor >> 8 ) & 0xFF ) / 255.0f;
|
||
float fB = ( (nColor >> 16) ) / 255.0f;
|
||
|
||
if ( FAILED( hRes = SetRGBFill( fR, fG, fB ) ) )
|
||
return hRes;
|
||
|
||
float fLineWidth = MMToPDFCoords( m_oPen.Size );
|
||
if ( FAILED( hRes = SetLineWidth( fLineWidth ) ) )
|
||
return hRes;
|
||
|
||
float fDashOffset = m_oPen.DashOffset;
|
||
int nDashStyle = m_oPen.DashStyle;
|
||
|
||
double *pDashPattern = m_oPen.DashPattern;
|
||
int nDashPatternSize = m_oPen.Count;
|
||
|
||
if ( FAILED( hRes = GdiDashToPDFDash( nDashStyle, pDashPattern, nDashPatternSize, fDashOffset ) ) )
|
||
return hRes;
|
||
|
||
//if ( 0 != nLineCap )
|
||
// if ( FAILED( hRes = SetLineCap( nLineCap ) ) )
|
||
// return hRes;
|
||
|
||
//int nLineJoin = m_oPen.LineJoin;
|
||
//if ( 0 != nLineJoin )
|
||
// if ( FAILED( hRes = SetLineJoin( nLineJoin ) ) )
|
||
// return hRes;
|
||
|
||
nColor = m_oPen.Color;
|
||
fR = ( nColor & 0xFF ) / 255.0f;
|
||
fG = ( ( nColor >> 8 ) & 0xFF ) / 255.0f;
|
||
fB = ( (nColor >> 16) ) / 255.0f;
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fR, fG, fB ) ) )
|
||
return hRes;
|
||
|
||
|
||
if ( 255 != m_oBrush.Alpha1 || 255 != m_oPen.Alpha )
|
||
{
|
||
XmlUtils::CXmlWriter oWriter;
|
||
|
||
oWriter.WriteNodeBegin( _T("ExtGState") );
|
||
|
||
if ( 255 != m_oBrush.Alpha1 )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaFill"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)m_oBrush.Alpha1/255.0f );
|
||
oWriter.WriteNodeEnd( _T("AlphaFill"), TRUE, TRUE );
|
||
}
|
||
|
||
if ( 255 != m_oPen.Alpha )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaStroke"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)m_oPen.Alpha/255.0f );
|
||
oWriter.WriteNodeEnd( _T("AlphaStroke"), TRUE, TRUE );
|
||
}
|
||
|
||
oWriter.WriteNodeEnd( _T("ExtGState") );
|
||
|
||
BSTR bsXml = oWriter.GetXmlString().AllocSysString();
|
||
if ( FAILED( hRes = SetExtGraphicsState2( bsXml ) ) )
|
||
{
|
||
::SysFreeString( bsXml );
|
||
return hRes;
|
||
}
|
||
|
||
::SysFreeString( bsXml );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = UpdateCoordSpace() ) )
|
||
return hRes;
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
unsigned long UpdateCoordSpace()
|
||
{
|
||
// Здесь предполагается, что текущая матрица CTM единичная
|
||
// Поэтому этой функцией надо пользоваться аккуратно
|
||
|
||
HRESULT hRes = S_OK;
|
||
|
||
float fPageHeight = 0.0f;
|
||
float fPageWidth = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = GetWidth( &fPageWidth ) ) )
|
||
return hRes;
|
||
|
||
DWORD nFlags = m_oCommandParams.nFlag;
|
||
if ( !( nFlags == 16 ) )
|
||
{
|
||
|
||
double dAngle = m_oCommandParams.dAngle;
|
||
double dLeft = m_oCommandParams.dLeft;
|
||
double dHeight = m_oCommandParams.dHeight;
|
||
double dWidth = m_oCommandParams.dWidth;
|
||
double dTop = m_oCommandParams.dTop;
|
||
|
||
if ( 0 == nFlags && 0 == dAngle )
|
||
return S_OK;
|
||
|
||
// Миллиметры -> координаты PDF (72dpi)
|
||
|
||
dLeft = MMToPDFCoords( dLeft );
|
||
dTop = MMToPDFCoords( dTop );
|
||
dWidth = MMToPDFCoords( dWidth );
|
||
dHeight = MMToPDFCoords( dHeight );
|
||
|
||
dTop = fPageHeight - dTop;
|
||
dAngle = dAngle * 3.141592f / 180;
|
||
|
||
// Высчитываем центр прямоугольника ( относительно него производится поворот )
|
||
|
||
double dX0 = dLeft + dWidth / 2;
|
||
double dY0 = dTop - dHeight / 2;
|
||
|
||
double dA = cos( dAngle );
|
||
double dB = sin( dAngle );
|
||
double dC = -sin( dAngle );
|
||
double dD = cos( dAngle );
|
||
double dE = dX0 - dX0 * cos ( dAngle ) + dY0 * sin( dAngle );
|
||
double dF = dY0 - dX0 * sin ( dAngle ) - dY0 * cos( dAngle );
|
||
|
||
BOOL bFlipX = nFlags & 1;
|
||
BOOL bFlipY = nFlags & 2;
|
||
|
||
if ( !bFlipX && !bFlipY )
|
||
{
|
||
// Ничего не делаем
|
||
//if ( FAILED( hRes = Concat( dA, dB, dC, dD, dE, dF ) ) )
|
||
// return hRes;
|
||
}
|
||
else if ( bFlipX && !bFlipY )
|
||
{
|
||
dA = -dA;
|
||
dC = -dC;
|
||
dE = -dE + 2 * dX0;
|
||
//if ( FAILED( hRes = Concat( -dA, dB, -dC, dD, -dE + 2 * dX0, dF ) ) )
|
||
// return hRes;
|
||
}
|
||
else if ( !bFlipX && bFlipY )
|
||
{
|
||
dB = -dB;
|
||
dD = -dD;
|
||
dF = -dF + 2 * dY0;
|
||
|
||
//if ( FAILED( hRes = Concat( dA, -dB, dC, -dD, dE, -dF + 2 * dY0 ) ) )
|
||
// return hRes;
|
||
}
|
||
else
|
||
{
|
||
dA = -dA;
|
||
dB = -dB;
|
||
dC = -dC;
|
||
dD = -dD;
|
||
dE = -dE + 2 * dX0;
|
||
dF = -dF + 2 * dY0;
|
||
//if ( FAILED( hRes = Concat( -dA, -dB, -dC, -dD, -dE + 2 * dX0, -dF + 2 * dY0 ) ) )
|
||
// return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = Concat( dA, dB, dC, dD, dE, dF ) ) )
|
||
return hRes;
|
||
|
||
//if ( (NULL != m_pCurCommand->pPrev && c_nClipType == m_pCurCommand->pPrev->nType) || c_nClipType == m_pCurCommand->nType )
|
||
m_oClipCTM.Set( dA, dB, dC, dD, dE, dF );
|
||
}
|
||
else
|
||
{
|
||
float fA = m_oCommandParams.oMatrix.fA;
|
||
float fB = m_oCommandParams.oMatrix.fB;
|
||
float fC = m_oCommandParams.oMatrix.fC;
|
||
float fD = m_oCommandParams.oMatrix.fD;
|
||
float fE = m_oCommandParams.oMatrix.fE;
|
||
float fF = m_oCommandParams.oMatrix.fF;
|
||
|
||
if ( FAILED( hRes = Concat( fA, -fB, -fC, fD, MMToPDFCoords( fE ) + fC * fPageHeight, fPageHeight - fPageHeight * fD - MMToPDFCoords( fF ) ) ) )
|
||
return hRes;
|
||
|
||
//if ( (NULL != m_pCurCommand->pPrev && c_nClipType == m_pCurCommand->pPrev->nType) || c_nClipType == m_pCurCommand->nType )
|
||
m_oClipCTM.Set( fA, -fB, -fC, fD, MMToPDFCoords( fE ) + fC * fPageHeight, fPageHeight - fPageHeight * fD - MMToPDFCoords( fF ) );
|
||
|
||
}
|
||
return S_OK;
|
||
|
||
}
|
||
unsigned long UpdateCoordSpace2(CMatrix *pTransform)
|
||
{
|
||
// Здесь предполагается, что текущая матрица CTM единичная
|
||
// Поэтому этой функцией надо пользоваться аккуратно
|
||
|
||
HRESULT hRes = S_OK;
|
||
|
||
float fPageHeight = 0.0f;
|
||
float fPageWidth = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = GetWidth( &fPageWidth ) ) )
|
||
return hRes;
|
||
|
||
|
||
float fA = (float)pTransform->get_A();
|
||
float fB = (float)pTransform->get_B();
|
||
float fC = (float)pTransform->get_C();
|
||
float fD = (float)pTransform->get_D();
|
||
float fE = (float)pTransform->get_E();
|
||
float fF = (float)pTransform->get_F();
|
||
|
||
if ( FAILED( hRes = Concat( fA, -fB, -fC, fD, MMToPDFCoords( fE ) + fC * fPageHeight, fPageHeight - fPageHeight * fD - MMToPDFCoords( fF ) ) ) )
|
||
return hRes;
|
||
|
||
m_oClipCTM.Set( fA, -fB, -fC, fD, MMToPDFCoords( fE ) + fC * fPageHeight, fPageHeight - fPageHeight * fD - MMToPDFCoords( fF ) );
|
||
|
||
return S_OK;
|
||
|
||
}
|
||
bool FileExist(CString sFilePath )
|
||
{
|
||
return ( -1 != _waccess( sFilePath.GetBuffer(), 0 ) || CFileDownloader::IsNeedDownload(sFilePath) );
|
||
}
|
||
|
||
// Устанавливаем текущее состояние рендерера
|
||
BOOL SetState ( ERendererState eState )
|
||
{
|
||
m_oRendererState.set_NewState( eState, m_oTransform );
|
||
|
||
if ( rendstatePath == m_oRendererState.get_PrevState() && rendstatePath != m_oRendererState.get_State() )
|
||
{
|
||
// TODO: перенести сюда запись пата
|
||
}
|
||
else if ( rendstateClipPath == m_oRendererState.get_PrevState() && rendstateClipReset == m_oRendererState.get_State() )
|
||
{
|
||
// Набили клип и его удалили, в данном случае ничего не делаем. Обнуляем клип
|
||
}
|
||
else if ( rendstateClipPath == m_oRendererState.get_PrevState() && rendstateClipPath != m_oRendererState.get_State() )
|
||
{
|
||
// TODO: Перенести сюда набивку клипа
|
||
}
|
||
else if ( rendstateClipReset == m_oRendererState.get_PrevState() && rendstateClipReset != m_oRendererState.get_State() )
|
||
{
|
||
// TODO: Reset клипа
|
||
}
|
||
else if ( rendstateText == m_oRendererState.get_PrevState() && ( rendstateText != m_oRendererState.get_State() || m_oRendererState.IsMatrixChanged() ) )
|
||
{
|
||
// TODO: Пока оставим так, но в будущем сделать, чтобы можно было менять матрицу сразу у текста
|
||
|
||
int nTextsCount = m_oContiniousText.GetSize();
|
||
|
||
// Если матрица преобразования изменилась, тогда последний текстовый
|
||
// элемент не нужно записывать. С него нужно начать новый текст.
|
||
if ( rendstateText == m_oRendererState.get_State() && m_oRendererState.IsMatrixChanged() )
|
||
nTextsCount--;
|
||
|
||
if ( nTextsCount > 0 )
|
||
{
|
||
CSynchAccess oSynchAccess = m_hSynchMutex;
|
||
|
||
// Загрузка шрифтов проиходит через m_oFont, поэтому далее этот параметр изменится
|
||
NSStructures::CFont CurFont = m_oFont;
|
||
|
||
// Запоминаем некоторые настройки, чтобы потом их восстановить
|
||
float fOldLineWidth = 0.0f;
|
||
float fFillR, fFillG, fFillB, fStrokeR, fStrokeG, fStrokeB;
|
||
|
||
if ( FAILED( GetLineWidth( &fOldLineWidth ) ) )
|
||
return FALSE;
|
||
|
||
if ( FAILED( GetRGBFill( &fFillR, &fFillG, &fFillB ) ) )
|
||
return FALSE;
|
||
|
||
if ( FAILED( GetRGBStroke( &fStrokeR, &fStrokeG, &fStrokeB ) ) )
|
||
return FALSE;
|
||
|
||
|
||
BOOL bDefaultFont = FALSE;
|
||
bool bWasHorScale = false;
|
||
bool bFirst = true;
|
||
NSStructures::CFont oPrevFont;
|
||
CContiniousText::TColor oPrevColor;
|
||
PToUnicode pPrevToUnicode = NULL;
|
||
double dPrevCharSpacing = 0;
|
||
|
||
long nAscent = 0;
|
||
long nDescent = 0;
|
||
long nXHeight = 0;
|
||
double dItalicAngle = 0;
|
||
float fPageHeight = 0.0f;
|
||
float fFontSize = 0;
|
||
|
||
float fXHeight = (float)nXHeight / 1000;
|
||
float fAscent = (float)nAscent / 1000;
|
||
float fDescent = fabs( (float)nDescent / 1000 );
|
||
float fR = 0;
|
||
float fG = 0;
|
||
float fB = 0;
|
||
|
||
if ( FAILED( GetHeight( &fPageHeight ) ) )
|
||
return FALSE;
|
||
|
||
// Делаем сохранение состояния
|
||
ATLTRACE2( _T("GSave: DrawText\n") );
|
||
if ( FAILED( GSave() ) )
|
||
return FALSE;
|
||
|
||
// Выставляем систему координат
|
||
CMatrix oTransform = m_oContiniousText.get_Matrix();
|
||
if ( FAILED( UpdateCoordSpace2( &oTransform ) ) )
|
||
return FALSE;
|
||
|
||
// Устанавливаем альфу для данного текста
|
||
float fAlphaFill = (float)m_oContiniousText.get_Color( 0 )->unA / 255.0f;
|
||
float fAlphaStroke = (float)m_oContiniousText.get_Color( 0 )->unA / 255.0f;
|
||
m_pCurrentExtGState = GetExtGState( m_pDocument, fAlphaStroke, fAlphaFill );
|
||
if ( OK != ( PageSetExtGState( m_pDocument->pCurPage, m_pCurrentExtGState ) ) )
|
||
return FALSE;
|
||
|
||
if ( FAILED( BeginText() ) )
|
||
return FALSE;
|
||
|
||
// Выясним как нам рисовать текст (пока сделаем всегда fill)
|
||
// TODO: В будущем надо добавить данную настройку в ContiniusText, и следить
|
||
// за ее изменениями, как, например, при изменении шрифта
|
||
ETextRenderingMode eRenderingMode = ETextRenderingMode::Fill; // Fill (по умолчанию)
|
||
//if ( c_nStrokeTextType == m_pCurCommand->nType )
|
||
// eRenderingMode = ETextRenderingMode::Stroke; // Stroke
|
||
|
||
if ( FAILED( SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
return FALSE;
|
||
|
||
/*
|
||
if ( ETextRenderingMode::Fill == eRenderingMode )
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Bold, тогда заливаем и обводим текст, тем самым утолщяя его
|
||
if ( m_oFont.Bold )
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::FillThenStroke) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::Fill) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
*/
|
||
|
||
|
||
for ( int nIndex = 0; nIndex < nTextsCount; nIndex++ )
|
||
{
|
||
const CContiniousText::TText *pText = m_oContiniousText.get_Text ( nIndex );
|
||
const NSStructures::CFont *pFont = m_oContiniousText.get_Font ( nIndex );
|
||
const CContiniousText::TColor *pColor = m_oContiniousText.get_Color ( nIndex );
|
||
const double dCharSp = m_oContiniousText.get_CharSp ( nIndex );
|
||
|
||
if ( !pText || !pFont || !pColor )
|
||
continue;
|
||
|
||
// Ищем кодировку ToUnicode для данной строки
|
||
PToUnicode pToUnicode = FindToUnicodeForString( m_pDocument, pText->bsText );
|
||
if ( !pToUnicode )
|
||
continue;
|
||
|
||
// Кодируем нашу строку в соответствии с текущей ToUnicode
|
||
CString sCodedString;
|
||
ToUnicodeWCharToString( pToUnicode, pText->bsText, &sCodedString );
|
||
|
||
bool bFontChange = false, bSizeChange = false, bColorChange = false, bCharSpChange = false;
|
||
|
||
if ( bFirst )
|
||
{
|
||
// Для первого текста выставляем все настройки
|
||
bFontChange = true;
|
||
bSizeChange = true;
|
||
bColorChange = true;
|
||
bCharSpChange = true;
|
||
|
||
bFirst = false;
|
||
}
|
||
else
|
||
{
|
||
if ( ( CString( pToUnicode->sName ) != CString( pPrevToUnicode->sName ) ) || ( oPrevFont.Path != pFont->Path ) || ( _T("") == pFont->Path && ( oPrevFont.Name != pFont->Name || oPrevFont.Bold != pFont->Bold || oPrevFont.Italic != pFont->Italic ) ) )
|
||
bFontChange = true;
|
||
if ( fabs( oPrevFont.Size - pFont->Size ) > 0.001 )
|
||
bSizeChange = true;
|
||
if ( oPrevColor.unA != pColor->unA || oPrevColor.unB != pColor->unB || oPrevColor.unG != pColor->unG || oPrevColor.unR != pColor->unR )
|
||
bColorChange = true;
|
||
if ( fabs( dPrevCharSpacing - dCharSp ) > 0.001 )
|
||
bCharSpChange = true;
|
||
}
|
||
|
||
// Запоминаем настройки
|
||
oPrevColor = *pColor;
|
||
oPrevFont = *pFont;
|
||
pPrevToUnicode = pToUnicode;
|
||
dPrevCharSpacing = dCharSp;
|
||
|
||
m_oFont = *pFont;
|
||
BOOL bOldBold = m_oFont.Bold;
|
||
BOOL bOldItalic = m_oFont.Italic;
|
||
|
||
if ( bSizeChange )
|
||
fFontSize = (float)m_oFont.Size;
|
||
|
||
if ( bFontChange )
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
// Запоминаем значения Bold и Italic, потому что в функции GdiFontToPdfFont они могут измениться
|
||
|
||
HRESULT hRes = S_OK;
|
||
if ( FAILED( hRes = GdiFontToPdfFont2( A2W( pToUnicode->sName ), FALSE ) ) )
|
||
{
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND == hRes )
|
||
{
|
||
ResetError( m_pDocument );
|
||
sCodedString = CString( pText->bsText );
|
||
bDefaultFont = TRUE;
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bDefaultFont = FALSE;
|
||
|
||
if ( bWasHorScale )
|
||
{
|
||
// Отменяем горизонтальное сжатие/растяжение
|
||
if ( FAILED( SetHorizontalScalling( 100 ) ) )
|
||
continue;
|
||
|
||
bWasHorScale = false;
|
||
}
|
||
}
|
||
|
||
if ( !m_oFont.Italic )
|
||
dItalicAngle = 0;
|
||
else
|
||
dItalicAngle = 3.141592f / 12;
|
||
|
||
if ( FAILED( GetFontAscent( &nAscent ) ) )
|
||
continue;
|
||
|
||
if ( FAILED( GetFontDescent( &nDescent ) ) )
|
||
continue;
|
||
|
||
if ( FAILED( GetFontXHeight( &nXHeight ) ) )
|
||
continue;
|
||
|
||
fXHeight = (float)nXHeight / 1000;
|
||
fAscent = (float)nAscent / 1000;
|
||
fDescent = fabs( (float)nDescent / 1000 );
|
||
|
||
// Данная ветка сделана специально для конвертации Djvu -> PDF
|
||
if ( _T("AVSEmptyFont") == pFont->Name )
|
||
{
|
||
float fVKoef;
|
||
|
||
if ( fabs( pFont->Size ) < 0.01 )
|
||
fVKoef = 1;
|
||
else
|
||
fVKoef = pText->fHeight / pFont->Size;
|
||
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( SetTextMatrix( 1, (float)tan( 0.0 ), (float)fVKoef * tan( dItalicAngle ), fVKoef * 1, 0, 0 ) ) )
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( SetTextMatrix( 1, (float)tan( 0.0 ), (float)tan( dItalicAngle ), 1, 0, 0 ) ) )
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if ( bColorChange )
|
||
{
|
||
fR = ( pColor->unR ) / 255.0f;
|
||
fG = ( pColor->unG ) / 255.0f;
|
||
fB = ( pColor->unB ) / 255.0f;
|
||
|
||
// Выставляем цвет текста и линий
|
||
if ( FAILED( SetRGBFill( fR, fG, fB ) ) )
|
||
continue;
|
||
|
||
if ( FAILED( SetRGBStroke( fR, fG, fB ) ) )
|
||
continue;
|
||
}
|
||
|
||
if ( bCharSpChange )
|
||
{
|
||
// Устанавливаем межсимвольный интервал
|
||
if ( FAILED( SetCharSpace( (float)dCharSp ) ) )
|
||
continue;
|
||
}
|
||
|
||
if ( bFontChange || bSizeChange )
|
||
{
|
||
// Устанавливаем текущий шрифт и размер шрифта
|
||
if ( FAILED( SetFontAndSizeToGState( fFontSize ) ) )
|
||
continue;
|
||
}
|
||
|
||
BSTR bsCodedString = sCodedString.AllocSysString();
|
||
|
||
|
||
// Если шрифт не нашли, и используется стандартный шрифт, значит, ширина слов будет неверной.
|
||
// Чтобы слова не наползали друг на друга скейлим текст к его реальной ширине.
|
||
if ( bDefaultFont )
|
||
{
|
||
bWasHorScale = true;
|
||
|
||
// Измеряем размер
|
||
float fTextWidth = 0.0f;
|
||
if ( FAILED( GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
continue;
|
||
}
|
||
|
||
float fKoef;
|
||
if ( fabs( fTextWidth ) < 0.01 )
|
||
fKoef = 1;
|
||
else
|
||
fKoef = pText->fWidth / fTextWidth * 100; // Scale задается в процентах
|
||
|
||
if ( fKoef > 0.001 )
|
||
{
|
||
if ( FAILED( SetHorizontalScalling( fKoef ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Выводим текст
|
||
if ( FAILED( TextOut( (float)pText->fX, fPageHeight - (float)(pText->fY + pText->fBaseLineOffset), bsCodedString ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
continue;
|
||
}
|
||
|
||
::SysFreeString( bsCodedString );
|
||
|
||
|
||
if ( bFontChange )
|
||
{
|
||
m_oFont.Bold = bOldBold;
|
||
m_oFont.Italic = bOldItalic;
|
||
}
|
||
}
|
||
|
||
// Заканчиваем запись текста
|
||
if ( FAILED( EndText() ) )
|
||
return FALSE;
|
||
|
||
// Восстанавливаем систему координат
|
||
ATLTRACE2( _T("GRestore: DrawText\n") );
|
||
if ( FAILED( GRestore() ) )
|
||
return FALSE;
|
||
|
||
// Восстанавливаем старые настройки
|
||
if ( FAILED( SetLineWidth( fOldLineWidth ) ) )
|
||
return FALSE;
|
||
|
||
if ( FAILED( SetRGBFill( fFillR, fFillG, fFillB ) ) )
|
||
return FALSE;
|
||
|
||
if ( FAILED( SetRGBStroke( fStrokeR, fStrokeG, fStrokeB ) ) )
|
||
return FALSE;
|
||
|
||
// Восстанавливаем текущий шрифт
|
||
m_oFont = CurFont;
|
||
}
|
||
|
||
if ( rendstateText == m_oRendererState.get_State() && m_oRendererState.IsMatrixChanged() )
|
||
m_oContiniousText.LeaveLast();
|
||
else
|
||
m_oContiniousText.Reset();
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
public:
|
||
//-----------------------------------------------------------------------------------------------------
|
||
//
|
||
// Интерфейс IPDFWriter
|
||
//
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(CreatePDF)()
|
||
{
|
||
if ( m_pFontManager && !m_bIsFontsInitialize )
|
||
{
|
||
#ifdef BUILD_CONFIG_OPENSOURCE_VERSION
|
||
m_pFontManager->Init( L"", TRUE, TRUE );
|
||
#else
|
||
m_pFontManager->Initialize( _T("") );
|
||
#endif
|
||
m_bIsFontsInitialize = TRUE;
|
||
}
|
||
|
||
if ( !CRegistratorClient::IsRegistered() )
|
||
return AVS_OFFICEPDFWRITER_ERROR_AVS_REGISTRATION;
|
||
m_pDocument = New();
|
||
if ( !m_pDocument )
|
||
return AVS_OFFICEPDFWRITER_ERROR_FAILD_TO_ALLOC_MEM;
|
||
|
||
// m_pDocument->patterns = &m_oPatterns;
|
||
|
||
// Создаем стек команд
|
||
m_pCurCommand = new TCommandType();
|
||
m_pCurCommand->nType = c_nNone;
|
||
m_pCurCommand->nFlag = 0;
|
||
m_pCurCommand->pPrev = NULL;
|
||
|
||
m_pFindFonts = new CFindFonts();
|
||
|
||
m_bClipPath = FALSE;
|
||
m_wsTempDir = _T("");
|
||
|
||
m_oTransform.Reset();
|
||
m_oRendererState.Reset();
|
||
m_bFirstMoveTo = TRUE;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DeletePDF)()
|
||
{
|
||
FreePDF();
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveToFile)(BSTR bsPath)
|
||
{
|
||
SetState( rendstateNone );
|
||
|
||
if ( !CRegistratorClient::IsRegistered() )
|
||
return AVS_OFFICEPDFWRITER_ERROR_AVS_REGISTRATION;
|
||
|
||
CString sFileName( bsPath );
|
||
|
||
// Проверяем не пустой ли документ мы пытаемся записать.
|
||
if ( m_pDocument->pPageList->nCount <= 0 )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_DOCUMENT;
|
||
|
||
unsigned long nRet = SaveDocToFile( m_pDocument, sFileName.GetBuffer() );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFPageMode)(long nMode)
|
||
{
|
||
unsigned long nRet = SetPageMode( m_pDocument, (EPageMode)nMode);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetPDFPageMode)(long *pnMode)
|
||
{
|
||
*pnMode = (long)GetPageMode( m_pDocument );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFPageLayout)(long nLayout)
|
||
{
|
||
unsigned long nRet = SetPageLayout( m_pDocument, (EPageLayout)nLayout);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetPDFPageLayout)(long *pnLayout)
|
||
{
|
||
*pnLayout = (long)GetPageLayout( m_pDocument );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFViewerPreference)(long nValue )
|
||
{
|
||
unsigned long nRet = SetViewerPreference( m_pDocument, nValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetPDFViewerPreference)(long *pnValue)
|
||
{
|
||
*pnValue = (long)GetViewerPreference( m_pDocument );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFCompressionMode)(long nMode)
|
||
{
|
||
unsigned long nRet = SetCompressionMode( m_pDocument, nMode );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFOpenAction)(long nAction)
|
||
{
|
||
if ( !m_pCurrentDestination )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_DESTINATION_NOT_FOUND;
|
||
unsigned long nRet = SetOpenAction( m_pDocument, m_pCurrentDestination );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetLastErrorCode)(long *pnErrorCode)
|
||
{
|
||
*pnErrorCode = ErrorGetCode( &m_pDocument->oError );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetLastErrorString)(BSTR *pbsErrorString)
|
||
{
|
||
const char *sErrorString = ErrorGetString( &m_pDocument->oError );
|
||
CString sErr(sErrorString);
|
||
|
||
*pbsErrorString = sErr.AllocSysString();
|
||
return S_OK;
|
||
}
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(AddNewPage)()
|
||
{
|
||
if ( !m_pDocument )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_DOCUMENT;
|
||
|
||
// новая страница становится текущей
|
||
Page page = AddPage( m_pDocument );
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetPagesCount)(long *pnCount )
|
||
{
|
||
*pnCount = m_pDocument->pPageList->nCount;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCurrentPage)(long nIndex)
|
||
{
|
||
if ( nIndex > m_pDocument->pPageList->nCount )
|
||
return S_FALSE;
|
||
|
||
Page pTempPage = (Page)ListItemAt( m_pDocument->pPageList, nIndex );
|
||
DocSetCurrentPage( m_pDocument, pTempPage );
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetCurrentPageIndex)(long *pnIndex)
|
||
{
|
||
*pnIndex = ListFind( m_pDocument->pPageList, m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPageWidth)(float fWidth)
|
||
{
|
||
unsigned long nRet = PageSetWidth( m_pDocument->pCurPage, fWidth );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPageHeight)(float fHeight)
|
||
{
|
||
unsigned long nRet = PageSetHeight( m_pDocument->pCurPage, fHeight );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetWidth)(float *pfWidth)
|
||
{
|
||
*pfWidth = PageGetWidth( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetHeight)(float *pfHeight)
|
||
{
|
||
*pfHeight = PageGetHeight( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetSize)(long nSize, long nDirection)
|
||
{
|
||
unsigned long nRet = PageSetSize(m_pDocument->pCurPage, (EPageSizes)nSize, (EPageDirection)nDirection);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetRotate)(long nAngle)
|
||
{
|
||
unsigned long nRet = PageSetRotate( m_pDocument->pCurPage, nAngle );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(AddLabel)(long nPageNum, long nNumStyle, long nFirstPage, BSTR bsPrefix )
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sPrefix = W2A(bsPrefix);
|
||
unsigned long nRet = AddPageLabel( m_pDocument, nPageNum, (PageNumStyle)nNumStyle, nFirstPage, sPrefix );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(SetLineWidth)(float fLineWidth)
|
||
{
|
||
unsigned long nRet = PageSetLineWidth( m_pDocument->pCurPage, fLineWidth );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetLineWidth)(float *pfLineWidth)
|
||
{
|
||
*pfLineWidth = PageGetLineWidth( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetLineCap)(long nLineCap)
|
||
{
|
||
unsigned long nRet = PageSetLineCap( m_pDocument->pCurPage, (ELineCapStyle)nLineCap);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetLineCap)(long *pnLineCap)
|
||
{
|
||
*pnLineCap = PageGetLineCap( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetLineJoin)(long nLineJoin)
|
||
{
|
||
unsigned long nRet = PageSetLineJoin( m_pDocument->pCurPage, (LineJoinStyle)nLineJoin);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetLineJoin)(long *pnLineJoin)
|
||
{
|
||
*pnLineJoin = PageGetLineJoin( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetMiterLimit)(float fMiterLimit)
|
||
{
|
||
unsigned long nRet = PageSetMiterLimit( m_pDocument->pCurPage, fMiterLimit);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetMiterLimit)(float *pfMiterLimit)
|
||
{
|
||
*pfMiterLimit = PageGetMiterLimit( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetDash)(SAFEARRAY **ppnDashPtn, long nNumParam, float fPhase)
|
||
{
|
||
double *pArray = new double[nNumParam];
|
||
if ( 0 != nNumParam )
|
||
{
|
||
// check for valid pixel array size
|
||
if ( 1 != SafeArrayGetDim(*ppnDashPtn) )
|
||
return FALSE;
|
||
|
||
VARTYPE vType;
|
||
// check for valid array element type
|
||
if ( FAILED(SafeArrayGetVartype(*ppnDashPtn, &vType)) || VT_R4 != vType )
|
||
return S_OK;
|
||
|
||
float* pTemp = (float*)(*ppnDashPtn)->pvData;
|
||
for ( int nIndex = 0 ; nIndex < nNumParam; nIndex++ )
|
||
{
|
||
pArray[nIndex] = *(pTemp + nIndex);
|
||
}
|
||
}
|
||
|
||
unsigned long nRet = PageSetDash( m_pDocument->pCurPage, pArray, nNumParam, fPhase);
|
||
delete[] pArray;
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetDash)(SAFEARRAY **ppnDashPtn, long *pnNumParam, float *pfPhase)
|
||
{
|
||
DashMode oMode = {{0, 0, 0, 0, 0, 0, 0, 0}, 0, 0};
|
||
oMode = PageGetDash( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
if ( 0 == oMode.nNumPoints )
|
||
{
|
||
*ppnDashPtn = NULL;
|
||
*pnNumParam = 0;
|
||
*pfPhase = 0;
|
||
return S_OK;
|
||
}
|
||
float* pTemp = new float[oMode.nNumPoints];
|
||
for ( int nIndex = 0; nIndex < oMode.nNumPoints; nIndex++ )
|
||
pTemp[nIndex] = (float)oMode.afPtn[nIndex];
|
||
|
||
SAFEARRAYBOUND bounds[1];
|
||
|
||
bounds[0].lLbound = 0;
|
||
bounds[0].cElements = oMode.nNumPoints;
|
||
|
||
(*ppnDashPtn) = SafeArrayCreate(VT_R4, 1, bounds);
|
||
|
||
if ( !(*ppnDashPtn) )
|
||
{
|
||
delete[] pTemp;
|
||
return S_OK;
|
||
}
|
||
|
||
memcpy( (*ppnDashPtn)->pvData, pTemp, oMode.nNumPoints * sizeof(float) );
|
||
delete[] pTemp;
|
||
*pnNumParam = (long)oMode.nNumPoints;
|
||
*pfPhase = (float)oMode.fPhase;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetFlat)(float fFlatness)
|
||
{
|
||
unsigned long nRet = PageSetFlat( m_pDocument->pCurPage, fFlatness );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFlat)(float *pfFlatness)
|
||
{
|
||
*pfFlatness = PageGetFlat( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(NewExtGraphicsState)()
|
||
{
|
||
m_pCurrentExtGState = CreateExtGState( m_pDocument );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ExtGraphicsStateSetAlphaStroke)(float fValue)
|
||
{
|
||
unsigned long nRet = ExtGStateSetAlphaStroke( m_pCurrentExtGState, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ExtGraphicsStateSetAlphaFill)(float fValue)
|
||
{
|
||
unsigned long nRet = ExtGStateSetAlphaFill( m_pCurrentExtGState, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ExtGraphicsStateSetBlendMode)(long nBlendMode)
|
||
{
|
||
unsigned long nRet = ExtGStateSetBlendMode( m_pCurrentExtGState, (EBlendMode)nBlendMode );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ExtGraphicsStateSetStrokeAdjustment)(int nFlag)
|
||
{
|
||
BOOL bFlag = ( 0 == nFlag ? FALSE : TRUE);
|
||
|
||
unsigned long nRet = ExtGStateSetStrokeAdjustment( m_pCurrentExtGState, bFlag );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetExtGraphicsState)()
|
||
{
|
||
if ( !m_pCurrentExtGState )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_EXTGSTATE_NOT_FOUND;
|
||
|
||
unsigned long nRet = PageSetExtGState( m_pDocument->pCurPage, m_pCurrentExtGState );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GSave)()
|
||
{
|
||
unsigned long nRet = PageGSave( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GRestore)()
|
||
{
|
||
BOOL bIsPrevGState = FALSE;
|
||
|
||
if ( m_pDocument->pCurPage && m_pDocument->pCurPage )
|
||
{
|
||
PageAttr pAttr = (PageAttr)m_pDocument->pCurPage->pAttr;
|
||
if ( pAttr->pGState->pPrev )
|
||
bIsPrevGState = TRUE;
|
||
}
|
||
if ( bIsPrevGState )
|
||
{
|
||
unsigned long nRet = PageGRestore( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetGStateDepth)(long *pnDepth)
|
||
{
|
||
*pnDepth = PageGetGStateDepth( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetGMode)(long *pnGMode)
|
||
{
|
||
*pnGMode = PageGetGMode( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(Concat)(float fA, float fB, float fC, float fD, float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageConcat( m_pDocument->pCurPage, fA, fB, fC, fD, fX, fY);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MoveTo)(float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageMoveTo( m_pDocument->pCurPage, fX, fY);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentPosition)(float *pfX, float *pfY)
|
||
{
|
||
TPoint oCurPos = {0,0};
|
||
|
||
unsigned long nRet = PageGetCurrentPos2( m_pDocument->pCurPage, &oCurPos );
|
||
if ( OK != nRet )
|
||
{
|
||
*pfX = 0.0f;
|
||
*pfY = 0.0f;
|
||
return nRet;
|
||
}
|
||
|
||
*pfX = oCurPos.fX;
|
||
*pfY = oCurPos.fY;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LineTo)(float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageLineTo( m_pDocument->pCurPage, fX, fY);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CurveTo)(float fX1, float fY1, float fX2, float fY2, float fX3, float fY3)
|
||
{
|
||
unsigned long nRet = PageCurveTo( m_pDocument->pCurPage, fX1, fY1, fX2, fY2, fX3, fY3);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CurveTo2)(float fX2, float fY2, float fX3, float fY3)
|
||
{
|
||
unsigned long nRet = PageCurveTo2( m_pDocument->pCurPage, fX2, fY2, fX3, fY3);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CurveTo3)(float fX1, float fY1, float fX3, float fY3)
|
||
{
|
||
unsigned long nRet = PageCurveTo3( m_pDocument->pCurPage, fX1, fY1, fX3, fY3);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ClosePath)()
|
||
{
|
||
unsigned long nRet = PageClosePath( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(AppendRectangle)(float fX, float fY, float fWidth, float fHeight)
|
||
{
|
||
unsigned long nRet = PageRectangle( m_pDocument->pCurPage, fX, fY, fWidth, fHeight );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(Stroke)()
|
||
{
|
||
unsigned long nRet = PageStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetStrokingColorSpace)(long *pnColorSpace)
|
||
{
|
||
*pnColorSpace = (long)PageGetStrokingColorSpace( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ClosePathStroke)()
|
||
{
|
||
unsigned long nRet = PageClosePathStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(Fill)()
|
||
{
|
||
unsigned long nRet = PageFill( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFillingColorSpace)(long *pnColorSpace)
|
||
{
|
||
*pnColorSpace = (long)PageGetFillingColorSpace( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EoFill)()
|
||
{
|
||
unsigned long nRet = PageEoFill( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(FillStroke)()
|
||
{
|
||
unsigned long nRet = PageFillStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EoFillStroke)()
|
||
{
|
||
unsigned long nRet = PageEoFillStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ClosePathFillStroke)()
|
||
{
|
||
unsigned long nRet = PageClosePathFillStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ClosePathEoFillStroke)()
|
||
{
|
||
unsigned long nRet = PageClosePathEoFillStroke( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EndPath)()
|
||
{
|
||
unsigned long nRet = PageEndPath( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(Clip)()
|
||
{
|
||
unsigned long nRet = PageClip( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EoClip)()
|
||
{
|
||
unsigned long nRet = PageEoclip( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(BeginText)()
|
||
{
|
||
unsigned long nRet = PageBeginText( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EndText)()
|
||
{
|
||
unsigned long nRet = PageEndText( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetCharSpace)(float fValue)
|
||
{
|
||
unsigned long nRet = PageSetCharSpace( m_pDocument->pCurPage, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCharSpace)(float *pfValue)
|
||
{
|
||
*pfValue = PageGetCharSpace( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetWordSpace)(float fValue)
|
||
{
|
||
unsigned long nRet = PageSetWordSpace( m_pDocument->pCurPage, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetWordSpace)(float *pfValue)
|
||
{
|
||
*pfValue = PageGetWordSpace( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetHorizontalScalling)(float fValue)
|
||
{
|
||
unsigned long nRet = PageSetHorizontalScalling( m_pDocument->pCurPage, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetHorizontalScalling)(float *pfValue)
|
||
{
|
||
*pfValue = PageGetHorizontalScalling( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetTextLeading)(float fValue)
|
||
{
|
||
unsigned long nRet = PageSetTextLeading( m_pDocument->pCurPage, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetTextLeading)(float *pfValue)
|
||
{
|
||
*pfValue = PageGetTextLeading( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetFontAndSizeToGState)(float fSize)
|
||
{
|
||
unsigned long nRet = PageSetFontAndSize( m_pDocument->pCurPage, m_pCurrentFont, fSize);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentFontFromGState)(BSTR *pbsFontName, BSTR *pbsEncodingName)
|
||
{
|
||
FontDict pFont = PageGetCurrentFont( m_pDocument->pCurPage );
|
||
if ( !pFont )
|
||
{
|
||
*pbsFontName = NULL;
|
||
*pbsEncodingName = NULL;
|
||
}
|
||
else
|
||
{
|
||
CString sFontName(FontGetFontName( pFont ));
|
||
CString sEncodingName(((FontAttr)pFont->pAttr)->pEncoder->sName);
|
||
|
||
*pbsFontName = sFontName.AllocSysString();
|
||
*pbsEncodingName = sEncodingName.AllocSysString();
|
||
}
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentFontSizeFromGState)(float *pfSize)
|
||
{
|
||
*pfSize = PageGetCurrentFontSize( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetTextRenderingMode)(long nMode)
|
||
{
|
||
unsigned long nRet = PageSetTextRenderingMode( m_pDocument->pCurPage, (ETextRenderingMode)nMode );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetTextRenderingMode)(long *pnMode)
|
||
{
|
||
*pnMode = (long)PageGetTextRenderingMode( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetTextRise)(float fValue)
|
||
{
|
||
unsigned long nRet = PageSetTextRise( m_pDocument->pCurPage, fValue );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetTextRise)(float *pfValue)
|
||
{
|
||
*pfValue = PageGetTextRise( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MoveTextPos)(float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageMoveTextPos( m_pDocument->pCurPage, fX, fY );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MoveTextPos2)(float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageMoveTextPos2( m_pDocument->pCurPage, fX, fY );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentTextPosition)(float *pfX, float *pfY)
|
||
{
|
||
TPoint oCurPos = {0,0};
|
||
|
||
oCurPos = PageGetCurrentTextPos( m_pDocument->pCurPage);
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
{
|
||
*pfX = 0.0f;
|
||
*pfY = 0.0f;
|
||
return nRet;
|
||
}
|
||
|
||
*pfX = oCurPos.fX;
|
||
*pfY = oCurPos.fY;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetTextMatrix)(float fA, float fB, float fC, float fD, float fX, float fY)
|
||
{
|
||
unsigned long nRet = PageSetTextMatrix( m_pDocument->pCurPage, fA, fB, fC, fD, fX, fY );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetTextMatrix)(float *pfA, float *pfB, float *pfC, float *pfD, float *pfX, float *pfY)
|
||
{
|
||
TransMatrix oMatrix = { 1, 0, 0, 1, 0, 0};
|
||
|
||
oMatrix = PageGetTextMatrix( m_pDocument->pCurPage );
|
||
*pfA = oMatrix.fA;
|
||
*pfB = oMatrix.fB;
|
||
*pfC = oMatrix.fC;
|
||
*pfD = oMatrix.fD;
|
||
*pfX = oMatrix.fX;
|
||
*pfY = oMatrix.fY;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MoveToNextLine)()
|
||
{
|
||
unsigned long nRet = PageMoveToNextLine( m_pDocument->pCurPage );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ShowText)(BSTR bsText)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
|
||
// TO DO: ShowText: надо нормально конвертировать текст, иизмерять его длину
|
||
unsigned long nRet = PageShowText( m_pDocument->pCurPage, (BYTE *)sText, strlen(sText), NULL, 0 );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ShowTextNextLine)(BSTR bsText)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
|
||
// TO DO: ShowText: надо нормально конвертировать текст, иизмерять его длину
|
||
unsigned long nRet = PageShowTextNextLine( m_pDocument->pCurPage, (BYTE *)sText, strlen(sText), NULL, 0 );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ShowTextNextLineEx)(float fWordSpace, float fCharSpace, BSTR bsText)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
|
||
// TO DO: ShowText: надо нормально конвертировать текст, иизмерять его длину
|
||
unsigned long nRet = PageShowTextNextLineEx( m_pDocument->pCurPage, fWordSpace, fCharSpace, (BYTE *)sText, strlen(sText), NULL, 0 );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetGrayStroke)(float fGray)
|
||
{
|
||
unsigned long nRet = PageSetGrayStroke( m_pDocument->pCurPage, fGray );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetGrayStroke)(float *pfGray)
|
||
{
|
||
*pfGray = PageGetGrayStroke( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetGrayFill)(float fGray)
|
||
{
|
||
unsigned long nRet = PageSetGrayFill( m_pDocument->pCurPage, fGray );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetGrayFill)(float *pfGray)
|
||
{
|
||
*pfGray = PageGetGrayFill( m_pDocument->pCurPage );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetRGBStroke)(float fR, float fG, float fB)
|
||
{
|
||
unsigned long nRet = PageSetRGBStroke( m_pDocument->pCurPage, fR, fG, fB);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetRGBStroke)(float *pfR, float *pfG, float *pfB)
|
||
{
|
||
RGBColor oRGB = { 0, 0, 0};
|
||
oRGB = PageGetRGBStroke( m_pDocument->pCurPage );
|
||
*pfR = oRGB.r;
|
||
*pfG = oRGB.g;
|
||
*pfB = oRGB.b;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetRGBFill)(float fR, float fG, float fB)
|
||
{
|
||
//unsigned long nRet = PageSetShadingFill( m_pDocument->pCurPage, fR, fG, fB);
|
||
//if ( OK != nRet )
|
||
// return nRet;
|
||
//return S_OK;
|
||
|
||
unsigned long nRet = PageSetRGBFill( m_pDocument->pCurPage, fR, fG, fB);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetRGBFill)(float *pfR, float *pfG, float *pfB)
|
||
{
|
||
RGBColor oColor = PageGetRGBFill( m_pDocument->pCurPage );
|
||
*pfR = oColor.r;
|
||
*pfG = oColor.g;
|
||
*pfB = oColor.b;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCMYKStroke)(float fC, float fM, float fY, float fK)
|
||
{
|
||
unsigned long nRet = PageSetCMYKStroke( m_pDocument->pCurPage, fC, fM, fY, fK);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCMYKStroke)(float *pfC, float *pfM, float *pfY, float *pfK)
|
||
{
|
||
CMYKColor oCMYK = { 0, 0, 0, 0};
|
||
oCMYK = PageGetCMYKStroke( m_pDocument->pCurPage );
|
||
*pfC = oCMYK.c;
|
||
*pfM = oCMYK.m;
|
||
*pfY = oCMYK.y;
|
||
*pfK = oCMYK.k;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCMYKFill)(float fC, float fM, float fY, float fK)
|
||
{
|
||
unsigned long nRet = PageSetCMYKFill( m_pDocument->pCurPage, fC, fM, fY, fK);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCMYKFill)(float *pfC, float *pfM, float *pfY, float *pfK)
|
||
{
|
||
CMYKColor oCMYK = { 0, 0, 0, 0};
|
||
oCMYK = PageGetCMYKFill( m_pDocument->pCurPage );
|
||
*pfC = oCMYK.c;
|
||
*pfM = oCMYK.m;
|
||
*pfY = oCMYK.y;
|
||
*pfK = oCMYK.k;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ExecuteXObject)()
|
||
{
|
||
unsigned long nRet = PageExecuteXObject( m_pDocument->pCurPage, m_pCurrentXObject );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetExtGraphicsState2)(BSTR bsXmlOptions)
|
||
{
|
||
CString wsXml( bsXmlOptions );
|
||
|
||
XmlUtils::CXmlNode oMainNode;
|
||
oMainNode.FromXmlString( wsXml );
|
||
|
||
if ( _T("ExtGState") == oMainNode.GetName() )
|
||
{
|
||
float fAlphaStroke = -1, fAlphaFill = -1;
|
||
BlendMode eMode = BMEOF;
|
||
int nStrokeAdjustment = -1;
|
||
|
||
CString sValue;
|
||
XmlUtils::CXmlNode oNode;
|
||
if ( oMainNode.GetNode( _T("AlphaStroke"), oNode ) )
|
||
{
|
||
sValue = oNode.GetAttribute( _T("value"), _T("-1") );
|
||
fAlphaStroke = (float)XmlUtils::GetDouble( sValue );
|
||
}
|
||
if ( oMainNode.GetNode( _T("AlphaFill"), oNode ) )
|
||
{
|
||
sValue = oNode.GetAttribute( _T("value"), _T("-1") );
|
||
fAlphaFill = (float)XmlUtils::GetDouble( sValue );
|
||
}
|
||
if ( oMainNode.GetNode( _T("BlendMode"), oNode ) )
|
||
{
|
||
sValue = oNode.GetAttribute( _T("value"), _T("12") );
|
||
eMode = (BlendMode)XmlUtils::GetInteger( sValue );
|
||
}
|
||
if ( oMainNode.GetNode( _T("StrokeAdjustment"), oNode ) )
|
||
{
|
||
sValue = oNode.GetAttribute( _T("value"), _T("-1") );
|
||
nStrokeAdjustment = XmlUtils::GetInteger( sValue );
|
||
}
|
||
|
||
m_pCurrentExtGState = GetExtGState( m_pDocument, fAlphaStroke, fAlphaFill, eMode, nStrokeAdjustment );
|
||
return PageSetExtGState( m_pDocument->pCurPage, m_pCurrentExtGState );
|
||
}
|
||
|
||
|
||
return S_OK;
|
||
}
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(AppendCircle)(float fX, float fY, float fRad)
|
||
{
|
||
unsigned long nRet = PageCircle( m_pDocument->pCurPage, fX, fY, fRad );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(AppendEllipse)(float fX, float fY, float fXRad, float fYRad)
|
||
{
|
||
unsigned long nRet = PageEllipse( m_pDocument->pCurPage, fX, fY, fXRad, fYRad );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(AppendArc)(float fX, float fY, float fRad, float fAngle1, float fAngle2)
|
||
{
|
||
unsigned long nRet = PageArc( m_pDocument->pCurPage, fX, fY, fRad, fAngle1, fAngle2);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(AppendEllipseArc)(float fX, float fY, float fXRad, float fYRad, float fAngle1, float fAngle2, BOOL bClockDirection = FALSE)
|
||
{
|
||
unsigned long nRet = PageEllipseArc2( m_pDocument->pCurPage, fX, fY, fXRad, fYRad, fAngle1, fAngle2, bClockDirection );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(TextOut)(float fXPos, float fYPos, BSTR bsText)
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
if ( !m_pCurrentFont )
|
||
return S_OK;
|
||
|
||
FontAttr pFontAttr = (FontAttr)m_pCurrentFont->pAttr;
|
||
if ( FontDefCID != pFontAttr->pFontDef->eType )
|
||
{
|
||
// В данном случае все символы имеют значение от 0 до 255, т.е. на них нужен 1 байт
|
||
|
||
wchar_t* wsText = (wchar_t*)bsText;
|
||
char* sText = new char[wcslen(wsText) + 1];
|
||
sText[wcslen(wsText)] = '\0';
|
||
|
||
BOOL *pZeros = new BOOL[wcslen(wsText)];
|
||
BOOL bCodedString = TRUE;
|
||
for ( int nIndex = 0; nIndex < wcslen(wsText); nIndex++ )
|
||
{
|
||
if ( (unsigned int)bsText[nIndex] >= 256 )
|
||
{
|
||
bCodedString = FALSE;
|
||
}
|
||
|
||
if ( 0xFFFE == (unsigned int)bsText[nIndex] )
|
||
{
|
||
pZeros[nIndex] = 1;
|
||
}
|
||
else
|
||
{
|
||
pZeros[nIndex] = 0;
|
||
}
|
||
}
|
||
if ( bCodedString )
|
||
wcstombs( sText, wsText, wcslen(wsText) );
|
||
else
|
||
{
|
||
delete []sText;
|
||
sText = W2A( wsText );
|
||
}
|
||
|
||
BYTE *pString = new BYTE[wcslen(wsText)];
|
||
for ( int nIndex = 0; nIndex < wcslen(wsText); nIndex++ )
|
||
{
|
||
if ( 0 == pZeros[nIndex] )
|
||
pString[nIndex] = sText[nIndex];
|
||
else
|
||
pString[nIndex] = '\0';
|
||
}
|
||
delete []pZeros;
|
||
|
||
unsigned long nRet = PageTextOut( m_pDocument->pCurPage, fXPos, fYPos, pString, wcslen(wsText), NULL, 0 );
|
||
delete []pString;
|
||
|
||
if ( bCodedString )
|
||
delete []sText;
|
||
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
}
|
||
else
|
||
{
|
||
// В CID шрифтах количество байт на каждый символ зависит от самого символа
|
||
// и от кодировки CMap, заданной в шрифте.
|
||
|
||
Encoder pEncoder = pFontAttr->pEncoder;
|
||
if ( EncoderTypeDoubleByteStream != pEncoder->eType )
|
||
return S_OK;
|
||
|
||
CMapEncoderStreamAttr pEncoderAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
|
||
|
||
wchar_t* wsText = (wchar_t*)bsText;
|
||
int nSrcLen = wcslen( wsText );
|
||
int nDstLen = 0;
|
||
|
||
// Для начала рассчитаем длину выходной строки
|
||
for ( int nIndex = 0; nIndex < nSrcLen; nIndex++ )
|
||
{
|
||
int nCID = (int)wsText[nIndex];
|
||
if ( 0xFFFE == nCID )
|
||
nCID = 0;
|
||
|
||
int nUsedLen = 0;
|
||
char *sBuffer = new char[4];
|
||
CMapEncoderStreamGetCodeByCID( pEncoder, nCID, (char **)&sBuffer, &nUsedLen );
|
||
delete []sBuffer;
|
||
nDstLen += nUsedLen;
|
||
}
|
||
|
||
BYTE *pText = new BYTE[nDstLen + 1];
|
||
pText[nDstLen] = '\0';
|
||
|
||
for ( int nIndex = 0, nIndex2 = 0; nIndex < nSrcLen; nIndex++ )
|
||
{
|
||
int nCID = (int)wsText[nIndex];
|
||
if ( 0xFFFE == nCID )
|
||
nCID = 0;
|
||
|
||
int nUsedLen = 0;
|
||
char *sBuffer = new char [4];
|
||
CMapEncoderStreamGetCodeByCID( pEncoder, nCID, (char **)&sBuffer, &nUsedLen );
|
||
|
||
for ( int nCurIndex = 0; nCurIndex < nUsedLen; nCurIndex++ )
|
||
{
|
||
pText[nIndex2 + nCurIndex] = sBuffer[4 - nUsedLen + nCurIndex];
|
||
}
|
||
delete []sBuffer;
|
||
|
||
nIndex2 += nUsedLen;
|
||
}
|
||
|
||
unsigned int *pCIDs = new unsigned int[nSrcLen];
|
||
for ( int nIndex = 0; nIndex < nSrcLen; nIndex++ )
|
||
{
|
||
pCIDs[nIndex] = (unsigned int)wsText[nIndex];
|
||
}
|
||
|
||
unsigned long nRet = PageTextOut( m_pDocument->pCurPage, fXPos, fYPos, pText, nDstLen, pCIDs, nSrcLen );
|
||
|
||
delete []pCIDs;
|
||
delete []pText;
|
||
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(TextRect)(float fLeft, float fTop, float fRight, float fBottom, BSTR bsText, long nAlign, unsigned int *pnLen)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
unsigned long nRet = PageTextRect( m_pDocument->pCurPage, fLeft, fTop, fRight, fBottom, sText, (ETextAlignment)nAlign, pnLen, NULL, 0 );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetSlideShow)(long nType, float fDispTime, float fTransTime)
|
||
{
|
||
unsigned long nRet = PageSetSlideShow( m_pDocument->pCurPage, (ETransitionStyle)nType, fDispTime, fTransTime );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetTextWidth)(BSTR bsText, float *pfResult)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
*pfResult = PageTextWidth( m_pDocument->pCurPage, (BYTE *)sText, strlen(sText), NULL, 0 );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MeasureText)(BSTR bsText, float fWidth, BOOL bWordWrap, float *pfRealWidth, long *pnLength)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
BOOL bWW = ( bWordWrap == 0 ? FALSE : TRUE);
|
||
*pnLength = PageMeasureText( m_pDocument->pCurPage, sText, NULL, 0, fWidth, bWW, pfRealWidth );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(LoadT1FFromFile)( BSTR bsAFMFileName, BSTR bsDataFileName, BSTR *bsFontName)
|
||
{
|
||
CString sAFMFileName( bsAFMFileName );
|
||
CString sDataFileName( bsDataFileName );
|
||
|
||
wchar_t *wsData = sDataFileName.GetBuffer();
|
||
if ( sDataFileName.GetLength() <= 0 )
|
||
wsData = NULL;
|
||
|
||
// Чтобы не изменять интерфейс, при перезаписи PDF, храним тип шрифта в его расширении
|
||
short nType = 0;
|
||
if ( wsData )
|
||
{
|
||
wchar_t wsExtension[MAX_PATH];
|
||
_wsplitpath( wsData, NULL, NULL, NULL, wsExtension );
|
||
|
||
CStringW wsExt( wsExtension );
|
||
|
||
if ( _T(".pfb_t1cot") == wsExt )
|
||
nType = 2;
|
||
else if ( _T(".pfb_t1c") == wsExt )
|
||
nType = 1;
|
||
else
|
||
nType = 0;
|
||
}
|
||
|
||
const char* sFontName = LoadType1FontFromFile( m_pDocument, sAFMFileName.GetBuffer(), wsData, nType );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_FONT_EXISTS == nRet )
|
||
ResetError( m_pDocument );
|
||
else if ( OK != nRet )
|
||
{
|
||
(*bsFontName) = NULL;
|
||
return nRet;
|
||
}
|
||
|
||
|
||
CString sTemp(sFontName);
|
||
(*bsFontName) = sTemp.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadTTFFromFile)( BSTR bsFileName, BOOL bEmbedding, BSTR bsEncodingName, BSTR *bsFontName)
|
||
{
|
||
CString sFileName( bsFileName );
|
||
if ( !FileExist( sFileName ) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_FILE_OPEN_ERROR;
|
||
|
||
USES_CONVERSION;
|
||
const char* sEncodingName = ( NULL == bsEncodingName ? NULL : W2A( bsEncodingName ) );
|
||
if ( NULL != sEncodingName && strlen( sEncodingName ) < 1 )
|
||
sEncodingName = NULL;
|
||
|
||
BOOL bEmbed = ( bEmbedding == 0 ? FALSE : TRUE);
|
||
|
||
const char *sFontName = ( bsFontName == NULL ? LoadTTFontFromFile( m_pDocument, sFileName.GetBuffer(), bEmbed, sEncodingName ) : LoadTTFontFromFile( m_pDocument, sFileName.GetBuffer(), bEmbed, sEncodingName, "_Embedded" ) );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_FONT_EXISTS == nRet )
|
||
ResetError( m_pDocument );
|
||
else if ( OK != nRet )
|
||
{
|
||
(*bsFontName) = NULL;
|
||
|
||
return nRet;
|
||
}
|
||
|
||
CString sTemp(sFontName);
|
||
(*bsFontName) = sTemp.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadTTCFromFile)( BSTR bsFileName, long nIndex, BOOL bEmbedding, BSTR *bsFontName)
|
||
{
|
||
CString sFileName( bsFileName );
|
||
|
||
const char* sFontName = LoadTTFontFromFile2( m_pDocument, sFileName.GetBuffer(), (unsigned int)nIndex, bEmbedding );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
{
|
||
(*bsFontName) = NULL;
|
||
return nRet;
|
||
}
|
||
|
||
CString sTemp(sFontName);
|
||
(*bsFontName) = sTemp.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCurrentFont)( BSTR bsFontName, BSTR bsEncodingName, BOOL bNameIsUnicodeArray, BSTR bsToUnicodeName)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sFontName = W2A(bsFontName);
|
||
const char* sEncodingName = W2A(bsEncodingName);
|
||
const char* sToUnicodeName = W2A(bsToUnicodeName);
|
||
|
||
if ( UtilsStrLen( sEncodingName, LIMIT_MAX_NAME_LEN ) <= 0 )
|
||
sEncodingName = NULL;
|
||
|
||
if ( UtilsStrLen( sToUnicodeName, LIMIT_MAX_NAME_LEN ) <= 0 )
|
||
sToUnicodeName = NULL;
|
||
|
||
if ( !bNameIsUnicodeArray )
|
||
m_pCurrentFont = GetFont( m_pDocument, sFontName, sEncodingName, sToUnicodeName );
|
||
else
|
||
{
|
||
BOOL bNewEncoding;
|
||
Encoder pCurEncoder = FindEncoderForString( m_pDocument, bsEncodingName, &bNewEncoding );
|
||
|
||
m_pCurrentFont = GetFont( m_pDocument, sFontName, pCurEncoder->sName, sToUnicodeName );
|
||
|
||
//CStringW oArray = (CStringW)bsEncodingName;
|
||
//int nCount = oArray.GetLength();
|
||
//unsigned short *pUnicode = new unsigned short[nCount];
|
||
//for ( int nIndex = 0; nIndex < nCount; nIndex++ )
|
||
//{
|
||
// pUnicode[nIndex] = (unsigned short)oArray.GetAt(nIndex);
|
||
//}
|
||
//m_pCurrentFont = GetFont( m_pDocument, sFontName, sEncodingName, pUnicode, nCount );
|
||
//delete []pUnicode;
|
||
}
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentFont)( BSTR *pbsFontName, BSTR *pbsEncodingName )
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
{
|
||
*pbsFontName = NULL;
|
||
*pbsEncodingName = NULL;
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
}
|
||
else
|
||
{
|
||
CString sFontName(FontGetFontName( m_pCurrentFont ));
|
||
CString sEncodingName(((FontAttr)m_pCurrentFont->pAttr)->pEncoder->sName);
|
||
|
||
*pbsFontName = sFontName.AllocSysString();
|
||
*pbsEncodingName = sEncodingName.AllocSysString();
|
||
}
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontUnicodeWidth)(long nCode, long *pnUnicode)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
*pnUnicode = (long)FontGetUnicodeWidth( m_pCurrentFont, (unsigned int)nCode );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontBBox )(float *pfLeft, float *pfBottom, float *pfRight, float *pfTop)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
Box oBox = { 0, 0, 0, 0};
|
||
oBox = FontGetBBox( m_pCurrentFont );
|
||
*pfLeft = oBox.fLeft;
|
||
*pfBottom = oBox.fBottom;
|
||
*pfRight = oBox.fRight;
|
||
*pfTop = oBox.fTop;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontAscent )(long *pnAscent)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
|
||
*pnAscent = (long)FontGetAscent( m_pCurrentFont );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontDescent )(long *pnDescent)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
*pnDescent = (long)FontGetDescent( m_pCurrentFont );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontXHeight )(long *pnXHeight)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
*pnXHeight = (long)FontGetXHeight( m_pCurrentFont );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetFontCapHeight )(long *pnCapHeight)
|
||
{
|
||
if ( !m_pCurrentFont )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_FONT_NOT_FOUND;
|
||
*pnCapHeight = (long)FontGetCapHeight( m_pCurrentFont );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(SetCurrentEncoder)( BSTR bsEncodingName )
|
||
{
|
||
USES_CONVERSION;
|
||
const char *sEncodingName = W2A(bsEncodingName);
|
||
|
||
unsigned long nRet = DocSetCurrentEncoder( m_pDocument, sEncodingName);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetCurrentEncoder)( BSTR *pbsEncodingName )
|
||
{
|
||
Encoder pCurEncoder = DocGetCurrentEncoder( m_pDocument );
|
||
if ( !pCurEncoder )
|
||
*pbsEncodingName = NULL;
|
||
else
|
||
{
|
||
CString sEncodingName(pCurEncoder->sName);
|
||
|
||
*pbsEncodingName = sEncodingName.AllocSysString();
|
||
}
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetEncoderUnicode) (long nCode, long *pnUnicode)
|
||
{
|
||
Encoder pCurEncoder = DocGetCurrentEncoder( m_pDocument );
|
||
*pnUnicode = EncoderGetUnicode( pCurEncoder, nCode );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetEncoderByteType) (BSTR bsText, long nIndex, long *pnByteType)
|
||
{
|
||
USES_CONVERSION;
|
||
const char *sText = W2A(bsText);
|
||
Encoder pCurEncoder = DocGetCurrentEncoder( m_pDocument);
|
||
*pnByteType = (long)EncoderGetByteType( pCurEncoder, sText, nIndex );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetEncoderType) (long *pnEncoderType)
|
||
{
|
||
Encoder pCurEncoder = DocGetCurrentEncoder( m_pDocument);
|
||
*pnEncoderType = (long)EncoderGetType( pCurEncoder );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetEncoderWritingMode)(long *pnWritingMode)
|
||
{
|
||
Encoder pCurEncoder = DocGetCurrentEncoder( m_pDocument);
|
||
*pnWritingMode = (long)EncoderGetWritingMode( pCurEncoder );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------------------------------
|
||
STDMETHOD(CreateNewDestination)()
|
||
{
|
||
if ( !m_pDestList )
|
||
m_pDestList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
m_pCurrentDestination = PageCreateDestination( m_pDocument->pCurPage );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pDestList, m_pCurrentDestination ) ) )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetXYZ)(float fLeft, float fTop, float fZoom)
|
||
{
|
||
unsigned long nRet = DestinationSetXYZ( m_pCurrentDestination, fLeft, fTop, fZoom );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFit)()
|
||
{
|
||
unsigned long nRet = DestinationSetFit( m_pCurrentDestination );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitH)(float fTop)
|
||
{
|
||
unsigned long nRet = DestinationSetFitH( m_pCurrentDestination, fTop );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitV)(float fLeft)
|
||
{
|
||
unsigned long nRet = DestinationSetFitV( m_pCurrentDestination, fLeft );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitR) (float fLeft, float fBottom, float fRight, float fTop)
|
||
{
|
||
unsigned long nRet = DestinationSetFitR( m_pCurrentDestination, fLeft, fBottom, fRight, fTop );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitB)()
|
||
{
|
||
unsigned long nRet = DestinationSetFitB( m_pCurrentDestination );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitBH)(float fTop)
|
||
{
|
||
unsigned long nRet = DestinationSetFitBH( m_pCurrentDestination, fTop );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DestSetFitBV)(float fLeft)
|
||
{
|
||
unsigned long nRet = DestinationSetFitBV( m_pCurrentDestination, fLeft );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetCurrentDest)(long nIndex)
|
||
{
|
||
Destination pTemp = (Destination)ListItemAt( m_pDestList, nIndex );
|
||
m_pCurrentDestination = pTemp;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetCurrentDestIndex)(long *pnIndex)
|
||
{
|
||
if ( !m_pCurrentDestination || !m_pDestList )
|
||
{
|
||
*pnIndex = -1;
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_DESTINATION_NOT_FOUND;
|
||
}
|
||
else
|
||
*pnIndex = ListFind( m_pDestList, m_pCurrentDestination );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(CreateTextAnnot)(float fLeft, float fBottom, float fRight, float fTop, BSTR bsText, BSTR bsEncoder)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sText = W2A(bsText);
|
||
const char* sEncoder = W2A(bsEncoder);
|
||
|
||
Encoder pEncoder = NULL;
|
||
if ( UtilsStrLen( sEncoder, LIMIT_MAX_NAME_LEN ) > 0 )
|
||
pEncoder = GetEncoder( m_pDocument, sEncoder );
|
||
|
||
TRect oRect = { fLeft, fBottom, fRight, fTop};
|
||
|
||
if ( !m_pAnnotList )
|
||
m_pAnnotList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
m_pCurrentAnnotation = PageCreateTextAnnot( m_pDocument->pCurPage, oRect, sText, pEncoder);
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pAnnotList, m_pCurrentAnnotation) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CreateLinkAnnot)(float fLeft, float fBottom, float fRight, float fTop)
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
if ( !m_pAnnotList )
|
||
{
|
||
m_pAnnotList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
TRect oRect = { fLeft, fBottom, fRight, fTop};
|
||
if ( !m_pCurrentDestination )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_DESTINATION_NOT_FOUND;
|
||
|
||
m_pCurrentAnnotation = PageCreateLinkAnnot( m_pDocument->pCurPage, oRect, m_pCurrentDestination );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pAnnotList, m_pCurrentAnnotation) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CreateUriLinkAnnot)(float fLeft, float fBottom, float fRight, float fTop, BSTR bsUrl)
|
||
{
|
||
unsigned long nRet = OK;
|
||
if ( !m_pAnnotList )
|
||
{
|
||
m_pAnnotList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
USES_CONVERSION;
|
||
const char* sUrl = W2A(bsUrl);
|
||
TRect oRect = { fLeft, fBottom, fRight, fTop};
|
||
|
||
m_pCurrentAnnotation = PageCreateUriLinkAnnot( m_pDocument->pCurPage, oRect, sUrl );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pAnnotList, m_pCurrentAnnotation) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ArbAnnotationSetBorderStyle)(long nSubtype, float fWidth, long nDashOn, long nDashOff, long nDashPhase)
|
||
{
|
||
unsigned long nRet = AnnotationSetBorderStyle( m_pCurrentAnnotation, (BSSubtype)nSubtype, fWidth, (unsigned short)nDashOn, (unsigned short)nDashOff, (unsigned short)nDashPhase );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LinkAnnotationSetBorderStyle)(float fWidth, long nDashOn, long nDashOff )
|
||
{
|
||
unsigned long nRet = LinkAnnotSetBorderStyle( m_pCurrentAnnotation, fWidth, (unsigned short)nDashOn, (unsigned short)nDashOff );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LinkAnnotationSetHighlightMode)(long nMode)
|
||
{
|
||
unsigned long nRet = LinkAnnotSetHighlightMode( m_pCurrentAnnotation, (AnnotHighlightMode)nMode );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(TextAnnotationSetIcon)(long nIcon)
|
||
{
|
||
unsigned long nRet = TextAnnotSetIcon( m_pCurrentAnnotation, (AnnotIcon)nIcon );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(TextAnnotationSetOpened)(BOOL bOpened)
|
||
{
|
||
unsigned long nRet = TextAnnotSetOpened( m_pCurrentAnnotation, bOpened );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetCurrentAnnot)(long nIndex)
|
||
{
|
||
Annotation pTemp = (Annotation)ListItemAt( m_pAnnotList, nIndex );
|
||
m_pCurrentAnnotation = pTemp;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetCurrentAnnotIndex)(long *pnIndex)
|
||
{
|
||
if ( !m_pCurrentAnnotation || !m_pAnnotList )
|
||
{
|
||
*pnIndex = -1;
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_ANNOTATION_NOT_FOUND;
|
||
}
|
||
else
|
||
*pnIndex = ListFind( m_pAnnotList, m_pCurrentAnnotation );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MakeAnnotationFromXml)(BSTR bsXML)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
// Запоминаем текущую страницу
|
||
long nStartPageIndex = 0;
|
||
if ( FAILED( hRes = GetCurrentPageIndex( &nStartPageIndex ) ) )
|
||
return hRes;
|
||
|
||
// Считываем количество страниц (для контроля)
|
||
long nPagesCount = 0;
|
||
if ( FAILED( hRes = GetPagesCount( &nPagesCount ) ) )
|
||
return hRes;
|
||
|
||
float fPageHeight = 0;
|
||
float fPageWidth = 0;
|
||
|
||
if ( FAILED( hRes = GetWidth( &fPageWidth ) ) )
|
||
return hRes;
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
|
||
XmlUtils::CXmlNode oLinker;
|
||
oLinker.FromXmlString( CString( bsXML ) );
|
||
|
||
if ( -1 != oLinker.GetName().Find( _T("linker") ) )
|
||
{
|
||
XmlUtils::CXmlNodes oLinks;
|
||
oLinker.GetNodes( _T("link"), oLinks );
|
||
|
||
for ( int nIndex = 0; nIndex < oLinks.GetCount(); nIndex++ )
|
||
{
|
||
XmlUtils::CXmlNode oLink;
|
||
oLinks.GetAt( nIndex, oLink );
|
||
|
||
XmlUtils::CXmlNode oSource;
|
||
XmlUtils::CXmlNode oTarget;
|
||
|
||
float fSrcX = 0;
|
||
float fSrcY = 0;
|
||
float fSrcH = 0;
|
||
float fSrcW = 0;
|
||
int nSrcPageIndex = nStartPageIndex;
|
||
|
||
if ( oLink.GetNode( _T("source"), oSource ) )
|
||
{
|
||
CString sValue;
|
||
|
||
sValue = oSource.GetAttribute( _T("page"), _T("0") );
|
||
nSrcPageIndex = max( 0, min( nPagesCount - 1, _wtoi( sValue.GetBuffer() ) ) );
|
||
|
||
sValue = oSource.GetAttribute( _T("x"), _T("0") );
|
||
fSrcX = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oSource.GetAttribute( _T("y"), _T("0") );
|
||
fSrcY = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oSource.GetAttribute( _T("width"), _T("0") );
|
||
fSrcW = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oSource.GetAttribute( _T("height"), _T("0") );
|
||
fSrcH = (float)_wtof( sValue.GetBuffer() );
|
||
}
|
||
|
||
float fDstX = 0;
|
||
float fDstY = 0;
|
||
float fDstH = 0;
|
||
float fDstW = 0;
|
||
int nDstPageIndex = nStartPageIndex;
|
||
CString sURL = _T("");
|
||
BOOL bLinkURL = FALSE;
|
||
|
||
if ( oLink.GetNode( _T("target"), oTarget ) )
|
||
{
|
||
CString sValue;
|
||
|
||
sValue = oTarget.GetAttribute( _T("url"), _T("") );
|
||
if ( sValue.GetLength() > 0 )
|
||
{
|
||
sURL = sValue;
|
||
bLinkURL = TRUE;
|
||
}
|
||
else
|
||
{
|
||
sValue = oTarget.GetAttribute( _T("page"), _T("0") );
|
||
nDstPageIndex = max( 0, min( nPagesCount - 1, _wtoi( sValue.GetBuffer() ) ) );
|
||
|
||
sValue = oTarget.GetAttribute( _T("x"), _T("0") );
|
||
fDstX = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oTarget.GetAttribute( _T("y"), _T("0") );
|
||
fDstY = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oTarget.GetAttribute( _T("width"), _T("0") );
|
||
fDstW = (float)_wtof( sValue.GetBuffer() );
|
||
|
||
sValue = oTarget.GetAttribute( _T("height"), _T("0") );
|
||
fDstH = (float)_wtof( sValue.GetBuffer() );
|
||
}
|
||
}
|
||
|
||
if ( bLinkURL )
|
||
{
|
||
if ( FAILED( hRes = SetCurrentPage( nSrcPageIndex ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
BSTR bsURL = sURL.AllocSysString();
|
||
if ( FAILED( hRes = CreateUriLinkAnnot( fSrcX, fPageHeight - ( fSrcY + fSrcH ), fSrcX + fSrcW, fPageHeight - fSrcY, bsURL ) ) )
|
||
return hRes;
|
||
::SysFreeString( bsURL );
|
||
|
||
if ( FAILED( hRes = ArbAnnotationSetBorderStyle( 0, 0, 0, 0, 0 ) ) )
|
||
return hRes;
|
||
}
|
||
else
|
||
{
|
||
// Создаем объект Destination
|
||
if ( FAILED( hRes = SetCurrentPage( nDstPageIndex ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = CreateNewDestination() ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = DestSetXYZ( 0, fPageHeight - fDstY, 0 ) ) )
|
||
return hRes;
|
||
|
||
// Создаем ссылку на текущий объект Destionation
|
||
if ( FAILED( hRes = SetCurrentPage( nSrcPageIndex ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = CreateLinkAnnot( fSrcX, fPageHeight - ( fSrcY + fSrcH ), fSrcX + fSrcW, fPageHeight - fSrcY ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = ArbAnnotationSetBorderStyle( 0, 0, 0, 0, 0 ) ) )
|
||
return hRes;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// Восстанавливаем текущую страницу
|
||
if ( FAILED( hRes = SetCurrentPage( nStartPageIndex ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(CreateNewOutline)(long nParentIndex, BSTR bsTitle, BSTR bsEncoder)
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
USES_CONVERSION;
|
||
const char* sTitle = W2A(bsTitle);
|
||
const char* sEncoder = W2A(bsEncoder);
|
||
|
||
Encoder pEncoder = NULL;
|
||
if ( UtilsStrLen( sEncoder, LIMIT_MAX_NAME_LEN ) > 0 )
|
||
{
|
||
pEncoder = GetEncoder( m_pDocument, sEncoder );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
if ( !m_pOutlineList )
|
||
{
|
||
m_pOutlineList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
Outline pRoot = NULL;
|
||
if ( nParentIndex < m_pOutlineList->nCount && nParentIndex >= 0 )
|
||
{
|
||
pRoot = (Outline)ListItemAt( m_pOutlineList, nParentIndex );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
m_pCurrentOutline = CreateOutline( m_pDocument, pRoot, sTitle, pEncoder );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pOutlineList, m_pCurrentOutline ) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(OutlineSetCurrentDestination)()
|
||
{
|
||
unsigned long nRet = OutlineSetDestination( m_pCurrentOutline, m_pCurrentDestination );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetOutlineOpened)(BOOL bOpened)
|
||
{
|
||
unsigned long nRet = OutlineSetOpened( m_pCurrentOutline, bOpened );
|
||
if( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetCurrentOutline)(long nIndex)
|
||
{
|
||
Outline pTemp = (Outline)ListItemAt( m_pOutlineList, nIndex );
|
||
m_pCurrentOutline = pTemp;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetCurrentOutlineIndex)(long *pnIndex)
|
||
{
|
||
if ( !m_pCurrentOutline || !m_pOutlineList )
|
||
{
|
||
*pnIndex = -1;
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_OUTLINE_NOT_FOUND;
|
||
}
|
||
else
|
||
*pnIndex = ListFind( m_pOutlineList, m_pCurrentOutline );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(MakeOutlineFromXml)(BSTR bsXML)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
// текущая страница изменится, поэтому ее запоминаем и восстанавливаем
|
||
long nCurPageIndex = 0;
|
||
|
||
if ( FAILED ( hRes = GetCurrentPageIndex( &nCurPageIndex ) ) )
|
||
return hRes;
|
||
CString sXml(bsXML);
|
||
|
||
XmlUtils::CXmlReader oReader;
|
||
oReader.SetXmlString(sXml);
|
||
if ( -1 != oReader.ReadNodeName().Find( _T("PDF-Chapters") ) || -1 != oReader.ReadNodeName().Find( _T("Outline") ) )
|
||
if ( FAILED ( hRes = ReadOutlineChilds( oReader.ReadNodeXml(), -1 ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED ( hRes = SetCurrentPage( nCurPageIndex ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(LoadJpegFromFile)(BSTR bsFileName)
|
||
{
|
||
unsigned long nRet = OK;
|
||
CString sFileName( bsFileName );
|
||
|
||
if ( !m_pXObjectList )
|
||
{
|
||
m_pXObjectList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
m_pCurrentXObject = LoadJpegImageFromFile( m_pDocument, sFileName.GetBuffer() );
|
||
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pXObjectList, m_pCurrentXObject) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadJpxFromFile)(BSTR bsFileName, long nFlag)
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
CString sFileName( bsFileName );
|
||
|
||
if ( !m_pXObjectList )
|
||
{
|
||
m_pXObjectList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
// Параметр nFlag соответсвуют значению SMaskInData в записи о загружаемом Jpx
|
||
// nFlag: 0, даже если в Jpx есть прозрачность, игнорируем ее
|
||
// 1, наличие в Jpx SMask
|
||
// 2, наличие в Jpx отдельных каналов с прозрачностью
|
||
|
||
long nOpacityFlag = max( 0, min ( 2, nFlag ));
|
||
|
||
m_pCurrentXObject = LoadJpxImageFromFile( m_pDocument, sFileName.GetBuffer(), nOpacityFlag );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pXObjectList, m_pCurrentXObject) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadImageFromFile)(BSTR bsFileName, long nWidth, long nHeight, long nColorSpace)
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
CString sFileName( bsFileName );
|
||
|
||
if ( !m_pXObjectList )
|
||
{
|
||
m_pXObjectList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
m_pCurrentXObject = LoadRawImageFromFile( m_pDocument, sFileName.GetBuffer(), nWidth, nHeight, (ColorSpace)nColorSpace );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pXObjectList, m_pCurrentXObject) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadImageFromArray)(SAFEARRAY **ppImage, long nWidth, long nHeight, long nColorSpace, long nBitsPerComponent)
|
||
{
|
||
unsigned long nRet = OK;
|
||
|
||
BYTE *pArray;
|
||
if ( nHeight && nWidth )
|
||
{
|
||
// check for valid pixel array size
|
||
if ( 1 != SafeArrayGetDim(*ppImage) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
VARTYPE vType;
|
||
// check for valid array element type
|
||
if ( FAILED(SafeArrayGetVartype(*ppImage, &vType)) || VT_UI1 != vType )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
pArray = (BYTE*)(*ppImage)->pvData;
|
||
}
|
||
if ( !m_pXObjectList )
|
||
{
|
||
m_pXObjectList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
}
|
||
|
||
m_pCurrentXObject = LoadRawImageFromMem( m_pDocument, pArray, nWidth, nHeight, (ColorSpace)nColorSpace, nBitsPerComponent );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ListAdd( m_pXObjectList, m_pCurrentXObject) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadImageFromInterface)(IUnknown **pInterface, BOOL bAlpha = FALSE)
|
||
{
|
||
// check for valid input parameters
|
||
if (!pInterface || !*pInterface)
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
int nWidth = 0;
|
||
int nHeight = 0;
|
||
BYTE* pPixels = 0;
|
||
|
||
#ifdef BUILD_CONFIG_OPENSOURCE_VERSION
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
|
||
if ( NULL == pInterface || NULL == (*pInterface) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
(*pInterface)->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pMediaData));
|
||
if ( NULL == pMediaData )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
LONG lWidth = 0;
|
||
LONG lHeight = 0;
|
||
#else
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
|
||
if ( NULL == pInterface || NULL == (*pInterface) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaDataIn = NULL;
|
||
(*pInterface)->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pMediaDataIn));
|
||
if ( NULL == pMediaDataIn )
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
LONG lWidth = 0; pMediaDataIn->get_Width(&lWidth);
|
||
LONG lHeight = 0; pMediaDataIn->get_Height(&lHeight);
|
||
LONG lAspectX = 0; pMediaDataIn->get_AspectRatioX(&lAspectX);
|
||
LONG lAspectY = 0; pMediaDataIn->get_AspectRatioY(&lAspectY);
|
||
|
||
// преобразуем к BGR формату
|
||
if (TRUE)
|
||
{
|
||
MediaFormat::IAVSVideoFormat* pMediaFormat = NULL;
|
||
CoCreateInstance(MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL, MediaFormat::IID_IAVSVideoFormat, (void**)(&pMediaFormat));
|
||
if (NULL == pMediaFormat)
|
||
{
|
||
pMediaDataIn->Release();
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
}
|
||
|
||
MediaCore::IAVSVideoFrameTransform* pMediaTransform = NULL;
|
||
CoCreateInstance(MediaCore::CLSID_CAVSVideoFrameTransform, NULL, CLSCTX_ALL, MediaCore::IID_IAVSVideoFrameTransform, (void**)(&pMediaTransform));
|
||
if (NULL == pMediaTransform)
|
||
{
|
||
pMediaDataIn->Release();
|
||
pMediaFormat->Release();
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
}
|
||
|
||
pMediaFormat->SetDefaultProperties();
|
||
pMediaFormat->Width = lWidth;
|
||
pMediaFormat->Height = lHeight;
|
||
pMediaFormat->AspectRatioX = lAspectX;
|
||
pMediaFormat->AspectRatioY = lAspectY;
|
||
pMediaFormat->ColorSpace = 1<< 6;//CSP_BGRA
|
||
|
||
pMediaTransform->SetVideoFormat(pMediaFormat);
|
||
|
||
IUnknown *pTransformResult = NULL;
|
||
pMediaTransform->raw_TransformFrame(pMediaDataIn, &pTransformResult);
|
||
if (NULL != pTransformResult)
|
||
{
|
||
if ((*pInterface)==pTransformResult)
|
||
{
|
||
MediaCore::IAVSMediaData *pData = NULL;
|
||
pTransformResult->QueryInterface(MediaCore::IID_IAVSMediaData, (void**)(&pData));
|
||
if (NULL!=pData)
|
||
{
|
||
MediaCore::IAVSMediaData *pmdOutFrame = NULL;
|
||
pData->raw_CreateDuplicate(2, &pmdOutFrame);
|
||
pData->Release();
|
||
if (NULL!=pmdOutFrame)
|
||
{
|
||
pmdOutFrame->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pMediaData));
|
||
pmdOutFrame->Release();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
pTransformResult->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pMediaData));
|
||
}
|
||
pTransformResult->Release();
|
||
}
|
||
|
||
pMediaFormat->Release();
|
||
pMediaTransform->Release();
|
||
}
|
||
|
||
pMediaDataIn->Release();
|
||
#endif
|
||
|
||
if (NULL == pMediaData)
|
||
return AVS_OFFICEPDFWRITER_ERROR_INVALID_IMAGE;
|
||
|
||
//
|
||
|
||
lWidth = 0; pMediaData->get_Width(&lWidth);
|
||
lHeight = 0; pMediaData->get_Height(&lHeight);
|
||
LONG lColorSpace = 0; pMediaData->get_ColorSpace(&lColorSpace);
|
||
LONG lBufferSize = 0; pMediaData->get_BufferSize(&lBufferSize);
|
||
BYTE* pSourceBuffer = 0; pMediaData->get_Buffer(&pSourceBuffer);
|
||
|
||
BYTE* pImage = new BYTE[ lWidth * lHeight * 3];
|
||
BYTE* pAlpha = new BYTE[ lWidth * lHeight ];
|
||
BYTE* pImagePointer = pImage;
|
||
BYTE* pAlphaPointer = pAlpha;
|
||
BOOL bHaveAlpha = FALSE;
|
||
|
||
// Разделяем саму картинку и альфа-канал. Одновременно с этим, посчитаем количество цветов в картинке.
|
||
CSimpleArray<TRGBColor> arrColors;
|
||
for ( int nIndex = 0; nIndex < lWidth * lHeight; nIndex++, pImagePointer += 3, pSourceBuffer += 4, pAlphaPointer++ )
|
||
{
|
||
pImagePointer[ 0 ] = pSourceBuffer[ 2 ];
|
||
pImagePointer[ 1 ] = pSourceBuffer[ 1 ];
|
||
pImagePointer[ 2 ] = pSourceBuffer[ 0 ];
|
||
|
||
// Картинки с количеством цветом > 256 считаем полноцветными. (формат RGB)
|
||
if ( arrColors.GetSize() <= 256 )
|
||
{
|
||
TRGBColor oColor;
|
||
oColor.r = pImagePointer[ 0 ];
|
||
oColor.g = pImagePointer[ 1 ];
|
||
oColor.b = pImagePointer[ 2 ];
|
||
if ( -1 == arrColors.Find( oColor ) )
|
||
arrColors.Add( oColor );
|
||
}
|
||
|
||
pAlphaPointer[ 0 ] = pSourceBuffer[ 3 ];
|
||
if ( 255 != pAlphaPointer[0] )
|
||
bHaveAlpha = TRUE;
|
||
}
|
||
pMediaData->Release();
|
||
|
||
TRGBColor oBlack = { 0, 0, 0 };
|
||
TRGBColor oWhite = { 255, 255, 255 };
|
||
|
||
BOOL bBnW = FALSE; // Черно-белая картинка
|
||
if ( ( ( arrColors.GetSize() == 2 && ( ( arrColors.GetData()[0] == oBlack && arrColors.GetData()[1] == oWhite ) || ( arrColors.GetData()[1] == oBlack && arrColors.GetData()[0] == oWhite ) ) ) ||
|
||
( arrColors.GetSize() == 1 && ( arrColors.GetData()[0] == oBlack || arrColors.GetData()[1] == oWhite ) ) ) && !bHaveAlpha )
|
||
bBnW = TRUE;
|
||
|
||
unsigned long nRet = OK;
|
||
if ( !m_pXObjectList )
|
||
{
|
||
m_pXObjectList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
{
|
||
delete[] pAlpha;
|
||
delete[] pImage;
|
||
return nRet;
|
||
}
|
||
}
|
||
|
||
// Проверим нужен ли нам альфа-канал
|
||
if ( bAlpha )
|
||
{
|
||
bool bFakeAlpha = true;
|
||
for ( int nIndex = 0; nIndex < lWidth * lHeight; nIndex++ )
|
||
{
|
||
if ( 255 != pAlpha[nIndex] )
|
||
{
|
||
bFakeAlpha = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( bFakeAlpha )
|
||
bAlpha = FALSE;
|
||
}
|
||
|
||
// Проверяем, возможно, такая картинка уже есть в нашем файле
|
||
XObject pOldImage = NULL;
|
||
|
||
CRC32 oCRC;
|
||
oCRC.ProcessCRC( pImage, lWidth * lHeight * 3 );
|
||
unsigned int unImageCheckSum = oCRC.m_nCRC32;
|
||
oCRC.Init();
|
||
oCRC.ProcessCRC( pAlpha, lWidth * lHeight );
|
||
unsigned int unAlphaCheckSum = oCRC.m_nCRC32;
|
||
|
||
for ( int nIndex = 0; nIndex < m_pXObjectList->nCount; ++nIndex )
|
||
{
|
||
XObject pCurImage = (XObject)ListItemAt( m_pXObjectList, nIndex );
|
||
if ( !ImageValidate( pCurImage ) )
|
||
continue;
|
||
|
||
unsigned int unHeight = ImageGetHeight( pCurImage );
|
||
unsigned int unWidth = ImageGetWidth( pCurImage );
|
||
unsigned int unBPC = ImageGetBitsPerComponent( pCurImage );
|
||
EColorSpace eCS = ImageGetColorSpace2( pCurImage );
|
||
|
||
if ( unHeight != lHeight || unWidth != lWidth || CSDeviceRGB != eCS || 8 != unBPC )
|
||
continue;
|
||
|
||
if ( !StreamValidate( pCurImage->pStream ) )
|
||
continue;
|
||
|
||
//unsigned int unSize = StreamSize( pCurImage->pStream );
|
||
//if ( unSize != lWidth * lHeight * 3 )
|
||
// continue;
|
||
|
||
if ( bAlpha && pAlpha )
|
||
{
|
||
XObject pSMask = ImageGetSMask( pCurImage );
|
||
|
||
if ( !ImageValidate( pSMask ) )
|
||
continue;
|
||
|
||
unsigned int unMaskHeight = ImageGetHeight( pSMask );
|
||
unsigned int unMaskWidth = ImageGetWidth( pSMask );
|
||
unsigned int unMaskBPC = ImageGetBitsPerComponent( pSMask );
|
||
EColorSpace eMaskCS = ImageGetColorSpace2( pSMask );
|
||
|
||
if ( unMaskHeight != lHeight || unMaskWidth != lWidth || CSDeviceGray != eMaskCS || 8 != unMaskBPC )
|
||
continue;
|
||
|
||
if ( !StreamValidate( pSMask->pStream ) )
|
||
continue;
|
||
|
||
//unsigned int unMaskSize = StreamSize( pSMask->pStream );
|
||
//if ( unMaskSize != lWidth * lHeight )
|
||
// continue;
|
||
|
||
if ( unAlphaCheckSum != pSMask->pStream->nCheckSum )
|
||
continue;
|
||
|
||
//BYTE *pAlphaBuffer = new BYTE[unMaskSize];
|
||
//StreamRead( pSMask->pStream, pAlphaBuffer, &unMaskSize );
|
||
//StreamSeek( pSMask->pStream, 0, SeekSet );
|
||
|
||
|
||
//if ( 0 != ::memcmp( pAlphaBuffer, pAlpha, unMaskSize ) )
|
||
//{
|
||
// delete []pAlphaBuffer;
|
||
// continue;
|
||
//}
|
||
|
||
//delete []pAlphaBuffer;
|
||
|
||
|
||
}
|
||
|
||
if ( unImageCheckSum != pCurImage->pStream->nCheckSum )
|
||
continue;
|
||
|
||
//BYTE *pBuffer = new BYTE[unSize];
|
||
//StreamRead( pCurImage->pStream, pBuffer, &unSize );
|
||
//StreamSeek( pCurImage->pStream, 0, SeekSet );
|
||
|
||
|
||
//if ( 0 != ::memcmp( pBuffer, pImage, unSize ) )
|
||
//{
|
||
// delete []pBuffer;
|
||
// continue;
|
||
//}
|
||
|
||
//delete []pBuffer;
|
||
|
||
// Если мы дошли до этого места, значит картинки полностью совпадают и нет смысла загружать картинку заново
|
||
|
||
pOldImage = pCurImage;
|
||
break;
|
||
}
|
||
|
||
|
||
//
|
||
if ( pOldImage )
|
||
m_pCurrentXObject = pOldImage;
|
||
else if ( bBnW )
|
||
m_pCurrentXObject = LoadJbig2ImageFromInt( m_pDocument, pInterface, lWidth, lHeight, unImageCheckSum, bAlpha, pAlpha, unAlphaCheckSum);
|
||
else
|
||
{
|
||
//m_pCurrentXObject = LoadRawImageFromMem ( m_pDocument, pImage, lWidth, lHeight, CSDeviceRGB, 8, bAlpha, pAlpha );
|
||
m_pCurrentXObject = LoadJpegImageFromMem( m_pDocument, pImage, lWidth, lHeight, unImageCheckSum, bAlpha, pAlpha, unAlphaCheckSum );
|
||
//m_pCurrentXObject = LoadJpxImageFromMem ( m_pDocument, pImage, lWidth, lHeight, unImageCheckSum, bAlpha, pAlpha, unAlphaCheckSum );
|
||
}
|
||
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
{
|
||
delete[] pAlpha;
|
||
delete[] pImage;
|
||
return nRet;
|
||
}
|
||
|
||
if ( !pOldImage )
|
||
{
|
||
if ( OK != ( nRet = ListAdd( m_pXObjectList, m_pCurrentXObject) ) )
|
||
{
|
||
delete[] pAlpha;
|
||
delete[] pImage;
|
||
return nRet;
|
||
}
|
||
}
|
||
|
||
delete[] pAlpha;
|
||
delete[]pImage;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DrawCurrentImage)(float fX, float fY, float fWidth, float fHeight)
|
||
{
|
||
if ( !m_pCurrentXObject )
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_IMAGE_NOT_FOUND;
|
||
unsigned long nRet = PageDrawImage( m_pDocument->pCurPage, m_pCurrentXObject, fX, fY, fWidth, fHeight );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetImageBitsPerComponent)(long *pnBitsPerComponent)
|
||
{
|
||
*pnBitsPerComponent = ImageGetBitsPerComponent( m_pCurrentXObject );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetImageColorSpace)(long *pnColorSpace)
|
||
{
|
||
EColorSpace eCS = ImageGetColorSpace2( m_pCurrentXObject );
|
||
*pnColorSpace = (long)eCS;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetImageHeight)(long *pnHeight)
|
||
{
|
||
*pnHeight = ImageGetHeight( m_pCurrentXObject );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetImageWidth)(long *pnWidth)
|
||
{
|
||
*pnWidth = ImageGetWidth( m_pCurrentXObject );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetImageColorMask)(long nRMin, long nRMax, long nGMin, long nGMax, long nBMin, long nBMax)
|
||
{
|
||
unsigned long nRet = ImageSetColorMask( m_pCurrentXObject, nRMin, nRMax, nGMin, nGMax, nBMin, nBMax );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetImageMaskImage)(long nMaskImageIndex)
|
||
{
|
||
unsigned long nRet = OK;
|
||
XObject pTemp = (XObject)ListItemAt( m_pXObjectList, nMaskImageIndex );
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
return nRet;
|
||
|
||
if ( OK != ( nRet = ImageSetMaskImage( m_pCurrentXObject, pTemp ) ) )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCurrentImage)(long nIndex)
|
||
{
|
||
XObject pTemp = (XObject)ListItemAt( m_pXObjectList, nIndex );
|
||
m_pCurrentXObject = pTemp;
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetCurrentImageIndex)(long *pnIndex)
|
||
{
|
||
if ( !m_pCurrentXObject || !m_pXObjectList )
|
||
{
|
||
*pnIndex = -1;
|
||
return AVS_OFFICEPDFWRITER_ERROR_CURRENT_IMAGE_NOT_FOUND;
|
||
}
|
||
else
|
||
*pnIndex = ListFind( m_pXObjectList, m_pCurrentXObject );
|
||
|
||
// проверяем не появилась ли ошибка
|
||
unsigned long nRet = ErrorGetCode( &m_pDocument->oError );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(SetEncryptOn)()
|
||
{
|
||
unsigned long nRet = DocSetEncryptOn( m_pDocument );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFPassword)(BSTR bsOwnerPassword, BSTR bsUserPassword)
|
||
{
|
||
USES_CONVERSION;
|
||
const char* sOwnerPassword = W2A( bsOwnerPassword );
|
||
const char* sUserPassword = W2A( bsUserPassword );
|
||
|
||
if ( UtilsStrLen(sOwnerPassword, LIMIT_MAX_NAME_LEN ) <= 0 )
|
||
sOwnerPassword = NULL;
|
||
|
||
if ( UtilsStrLen(sUserPassword, LIMIT_MAX_NAME_LEN ) <= 0 )
|
||
sUserPassword = NULL;
|
||
|
||
// Паролей нет, ничего не делаем
|
||
if ( NULL == sOwnerPassword && NULL == sUserPassword )
|
||
return S_OK;
|
||
|
||
// Если пароли одинаковые, тогда устанавливаем только пользовательский пароль
|
||
if ( sOwnerPassword && sUserPassword && 0 == UtilsStrCmp( sOwnerPassword, sUserPassword ) )
|
||
sUserPassword = NULL;
|
||
|
||
unsigned long nRet = SetPassword( m_pDocument, sOwnerPassword, sUserPassword );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFPermission)(long nPermission)
|
||
{
|
||
unsigned long nRet = SetPermission( m_pDocument, (unsigned long)nPermission);
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetPDFEncryptionMode)(long nMode, long nKeyLen)
|
||
{
|
||
unsigned long nRet = SetEncryptionMode( m_pDocument, (EEncryptMode)nMode, nKeyLen );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetEncryptOff)()
|
||
{
|
||
unsigned long nRet = DocSetEncryptOff( m_pDocument );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(GetInfoItem)(long nDataType, BSTR *pbsItem)
|
||
{
|
||
unsigned long nRet = OK;
|
||
const char* sItem = GetInfoAttr( m_pDocument, (InfoType)nDataType);
|
||
if ( OK != ( nRet = ErrorGetCode( &m_pDocument->oError ) ) )
|
||
{
|
||
*pbsItem = NULL;
|
||
return nRet;
|
||
}
|
||
|
||
CString sTemp(sItem);
|
||
*pbsItem = sTemp.AllocSysString();
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetInfoItem)(long nDataType, BSTR bsData)
|
||
{
|
||
USES_CONVERSION;
|
||
const char *sData = W2A(bsData);
|
||
unsigned long nRet = SetInfoAttr( m_pDocument, (InfoType)nDataType, sData );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetInfoDateItem)(long nType, long nYear, long nMonth, long nDay, long nHour, long nMinutes, long nSeconds, long nInd, long nOffHour, long nOffMinutes)
|
||
{
|
||
TDate oDate;
|
||
oDate.nYear = nYear;
|
||
oDate.nMinutes = nMinutes;
|
||
oDate.nMonth = nMonth;
|
||
oDate.nDay = nDay;
|
||
oDate.nHour = nHour;
|
||
oDate.nSeconds = nSeconds;
|
||
oDate.nInd = nInd;
|
||
oDate.nOffHour = nOffHour;
|
||
oDate.nOffMinutes = nOffMinutes;
|
||
|
||
unsigned long nRet = SetInfoDateAttr( m_pDocument, (InfoType)nType, oDate );
|
||
if ( OK != nRet )
|
||
return nRet;
|
||
|
||
return S_OK;
|
||
}
|
||
//------------------------------------------------------------------------------------------------
|
||
STDMETHOD(SetAdditionalParam)(BSTR ParamName, VARIANT ParamValue)
|
||
{
|
||
CString sParamName; sParamName = ParamName;
|
||
|
||
if ( _T("TempDirectory") == sParamName && VT_BSTR == ParamValue.vt )
|
||
{
|
||
m_wsTempDir = CString( ParamValue.bstrVal );
|
||
DocSetTempDir( m_pDocument, m_wsTempDir.GetBuffer() );
|
||
}
|
||
else if ( _T("WhiteBackImage") == sParamName && VT_BOOL == ParamValue.vt )
|
||
{
|
||
m_bIsWhiteBackImage = (ParamValue.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
|
||
}
|
||
else if ( _T("BaseTransform") == sParamName && VT_ARRAY == ParamValue.vt )
|
||
{
|
||
// check for valid pixel array size
|
||
if ( 1 != SafeArrayGetDim(*ParamValue.pparray) )
|
||
return S_FALSE;
|
||
|
||
VARTYPE vType;
|
||
// check for valid array element type
|
||
if ( FAILED(SafeArrayGetVartype(*ParamValue.pparray, &vType)) || VT_R8 != vType )
|
||
return S_FALSE;
|
||
|
||
double* pTemp = (double*)(*ParamValue.pparray)->pvData;
|
||
m_oBaseTransform.fA = pTemp[0]; m_oBaseTransform.fB = pTemp[1];
|
||
m_oBaseTransform.fC = pTemp[2]; m_oBaseTransform.fD = pTemp[3];
|
||
m_oBaseTransform.fE = pTemp[4]; m_oBaseTransform.fF = pTemp[5];
|
||
}
|
||
else if ( _T("BrushFillBoundsEnable") == sParamName && VT_BOOL == ParamValue.vt )
|
||
{
|
||
m_bUseTextureRect = (ParamValue.boolVal == VARIANT_TRUE) ? TRUE : FALSE;
|
||
}
|
||
// NOTE: пока градиенты выставим в виде svg-xml
|
||
// TODO: потом убрать
|
||
else if (_T("Fill-LinearGradient") == sParamName && VT_BSTR == ParamValue.vt)
|
||
{
|
||
if (!CreateLinearGradientFromSvgXml(CString(ParamValue.bstrVal), TRUE))
|
||
return S_FALSE;
|
||
}
|
||
// NOTE: пока градиенты выставим в виде svg-xml
|
||
// TODO: потом убрать
|
||
else if (_T("Stroke-LinearGradient") == sParamName && VT_BSTR == ParamValue.vt)
|
||
{
|
||
if (!CreateLinearGradientFromSvgXml(CString(ParamValue.bstrVal), FALSE))
|
||
return S_FALSE;
|
||
}
|
||
// NOTE: пока градиенты выставим в виде svg-xml
|
||
// TODO: потом убрать
|
||
else if (_T("Fill-RadialGradient") == sParamName && VT_BSTR == ParamValue.vt)
|
||
{
|
||
if (!CreateRadialGradientFromSvgXml(CString(ParamValue.bstrVal), TRUE))
|
||
return S_FALSE;
|
||
}
|
||
// NOTE: пока градиенты выставим в виде svg-xml
|
||
// TODO: потом убрать
|
||
else if (_T("Stroke-RadialGradient") == sParamName && VT_BSTR == ParamValue.vt)
|
||
{
|
||
if (!CreateRadialGradientFromSvgXml(CString(ParamValue.bstrVal), FALSE))
|
||
return S_FALSE;
|
||
}
|
||
else if (_T("InitializeFromFolder") == sParamName && VT_BSTR == ParamValue.vt)
|
||
{
|
||
if (NULL != m_pFontManager)
|
||
{
|
||
m_pFontManager->SetAdditionalParam(ParamName, ParamValue);
|
||
m_bIsFontsInitialize = TRUE;
|
||
}
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetAdditionalParam)(BSTR ParamName, VARIANT * ParamValue)
|
||
{
|
||
return S_OK;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------------------------------
|
||
//
|
||
// Интерфейс IAVSOfficeRendererTemplate (IPDFRenderer) IAVSRenderer
|
||
//
|
||
//-----------------------------------------------------------------------------------------------------
|
||
//-------- Тип рендерера--------------------------------------------------------------------------
|
||
STDMETHOD(get_Type)(LONG *plType)
|
||
{
|
||
if ( !plType )
|
||
return S_FALSE;
|
||
|
||
*plType = c_nPDFWriter;
|
||
|
||
return S_OK;
|
||
}
|
||
//-------- Функции для работы со страницей -------------------------------------------------------
|
||
STDMETHOD(NewPage)()
|
||
{
|
||
m_bStartSubPath = FALSE;
|
||
m_bGStateChange = FALSE;
|
||
m_bClipPath = FALSE;
|
||
|
||
m_dCharSpace = 0.0;
|
||
|
||
m_oClipCTM.Set( 1, 0, 0, 1, 0, 0 );
|
||
m_oBaseTransform.Set( 1, 0, 0, 1, 0, 0 );
|
||
|
||
m_oPen.SetDefaultParams();
|
||
m_oFont.SetDefaultParams();
|
||
m_oBrush.SetDefaultParams();
|
||
m_oShadow.SetDefaultParams();
|
||
m_oEdgeText.SetDefaultParams();
|
||
|
||
m_oTransform.Reset();
|
||
// Заканчиваем последнее состояние
|
||
SetState( rendstateNone );
|
||
// Сбрасываем состояние
|
||
m_oRendererState.Reset();
|
||
|
||
m_bFirstMoveTo = TRUE;
|
||
|
||
m_oContiniousText.Reset();
|
||
|
||
return AddNewPage();
|
||
}
|
||
STDMETHOD(put_Height)(double dHeight)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
dHeight = MMToPDFCoords( dHeight );
|
||
|
||
if ( FAILED( hRes = SetPageHeight( (float)dHeight ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_Height)(double *pdHeight)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
float fHeight = 0;
|
||
if ( FAILED( hRes = GetHeight( &fHeight ) ) )
|
||
return hRes;
|
||
|
||
*pdHeight = PDFCoordsToMM( (double)fHeight );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_Width)(double dWidth)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
dWidth = MMToPDFCoords( dWidth );
|
||
|
||
if ( FAILED( hRes = SetPageWidth( (float)dWidth ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_Width)(double *pdWidth)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
float fWidth = 0;
|
||
|
||
if ( FAILED( hRes = GetWidth( &fWidth ) ) )
|
||
return hRes;
|
||
|
||
*pdWidth = PDFCoordsToMM( (double)fWidth );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_DpiX)(double *pdDpiX)
|
||
{
|
||
*pdDpiX = 72.0;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_DpiY)(double *pdDpiY)
|
||
{
|
||
*pdDpiY = 72.0;
|
||
|
||
return S_OK;
|
||
}
|
||
//-------- Функции для работы с Pen --------------------------------------------------------------
|
||
STDMETHOD(SetPen)(BSTR bsXML)
|
||
{
|
||
CString strXML( bsXML );
|
||
m_oPen.FromXmlString( strXML );
|
||
m_bGStateChange = TRUE;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenColor)(LONG *plColor)
|
||
{
|
||
*plColor = m_oPen.Color;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenColor)(LONG lColor)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.Color = lColor;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenAlpha)(LONG *plAlpha)
|
||
{
|
||
*plAlpha = m_oPen.Alpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenAlpha)(LONG lAlpha)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.Alpha = lAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenSize)(double *pdSize)
|
||
{
|
||
*pdSize = m_oPen.Size;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenSize)(double dSize)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.Size = dSize;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenDashStyle)(BYTE *pnStyle)
|
||
{
|
||
*pnStyle = m_oPen.DashStyle;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenDashStyle)(BYTE nStyle)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.DashStyle = nStyle;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenLineStartCap)(BYTE *pnStartCap)
|
||
{
|
||
*pnStartCap = m_oPen.LineStartCap;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenLineStartCap)(BYTE nStartCap)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.LineStartCap = nStartCap;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenLineEndCap)(BYTE *pnEndCap)
|
||
{
|
||
*pnEndCap = m_oPen.LineEndCap;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenLineEndCap)(BYTE nEndCap)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.LineEndCap = nEndCap;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenLineJoin)(BYTE *pnJointStyle)
|
||
{
|
||
*pnJointStyle = m_oPen.LineJoin;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenLineJoin)(BYTE nJointStyle)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.LineJoin = nJointStyle;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenDashOffset)(double *pdOffset)
|
||
{
|
||
*pdOffset = m_oPen.DashOffset;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenDashOffset)(double dOffset)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.DashOffset = dOffset;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenAlign)(LONG *plAlign)
|
||
{
|
||
*plAlign = m_oPen.Align;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenAlign)(LONG lAlign)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.Align = lAlign;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_PenMiterLimit)(double *pdMiterLimit)
|
||
{
|
||
*pdMiterLimit = m_oPen.MiterLimit;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_PenMiterLimit)(double dMiterLimit)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.MiterLimit = dMiterLimit;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PenDashPattern)(SAFEARRAY* pPattern)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oPen.SetDashPattern( (double*)pPattern->pvData, pPattern->rgsabound[0].cElements );
|
||
|
||
return S_OK;
|
||
}
|
||
//-------- Функции для работы с Brush ------------------------------------------------------------
|
||
STDMETHOD(SetBrush)(BSTR bsXML)
|
||
{
|
||
CString strXML( bsXML );
|
||
m_oBrush.FromXmlString( strXML );
|
||
m_bGStateChange = TRUE;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushType)(LONG *plType)
|
||
{
|
||
*plType = m_oBrush.Type;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushType)(LONG lType)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.Type = lType;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushColor1)(LONG *plColor)
|
||
{
|
||
*plColor = m_oBrush.Color1;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushColor1)(LONG lColor)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.Color1 = lColor;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushAlpha1)(LONG *plAlpha)
|
||
{
|
||
*plAlpha = m_oBrush.Alpha1;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushAlpha1)(LONG lAlpha)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.Alpha1 = lAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushColor2)(LONG *plColor)
|
||
{
|
||
*plColor = m_oBrush.Color2;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushColor2)(LONG lColor)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.Color2 = lColor;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushAlpha2)(LONG *plAlpha)
|
||
{
|
||
*plAlpha = m_oBrush.Alpha2;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushAlpha2)(LONG lAlpha)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.Alpha2 = lAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushTexturePath)(BSTR *pbsPath)
|
||
{
|
||
*pbsPath = m_oBrush.TexturePath.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushTexturePath)(BSTR bsPath)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.TexturePath = CString(bsPath);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushTextureMode)(LONG *plMode)
|
||
{
|
||
*plMode = m_oBrush.TextureMode;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushTextureMode)(LONG lMode)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.TextureMode = lMode;
|
||
|
||
if (c_BrushTextureModeTile == m_oBrush.TextureMode)
|
||
m_oPatternState.SetTileMode(TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushTextureAlpha)(LONG *plTxAlpha)
|
||
{
|
||
*plTxAlpha = m_oBrush.TextureAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushTextureAlpha)(LONG lTxAlpha)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.TextureAlpha = lTxAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_BrushLinearAngle)(double *pdAngle)
|
||
{
|
||
*pdAngle = m_oBrush.LinearAngle;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_BrushLinearAngle)(double dAngle)
|
||
{
|
||
m_bGStateChange = TRUE;
|
||
m_oBrush.LinearAngle = dAngle;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(BrushRect)(BOOL bVal, double dLeft, double dTop, double dWidth, double dHeight)
|
||
{
|
||
m_oBrush.Rectable = bVal;
|
||
m_oBrush.Rect.X = (float)dLeft;
|
||
m_oBrush.Rect.Y = (float)dTop;
|
||
m_oBrush.Rect.Width = (float)dWidth;
|
||
m_oBrush.Rect.Height = (float)dHeight;
|
||
|
||
return S_OK;
|
||
}
|
||
//-------- Функции для работы с Шрифтом ----------------------------------------------------------
|
||
STDMETHOD(SetFont)(BSTR bsXML)
|
||
{
|
||
CString strXML( bsXML );
|
||
m_oFont.FromXmlString( strXML );
|
||
|
||
//if ( m_bCurFontGIDString && !m_bEncoderGID )
|
||
//{
|
||
// BOOL bNew = FALSE;
|
||
|
||
// wchar_t wsString[255];
|
||
// for ( int nCode = 1; nCode < 256; nCode++ )
|
||
// {
|
||
// wsString[nCode - 1] = nCode;
|
||
// }
|
||
// FindEncoderForString( m_pDocument, (BSTR)wsString ,&bNew);
|
||
//}
|
||
//unsigned long unRes = GdiFontToPdfFont(/*L""*/(CStringW(L"qwertyuiop[]';lkjhgfdsazxcvbnm,./QWERTYUIOP{}\":LKJHGFDSAZXCVBNM<>?ЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮ,.юбьтимсчяфывапролджэъхзщшгнекуцйЁё1234567890-=+_)(*?:%;№!qwertyuiop[]';lkjhgfdsazxcvbnm,./QWERTYUIOP{}\":LKJHGFDSAZXCVBNM<>?ЙЦУКЕНГ ")).AllocSysString(), TRUE);
|
||
//if ( S_OK != unRes )
|
||
// return unRes;
|
||
|
||
//if ( !m_pFontEncodingList )
|
||
// m_pFontEncodingList = ListNew( m_pDocument->oMMgr, DEF_ITEMS_PER_BLOCK );
|
||
|
||
//TFontEncodingPair *pPair = new TFontEncodingPair;
|
||
//const char *sPdfFontName = FontGetFontName( m_pCurrentFont );
|
||
//const char *sRealFontName = FontGetFontName( m_pCurrentFont, TRUE );
|
||
//const char *sEncodingName = FontGetEncodingName( m_pCurrentFont );
|
||
|
||
//UtilsMemCpy( (BYTE *)pPair->sPdfFontName, (BYTE *)sPdfFontName, LIMIT_MAX_NAME_LEN + 1 );
|
||
//UtilsMemCpy( (BYTE *)pPair->sRealFontName, (BYTE *)sRealFontName, LIMIT_MAX_NAME_LEN + 1 );
|
||
//UtilsMemCpy( (BYTE *)pPair->sEncodingName, (BYTE *)sEncodingName, LIMIT_MAX_NAME_LEN + 1 );
|
||
|
||
//ListAdd( m_pFontEncodingList, pPair );
|
||
|
||
return S_OK;
|
||
|
||
}
|
||
STDMETHOD(get_FontName)(BSTR *pbsName)
|
||
{
|
||
*pbsName = m_oFont.Name.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontName)(BSTR bsName)
|
||
{
|
||
m_oFont.Name = CString( bsName );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_FontPath)(BSTR *pbsPath)
|
||
{
|
||
*pbsPath = m_oFont.Path.AllocSysString();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontPath)(BSTR bsName)
|
||
{
|
||
m_oFont.Path = CString( bsName );
|
||
m_oFont.Path.Replace(_T("\\\\"), _T("\\") );
|
||
m_oFont.Path.Replace(_T("\\\\"), _T("\\") );
|
||
|
||
m_oFont.Path.Replace(_T("//"), _T("/") );
|
||
m_oFont.Path.Replace(_T("//"), _T("/") );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_FontSize)(double *pdSize)
|
||
{
|
||
*pdSize = m_oFont.Size;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontSize)(double dSize)
|
||
{
|
||
m_oFont.Size = dSize;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_FontStyle)(LONG *plStyle)
|
||
{
|
||
*plStyle = m_oFont.GetStyle();
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontStyle)(LONG lStyle)
|
||
{
|
||
m_oFont.SetStyle( lStyle );
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_FontStringGID)(BOOL *pbGID)
|
||
{
|
||
*pbGID = m_oFont.StringGID;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontStringGID)(BOOL bGID)
|
||
{
|
||
m_oFont.StringGID = bGID;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_FontCharSpace)(double *pdSpace)
|
||
{
|
||
if ( !pdSpace )
|
||
return S_FALSE;
|
||
|
||
*pdSpace = PDFCoordsToMM( m_dCharSpace );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_FontCharSpace)(double dSpace)
|
||
{
|
||
m_dCharSpace = MMToPDFCoords( dSpace );
|
||
return S_OK;
|
||
}
|
||
|
||
//-------- Функции для работы с Shadow -----------------------------------------------------------
|
||
STDMETHOD(SetShadow)(BSTR bsXML)
|
||
{
|
||
CString strXML( bsXML );
|
||
m_oShadow.FromXmlString( strXML );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowDistanceX)(double *pdX)
|
||
{
|
||
*pdX = m_oShadow.DistanceX;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowDistanceX)(double dX)
|
||
{
|
||
m_oShadow.DistanceX = dX;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowDistanceY)(double *pdY)
|
||
{
|
||
*pdY = m_oShadow.DistanceY;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowDistanceY)(double dY)
|
||
{
|
||
m_oShadow.DistanceY = dY;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowBlurSize)(double *pdSize)
|
||
{
|
||
*pdSize = m_oShadow.BlurSize;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowBlurSize)(double dSize)
|
||
{
|
||
m_oShadow.BlurSize = dSize;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowColor)(LONG *plColor)
|
||
{
|
||
*plColor = m_oShadow.Color;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowColor)(LONG lColor)
|
||
{
|
||
m_oShadow.Color = lColor;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowAlpha)(LONG *plAlpha)
|
||
{
|
||
*plAlpha = m_oShadow.Alpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowAlpha)(LONG lAlpha)
|
||
{
|
||
m_oShadow.Alpha = lAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_ShadowVisible)(BOOL *pbVisible)
|
||
{
|
||
*pbVisible = m_oShadow.Visible;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ShadowVisible)(BOOL bVisible)
|
||
{
|
||
m_oShadow.Visible = bVisible;
|
||
|
||
return S_OK;
|
||
}
|
||
//-------- Функции для работы с Edge Text --------------------------------------------------------
|
||
STDMETHOD(SetEdgeText)(BSTR bsXML)
|
||
{
|
||
CString strXML( bsXML );
|
||
m_oEdgeText.FromXmlString( strXML );
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_EdgeVisible)(LONG *plVisible)
|
||
{
|
||
*plVisible = m_oEdgeText.Visible;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_EdgeVisible)(LONG lVisible)
|
||
{
|
||
m_oEdgeText.Visible = lVisible;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_EdgeColor)(LONG *plColor)
|
||
{
|
||
*plColor = m_oEdgeText.Color;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_EdgeColor)(LONG lColor)
|
||
{
|
||
m_oEdgeText.Color = lColor;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_EdgeAlpha)(LONG *plAlpha)
|
||
{
|
||
*plAlpha = m_oEdgeText.Alpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_EdgeAlpha)(LONG lAlpha)
|
||
{
|
||
m_oEdgeText.Alpha = lAlpha;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(get_EdgeDist)(double *pdDist)
|
||
{
|
||
*pdDist = m_oEdgeText.Dist;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_EdgeDist)(double dDist)
|
||
{
|
||
m_oEdgeText.Dist = dDist;
|
||
|
||
return S_OK;
|
||
}
|
||
//--------- Функции для вывода текста ------------------------------------------------------------
|
||
STDMETHOD(CommandDrawText) (BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
|
||
{
|
||
HRESULT hRes = S_OK;
|
||
|
||
// Работа с сылками тоже проходит с помощью функции CommandDrawText
|
||
if ( c_nHyperlinkType == m_pCurCommand->nType )
|
||
{
|
||
SetState( rendstateNone );
|
||
|
||
if ( FAILED( hRes = MakeAnnotationFromXml( bsText ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
if ( c_nClipType != m_pCurCommand->nType )
|
||
{
|
||
m_oContiniousText.Add( bsText, bsText, fX, fY, fWidth, fHeight, fBaseLineOffset, false, m_oFont, m_oBrush, m_oTransform, m_dCharSpace );
|
||
SetState( rendstateText );
|
||
|
||
return S_OK;
|
||
}
|
||
else
|
||
{
|
||
SetState( rendstateClipText );
|
||
}
|
||
|
||
|
||
CSynchAccess oSynchAccess = m_hSynchMutex;
|
||
|
||
// Работа с сылками тоже проходит с помощью функции CommandDrawText
|
||
if ( c_nHyperlinkType == m_pCurCommand->nType )
|
||
{
|
||
if ( FAILED( hRes = MakeAnnotationFromXml( bsText ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
// Переводим в миллиметры
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
fWidth = MMToPDFCoords( fWidth );
|
||
fHeight = MMToPDFCoords( fHeight );
|
||
fBaseLineOffset = MMToPDFCoords( fBaseLineOffset );
|
||
|
||
PToUnicode pToUnicode = FindToUnicodeForString( m_pDocument, bsText );
|
||
if ( !pToUnicode )
|
||
return S_OK;
|
||
|
||
CString sCodedString;
|
||
BOOL bResult = ToUnicodeWCharToString( pToUnicode, bsText, &sCodedString );
|
||
|
||
USES_CONVERSION;
|
||
|
||
// Запоминаем значения Bold и Italic, потому что в функции GdiFontToPdfFont они могут измениться
|
||
BOOL bOldBold = m_oFont.Bold;
|
||
BOOL bOldItalic = m_oFont.Italic;
|
||
|
||
BOOL bDefaultFont = FALSE;
|
||
if ( FAILED( hRes = GdiFontToPdfFont2( A2W( pToUnicode->sName ), FALSE ) ) )
|
||
{
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND == hRes )
|
||
{
|
||
ResetError( m_pDocument );
|
||
sCodedString = CString( bsText );
|
||
bDefaultFont = TRUE;
|
||
}
|
||
else
|
||
{
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
BSTR bsCodedString = sCodedString.AllocSysString();
|
||
|
||
long nAscent = 0;
|
||
long nDescent = 0;
|
||
long nXHeight = 0;
|
||
|
||
double dItalicAngle = 3.141592f / 12;
|
||
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( !m_oFont.Italic )
|
||
dItalicAngle = 0;
|
||
|
||
float fFontSize = (float)m_oFont.Size;
|
||
|
||
if ( FAILED( hRes = GetFontAscent( &nAscent ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetFontDescent( &nDescent ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetFontXHeight( &nXHeight ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Выясним как нам рисовать текст
|
||
ETextRenderingMode eRenderingMode = ETextRenderingMode::Fill; // Fill (по умолчанию)
|
||
if ( c_nStrokeTextType == m_pCurCommand->nType )
|
||
eRenderingMode = ETextRenderingMode::Stroke; // Stroke
|
||
if ( c_nClipType == m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T( "TextClip" ) );
|
||
eRenderingMode = ETextRenderingMode::Clipping; // Clip
|
||
}
|
||
|
||
float fXHeight = (float)nXHeight / 1000;
|
||
float fAscent = (float)nAscent / 1000;
|
||
float fDescent = fabs( (float)nDescent / 1000 );
|
||
|
||
long nColor1 = m_oBrush.Color1;
|
||
float fR = ( nColor1 & 0xFF ) / 255.0f;
|
||
float fG = ( ( nColor1 >> 8 ) & 0xFF ) / 255.0f;
|
||
float fB = ( nColor1 >> 16 ) / 255.0f;
|
||
float fTextWidth = 0.0f;
|
||
float fLineWidth = fFontSize / ( bOldBold ? 10.f : 15.0f );
|
||
float fOldLineWidth = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetLineWidth( &fOldLineWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
float fFillR, fFillG, fFillB, fStrokeR, fStrokeG, fStrokeB;
|
||
if ( FAILED( hRes = GetRGBFill( &fFillR, &fFillG, &fFillB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetRGBStroke( &fStrokeR, &fStrokeG, &fStrokeB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
// Рисуем тени
|
||
|
||
if ( m_oShadow.Visible )
|
||
{
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
ATLTRACE2( _T("GSave: DrawText - Shadow\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetLineWidth( fLineWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Выставляем систему координат
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
double dXShadow = fX + MMToPDFCoords( m_oShadow.DistanceX );
|
||
double dYShadow = fY + MMToPDFCoords( m_oShadow.DistanceY );
|
||
|
||
long nAlpha = m_oShadow.Alpha;
|
||
long nShadowColor = m_oShadow.Color;
|
||
|
||
float fAlpha = (float)nAlpha / 255.0f;
|
||
float fBShadow = ( nShadowColor & 0xFF ) / 255.0f;
|
||
float fGShadow = ( ( nShadowColor >> 8 ) & 0xFF ) / 255.0f;
|
||
float fRShadow = ( nShadowColor >> 16 ) / 255.0f;
|
||
|
||
{
|
||
XmlUtils::CXmlWriter oWriter;
|
||
|
||
oWriter.WriteNodeBegin( _T("ExtGState") );
|
||
|
||
if ( 255 != fAlpha )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaFill"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)fAlpha );
|
||
oWriter.WriteNodeEnd( _T("AlphaFill"), TRUE, TRUE );
|
||
}
|
||
|
||
if ( 255 != fAlpha )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaStroke"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)fAlpha );
|
||
oWriter.WriteNodeEnd( _T("AlphaStroke"), TRUE, TRUE );
|
||
}
|
||
|
||
oWriter.WriteNodeEnd( _T("ExtGState") );
|
||
|
||
BSTR bsXml = oWriter.GetXmlString().AllocSysString();
|
||
if ( FAILED( hRes = SetExtGraphicsState2( bsXml ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
::SysFreeString( bsXml );
|
||
return hRes;
|
||
}
|
||
|
||
::SysFreeString( bsXml );
|
||
|
||
//if ( FAILED( hRes = NewExtGraphicsState() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
////if ( FAILED( hRes = ExtGraphicsStateSetBlendMode( EBlendMode::BMOverlay ) ) )
|
||
////{
|
||
//// ::SysFreeString( bsCodedString );
|
||
//// return hRes;
|
||
////}
|
||
//if ( FAILED( hRes = ExtGraphicsStateSetAlphaFill( fAlpha ) ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
//if ( FAILED( hRes = ExtGraphicsStateSetAlphaStroke( fAlpha ) ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
//if ( FAILED( hRes = SetExtGraphicsState() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
}
|
||
|
||
// Выставляем цвет текста и линий
|
||
if ( FAILED( hRes = SetRGBFill( fRShadow, fGShadow, fBShadow ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fRShadow, fGShadow, fBShadow ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = BeginText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Устанавливаем текущий фонт и размер фонта
|
||
if ( FAILED( hRes = SetFontAndSizeToGState( fFontSize ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( hRes = SetTextMatrix( 1, (float)tan( 0.0 ), (float)tan( dItalicAngle ), 1, 0, 0 ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( eRenderingMode == ETextRenderingMode::Fill )
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Bold, тогда заливаем и обводим текст, тем самым утолщяя его
|
||
if ( m_oFont.Bold )
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::FillThenStroke) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::Fill) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выводим текст
|
||
if ( FAILED( hRes = TextOut( (float)dXShadow, fPageHeight - (float)(dYShadow + fBaseLineOffset) , bsCodedString ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
if ( FAILED( hRes = EndText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
//// Перечеркивание текста. Текст перечеркиваем по середине буквы 'x'. (См. XHeight)
|
||
//if ( m_oFont.Strikeout )
|
||
//{
|
||
// double dItalicAdd = tan( (double)dItalicAngle ) * fXHeight * fFontSize / 2;
|
||
// if ( !m_oFont.Italic )
|
||
// dItalicAdd = 0;
|
||
// if ( FAILED( hRes = MoveTo( (float)dXShadow + dItalicAdd, fPageHeight - (float)( dYShadow + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = LineTo( (float)dXShadow + fTextWidth + dItalicAdd, fPageHeight - (float)( dYShadow + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = Stroke( ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
//}
|
||
|
||
//// Подчеркивание текста.
|
||
//if ( m_oFont.Underline )
|
||
//{
|
||
// float fTextWidth = 0.0f;
|
||
// float fUnderLineOffset = 3 + fLineWidth / 2;
|
||
// if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = MoveTo( (float)dXShadow, fPageHeight - ( (float)dYShadow + fBaseLineOffset + fUnderLineOffset /*fDescent * fFontSize*/ ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = LineTo( (float)dXShadow + fTextWidth, fPageHeight - ( (float)dYShadow + fBaseLineOffset + fUnderLineOffset /*fDescent * fFontSize*/ ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = Stroke( ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
//}
|
||
|
||
ATLTRACE2( _T("GRestore: DrawText - Shadow\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
|
||
// Дальше рисуем все, что непосредственно связанно с самим текстом
|
||
// Выставляем цвет текста и линий
|
||
|
||
if ( ETextRenderingMode::Fill == eRenderingMode )
|
||
{
|
||
if ( FAILED( hRes = SetRGBFill( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetRGBFill( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выставляем систему координат
|
||
if ( c_nClipType != m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T("GSave: DrawText\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
float fAlphaFill = (float)m_oBrush.Alpha1 / 255.0f;
|
||
float fAlphaStroke = (float)m_oPen.Alpha / 255.0f;
|
||
m_pCurrentExtGState = GetExtGState( m_pDocument, fAlphaStroke, fAlphaFill );
|
||
if ( OK != ( hRes = PageSetExtGState( m_pDocument->pCurPage, m_pCurrentExtGState ) ) )
|
||
return hRes;
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
if ( FAILED( hRes = BeginText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Устанавливаем межсимвольный интервал
|
||
if ( FAILED( hRes = SetCharSpace( (float)m_dCharSpace ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Устанавливаем текущий фонт и размер фонта
|
||
if ( FAILED( hRes = SetFontAndSizeToGState( fFontSize ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Если шрифт не нашли, и используется стандартный шрифт, значит, ширина слов будет неверной.
|
||
// Чтобы слова не наползали друг на друга скейлим текст к его реальной ширине.
|
||
if ( bDefaultFont )
|
||
{
|
||
// Измеряем размер
|
||
float fTextWidth = 0.0f;
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
float fKoef;
|
||
if ( fabs( fTextWidth ) < 0.01 )
|
||
fKoef = 1;
|
||
else
|
||
fKoef = fWidth / fTextWidth * 100; // Scale задается в процентах
|
||
|
||
if ( fKoef > 0.001 )
|
||
{
|
||
if ( FAILED( hRes = SetHorizontalScalling( fKoef ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( _T("AVSEmptyFont") == m_oFont.Name )
|
||
{
|
||
// Данная ветка сделана специально для конвертации Djvu -> PDF
|
||
|
||
float fVKoef;
|
||
|
||
if ( fabs( m_oFont.Size ) < 0.01 )
|
||
fVKoef = 1;
|
||
else
|
||
fVKoef = fHeight / m_oFont.Size;
|
||
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( hRes = SetTextMatrix( 1, (float)tan( 0.0 ), (float)fVKoef * tan( dItalicAngle ), fVKoef * 1, 0, 0 ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( hRes = SetTextMatrix( 1, (float)tan( 0.0 ), (float)tan( dItalicAngle ), 1, 0, 0 ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( ETextRenderingMode::Fill == eRenderingMode )
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Bold, тогда заливаем и обводим текст, тем самым утолщяя его
|
||
if ( m_oFont.Bold )
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::FillThenStroke) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::Fill) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выводим текст
|
||
if ( FAILED( hRes = TextOut( (float)fX, fPageHeight - (float)(fY + fBaseLineOffset), bsCodedString ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = EndText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
//if ( FAILED( hRes = SetLineWidth( fLineWidth ) ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
|
||
//// Перечеркивание текста. Текст перечеркиваем по середине буквы 'x'. (См. XHeight)
|
||
//if ( m_oFont.Strikeout )
|
||
//{
|
||
// double dItalicAdd = tan( (double)dItalicAngle ) * fXHeight * fFontSize / 2;
|
||
// if ( !m_oFont.Italic )
|
||
// dItalicAdd = 0;
|
||
// if ( FAILED( hRes = MoveTo( (float)fX + dItalicAdd, fPageHeight - (float)( fY + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = LineTo( (float)fX + fTextWidth + dItalicAdd, fPageHeight - (float)( fY + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = Stroke( ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// //MoveTo(dX, dY - fDescent * fFontSize );
|
||
// //LineTo(dX + dItalicAdd * 2, dY + fFontSize * ( 1 - fDescent ) );
|
||
// //LineTo(dX + fTextWidth + dItalicAdd * 2, dY + fFontSize * ( 1 - fDescent ) );
|
||
// //LineTo(dX + fTextWidth, dY - fDescent * fFontSize );
|
||
// //LineTo(dX, dY - fDescent * fFontSize );
|
||
// //Stroke();
|
||
//}
|
||
|
||
//// Подчеркивание текста.
|
||
//if ( m_oFont.Underline )
|
||
//{
|
||
// float fTextWidth = 0.0f;
|
||
// float fUnderLineOffset = 3 + fLineWidth / 2;
|
||
// if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = MoveTo( (float)fX, fPageHeight - (float)(fY + fBaseLineOffset + fUnderLineOffset) /*fDescent * fFontSize*/ ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = LineTo( (float)fX + fTextWidth, fPageHeight - (float)(fY + fBaseLineOffset + fUnderLineOffset) /*fDescent * fFontSize*/ ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
// if ( FAILED( hRes = Stroke( ) ) )
|
||
// {
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
// }
|
||
//}
|
||
|
||
::SysFreeString( bsCodedString );
|
||
|
||
// Восстанавливаем систему координат
|
||
if ( c_nClipType != m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T("GRestore: DrawText\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
return hRes;
|
||
}
|
||
else
|
||
{
|
||
float fDelta = m_oClipCTM.fA * m_oClipCTM.fD - m_oClipCTM.fB * m_oClipCTM.fC;
|
||
if ( 0.0f != fDelta )
|
||
{
|
||
float fIDelta = 1 / fDelta;
|
||
float fA = fIDelta * m_oClipCTM.fD;
|
||
float fB = fIDelta * ( -m_oClipCTM.fB );
|
||
float fC = fIDelta * ( -m_oClipCTM.fC );
|
||
float fD = fIDelta * m_oClipCTM.fA;
|
||
float fE = fIDelta * (m_oClipCTM.fC * m_oClipCTM.fF - m_oClipCTM.fE * m_oClipCTM.fD);
|
||
float fF = fIDelta * (m_oClipCTM.fE * m_oClipCTM.fB - m_oClipCTM.fA * m_oClipCTM.fF);
|
||
|
||
// Делаем матрицу CTM единичной
|
||
if ( FAILED( hRes = Concat( fA, fB, fC, fD, fE, fF ) ) )
|
||
return hRes;
|
||
}
|
||
|
||
m_oClipCTM.Set( 1, 0, 0, 1, 0, 0 );
|
||
}
|
||
|
||
// Восстанавливаем старые настройки
|
||
if ( FAILED( hRes = SetLineWidth( fOldLineWidth ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = SetRGBFill( fFillR, fFillG, fFillB ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fStrokeR, fStrokeG, fStrokeB ) ) )
|
||
return hRes;
|
||
|
||
m_oFont.Bold = bOldBold;
|
||
m_oFont.Italic = bOldItalic;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(CommandDrawTextEx)(BSTR bsUnicodeText, BSTR bsGidText, BSTR bsSrcCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD nFlags)
|
||
{
|
||
// TODO: Сделать обработку DrawTextEx тоже через Состояния рендерера
|
||
SetState( rendstateNone );
|
||
|
||
if ( !bsUnicodeText && !bsSrcCodeText )
|
||
return S_OK;
|
||
|
||
CSynchAccess oSynchAccess = m_hSynchMutex;
|
||
|
||
HRESULT hRes = S_OK;
|
||
|
||
// Работа с сылками тоже проходит с помощью функции CommandDrawText
|
||
if ( c_nHyperlinkType == m_pCurCommand->nType )
|
||
{
|
||
if ( FAILED( hRes = MakeAnnotationFromXml( bsUnicodeText ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
// Переводим в миллиметры
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
fWidth = MMToPDFCoords( fWidth );
|
||
fHeight = MMToPDFCoords( fHeight );
|
||
fBaseLineOffset = MMToPDFCoords( fBaseLineOffset );
|
||
|
||
BSTR bsCodedString = NULL;
|
||
|
||
// Запоминаем значения Bold и Italic, потому что в функции GdiFontToPdfFont они могут измениться
|
||
BOOL bOldBold = m_oFont.Bold;
|
||
BOOL bOldItalic = m_oFont.Italic;
|
||
BOOL bDefaultFont = FALSE;
|
||
|
||
// Проверяем как задан шрифт, через путь к файлу, или по имени
|
||
if ( _T("") != m_oFont.Path )
|
||
{
|
||
XmlUtils::CXmlNode oNode;
|
||
oNode.FromXmlString( CString(bsSrcCodeText) );
|
||
|
||
// TO DO: Пока если шрифт задан путем, значит он пришел из PDF, как только
|
||
// появится другой формат, с внедренными шрифтами, доделать тут.
|
||
if ( _T("PDF-Text") == oNode.GetName() )
|
||
{
|
||
// Загружаем шрифт и кодировки
|
||
if ( FAILED( hRes = FontFromFileToPdfFont() ) )
|
||
{
|
||
return hRes;
|
||
}
|
||
|
||
int nCode = 0, nCID = 0;
|
||
if ( FontDefCID == ((FontAttr)m_pCurrentFont->pAttr)->pFontDef->eType )
|
||
{
|
||
int nCID;
|
||
|
||
nCID = XmlUtils::GetInteger( oNode.GetAttribute( _T("cid") ) );
|
||
nCode = XmlUtils::GetInteger( oNode.GetAttribute( _T("code") ) );
|
||
int nLen = XmlUtils::GetInteger( oNode.GetAttribute( _T("len") ) );
|
||
|
||
char pBuffer[4];
|
||
|
||
pBuffer[0] = (char)(nCode >> 24);
|
||
pBuffer[1] = (char)(nCode >> 16);
|
||
pBuffer[2] = (char)(nCode >> 8);
|
||
pBuffer[3] = (char)nCode;
|
||
|
||
|
||
CMapEncoderStreamAddCIDtoCode( ((FontAttr)m_pCurrentFont->pAttr)->pEncoder, nCID, pBuffer ,nLen );
|
||
|
||
bsCodedString = CString( wchar_t(nCID) ).AllocSysString();
|
||
}
|
||
else
|
||
{
|
||
nCode = XmlUtils::GetInteger( oNode.GetAttribute( _T("code") ) );
|
||
|
||
bsCodedString = CString( wchar_t(nCode) ).AllocSysString();
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
return S_OK;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
PToUnicode pToUnicode = FindToUnicodeForString( m_pDocument, bsUnicodeText );
|
||
if ( !pToUnicode )
|
||
return S_OK;
|
||
|
||
CString sCodedString;
|
||
BOOL bResult = ToUnicodeWCharToString( pToUnicode, bsUnicodeText, &sCodedString );
|
||
|
||
USES_CONVERSION;
|
||
|
||
if ( FAILED( hRes = GdiFontToPdfFont2( A2W( pToUnicode->sName ), FALSE ) ) )
|
||
{
|
||
if ( AVS_OFFICEPDFWRITER_ERROR_FONT_NOT_FOUND == hRes )
|
||
{
|
||
ResetError( m_pDocument );
|
||
sCodedString = CString( bsUnicodeText );
|
||
bDefaultFont = TRUE;
|
||
}
|
||
else
|
||
{
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
bsCodedString = sCodedString.AllocSysString();
|
||
}
|
||
|
||
|
||
long nAscent = 0;
|
||
long nDescent = 0;
|
||
long nXHeight = 0;
|
||
|
||
double dItalicAngle = 3.141592f / 12;
|
||
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( !m_oFont.Italic )
|
||
dItalicAngle = 0;
|
||
|
||
float fFontSize = (float)m_oFont.Size;
|
||
|
||
if ( FAILED( hRes = GetFontAscent( &nAscent ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetFontDescent( &nDescent ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetFontXHeight( &nXHeight ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Выясним как нам рисовать текст
|
||
ETextRenderingMode eRenderingMode = ETextRenderingMode::Fill; // Fill (по умолчанию)
|
||
if ( c_nStrokeTextType == m_pCurCommand->nType )
|
||
eRenderingMode = ETextRenderingMode::Stroke; // Stroke
|
||
if ( c_nClipType == m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T( "TextClip" ) );
|
||
eRenderingMode = ETextRenderingMode::Clipping; // Clip
|
||
}
|
||
|
||
float fXHeight = (float)nXHeight / 1000;
|
||
float fAscent = (float)nAscent / 1000;
|
||
float fDescent = fabs( (float)nDescent / 1000 );
|
||
|
||
long nColor1 = m_oBrush.Color1;
|
||
float fR = ( nColor1 & 0xFF ) / 255.0f;
|
||
float fG = ( ( nColor1 >> 8 ) & 0xFF ) / 255.0f;
|
||
float fB = ( nColor1 >> 16 ) / 255.0f;
|
||
float fTextWidth = 0.0f;
|
||
float fLineWidth = fFontSize / ( bOldBold ? 10.f : 15.0f );
|
||
float fOldLineWidth = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetLineWidth( &fOldLineWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
float fFillR, fFillG, fFillB, fStrokeR, fStrokeG, fStrokeB;
|
||
if ( FAILED( hRes = GetRGBFill( &fFillR, &fFillG, &fFillB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetRGBStroke( &fStrokeR, &fStrokeG, &fStrokeB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
// Рисуем тени
|
||
|
||
if ( m_oShadow.Visible )
|
||
{
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
ATLTRACE2( _T("GSave: DrawText - Shadow\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetLineWidth( fLineWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Выставляем систему координат
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
double dXShadow = fX + MMToPDFCoords( m_oShadow.DistanceX );
|
||
double dYShadow = fY + MMToPDFCoords( m_oShadow.DistanceY );
|
||
|
||
long nAlpha = m_oShadow.Alpha;
|
||
long nShadowColor = m_oShadow.Color;
|
||
|
||
float fAlpha = (float)nAlpha / 255.0f;
|
||
float fBShadow = ( nShadowColor & 0xFF ) / 255.0f;
|
||
float fGShadow = ( ( nShadowColor >> 8 ) & 0xFF ) / 255.0f;
|
||
float fRShadow = ( nShadowColor >> 16 ) / 255.0f;
|
||
|
||
{
|
||
XmlUtils::CXmlWriter oWriter;
|
||
|
||
oWriter.WriteNodeBegin( _T("ExtGState") );
|
||
|
||
if ( 255 != fAlpha )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaFill"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)fAlpha );
|
||
oWriter.WriteNodeEnd( _T("AlphaFill"), TRUE, TRUE );
|
||
}
|
||
|
||
if ( 255 != fAlpha )
|
||
{
|
||
oWriter.WriteNodeBegin( _T("AlphaStroke"), TRUE );
|
||
oWriter.WriteAttribute( _T("value"), (double)fAlpha );
|
||
oWriter.WriteNodeEnd( _T("AlphaStroke"), TRUE, TRUE );
|
||
}
|
||
|
||
oWriter.WriteNodeEnd( _T("ExtGState") );
|
||
|
||
BSTR bsXml = oWriter.GetXmlString().AllocSysString();
|
||
if ( FAILED( hRes = SetExtGraphicsState2( bsXml ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
::SysFreeString( bsXml );
|
||
return hRes;
|
||
}
|
||
|
||
::SysFreeString( bsXml );
|
||
//if ( FAILED( hRes = NewExtGraphicsState() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
////if ( FAILED( hRes = ExtGraphicsStateSetBlendMode( EBlendMode::BMOverlay ) ) )
|
||
////{
|
||
//// ::SysFreeString( bsCodedString );
|
||
//// return hRes;
|
||
////}
|
||
//if ( FAILED( hRes = ExtGraphicsStateSetAlphaFill( fAlpha ) ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
//if ( FAILED( hRes = ExtGraphicsStateSetAlphaStroke( fAlpha ) ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
//if ( FAILED( hRes = SetExtGraphicsState() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
|
||
}
|
||
|
||
// Выставляем цвет текста и линий
|
||
if ( FAILED( hRes = SetRGBFill( fRShadow, fGShadow, fBShadow ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fRShadow, fGShadow, fBShadow ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = BeginText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Устанавливаем текущий фонт и размер фонта
|
||
if ( FAILED( hRes = SetFontAndSizeToGState( fFontSize ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( hRes = SetTextMatrix( 1, (float)tan( 0.0 ), (float)tan( dItalicAngle ), 1, 0, 0 ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( eRenderingMode == ETextRenderingMode::Fill )
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Bold, тогда заливаем и обводим текст, тем самым утолщяя его
|
||
if ( m_oFont.Bold )
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::FillThenStroke) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::Fill) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выводим текст
|
||
if ( FAILED( hRes = TextOut( (float)dXShadow, fPageHeight - (float)(dYShadow + fBaseLineOffset) , bsCodedString ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
if ( FAILED( hRes = EndText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Перечеркивание текста. Текст перечеркиваем по середине буквы 'x'. (См. XHeight)
|
||
if ( m_oFont.Strikeout )
|
||
{
|
||
double dItalicAdd = tan( (double)dItalicAngle ) * fXHeight * fFontSize / 2;
|
||
if ( !m_oFont.Italic )
|
||
dItalicAdd = 0;
|
||
if ( FAILED( hRes = MoveTo( (float)dXShadow + dItalicAdd, fPageHeight - (float)( dYShadow + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = LineTo( (float)dXShadow + fTextWidth + dItalicAdd, fPageHeight - (float)( dYShadow + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = Stroke( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Подчеркивание текста.
|
||
if ( m_oFont.Underline )
|
||
{
|
||
float fTextWidth = 0.0f;
|
||
float fUnderLineOffset = 3 + fLineWidth / 2;
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = MoveTo( (float)dXShadow, fPageHeight - ( (float)dYShadow + fBaseLineOffset + fUnderLineOffset /*fDescent * fFontSize*/ ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = LineTo( (float)dXShadow + fTextWidth, fPageHeight - ( (float)dYShadow + fBaseLineOffset + fUnderLineOffset /*fDescent * fFontSize*/ ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = Stroke( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
ATLTRACE2( _T("GRestore: DrawText - Shadow\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
//{
|
||
// ::SysFreeString( bsCodedString );
|
||
// return hRes;
|
||
//}
|
||
|
||
// Дальше рисуем все, что непосредственно связанно с самим текстом
|
||
// Выставляем цвет текста и линий
|
||
|
||
if ( ETextRenderingMode::Fill == eRenderingMode )
|
||
{
|
||
if ( FAILED( hRes = SetRGBFill( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetRGBFill( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fR, fG, fB ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выставляем систему координат
|
||
if ( c_nClipType != m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T("GSave: DrawText\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = UpdateCoordSpace( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
if ( FAILED( hRes = BeginText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Устанавливаем текущий фонт и размер фонта
|
||
if ( FAILED( hRes = SetFontAndSizeToGState( fFontSize ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Если шрифт не нашли, и используется стандартный шрифт, значит, ширина слов будет неверной.
|
||
// Чтобы слова не наползали друг на друга скейлим текст к его реальной ширине.
|
||
if ( bDefaultFont )
|
||
{
|
||
// Измеряем размер
|
||
float fTextWidth = 0.0f;
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
float fKoef = fWidth / fTextWidth * 100; // Scale задается в процентах
|
||
|
||
if ( fKoef > 0.001 )
|
||
{
|
||
if ( FAILED( hRes = SetHorizontalScalling( fKoef ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Если данный фонт не нашли с атрибутом Italic, тогда наколняем текст сами на угол dItalicAngle
|
||
if ( FAILED( hRes = SetTextMatrix( 1, (float)tan( 0.0 ), (float)tan( dItalicAngle ), 1, 0, 0 ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( ETextRenderingMode::Fill == eRenderingMode )
|
||
{
|
||
// Если данный фонт не нашли с атрибутом Bold, тогда заливаем и обводим текст, тем самым утолщяя его
|
||
if ( m_oFont.Bold )
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::FillThenStroke) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
if ( FAILED( hRes = SetTextRenderingMode((long)ETextRenderingMode::Fill) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( FAILED( hRes = SetTextRenderingMode( (long)eRenderingMode ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
// Выводим текст
|
||
if ( FAILED( hRes = TextOut( (float)fX, fPageHeight - (float)(fY + fBaseLineOffset), bsCodedString ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = EndText() ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = SetLineWidth( fLineWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
|
||
// Перечеркивание текста. Текст перечеркиваем по середине буквы 'x'. (См. XHeight)
|
||
if ( m_oFont.Strikeout )
|
||
{
|
||
double dItalicAdd = tan( (double)dItalicAngle ) * fXHeight * fFontSize / 2;
|
||
if ( !m_oFont.Italic )
|
||
dItalicAdd = 0;
|
||
if ( FAILED( hRes = MoveTo( (float)fX + dItalicAdd, fPageHeight - (float)( fY + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = LineTo( (float)fX + fTextWidth + dItalicAdd, fPageHeight - (float)( fY + fBaseLineOffset - fXHeight * fFontSize / 2 ) ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = Stroke( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
//MoveTo(dX, dY - fDescent * fFontSize );
|
||
//LineTo(dX + dItalicAdd * 2, dY + fFontSize * ( 1 - fDescent ) );
|
||
//LineTo(dX + fTextWidth + dItalicAdd * 2, dY + fFontSize * ( 1 - fDescent ) );
|
||
//LineTo(dX + fTextWidth, dY - fDescent * fFontSize );
|
||
//LineTo(dX, dY - fDescent * fFontSize );
|
||
//Stroke();
|
||
}
|
||
|
||
// Подчеркивание текста.
|
||
if ( m_oFont.Underline )
|
||
{
|
||
float fTextWidth = 0.0f;
|
||
float fUnderLineOffset = 3 + fLineWidth / 2;
|
||
if ( FAILED( hRes = GetTextWidth( bsCodedString, &fTextWidth ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = MoveTo( (float)fX, fPageHeight - (float)(fY + fBaseLineOffset + fUnderLineOffset) /*fDescent * fFontSize*/ ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = LineTo( (float)fX + fTextWidth, fPageHeight - (float)(fY + fBaseLineOffset + fUnderLineOffset) /*fDescent * fFontSize*/ ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
if ( FAILED( hRes = Stroke( ) ) )
|
||
{
|
||
::SysFreeString( bsCodedString );
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
::SysFreeString( bsCodedString );
|
||
|
||
// Восстанавливаем систему координат
|
||
if ( c_nClipType != m_pCurCommand->nType )
|
||
{
|
||
ATLTRACE2( _T("GRestore: DrawText\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
return hRes;
|
||
}
|
||
else
|
||
{
|
||
float fDelta = m_oClipCTM.fA * m_oClipCTM.fD - m_oClipCTM.fB * m_oClipCTM.fC;
|
||
if ( 0.0f != fDelta )
|
||
{
|
||
float fIDelta = 1 / fDelta;
|
||
float fA = fIDelta * m_oClipCTM.fD;
|
||
float fB = fIDelta * ( -m_oClipCTM.fB );
|
||
float fC = fIDelta * ( -m_oClipCTM.fC );
|
||
float fD = fIDelta * m_oClipCTM.fA;
|
||
float fE = fIDelta * (m_oClipCTM.fC * m_oClipCTM.fF - m_oClipCTM.fE * m_oClipCTM.fD);
|
||
float fF = fIDelta * (m_oClipCTM.fE * m_oClipCTM.fB - m_oClipCTM.fA * m_oClipCTM.fF);
|
||
|
||
// Делаем матрицу CTM единичной
|
||
if ( FAILED( hRes = Concat( fA, fB, fC, fD, fE, fF ) ) )
|
||
return hRes;
|
||
}
|
||
|
||
m_oClipCTM.Set( 1, 0, 0, 1, 0, 0 );
|
||
}
|
||
|
||
// Восстанавливаем старые настройки
|
||
if ( FAILED( hRes = SetLineWidth( fOldLineWidth ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = SetRGBFill( fFillR, fFillG, fFillB ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED( hRes = SetRGBStroke( fStrokeR, fStrokeG, fStrokeB ) ) )
|
||
return hRes;
|
||
|
||
m_oFont.Bold = bOldBold;
|
||
m_oFont.Italic = bOldItalic;
|
||
|
||
return S_OK;
|
||
}
|
||
//--------- Маркеры для команд -------------------------------------------------------------------
|
||
STDMETHOD(BeginCommand)(DWORD nFlag)
|
||
{
|
||
char sTemp[32];
|
||
itoa(nFlag, sTemp, 10);
|
||
|
||
ATLTRACE2( _T("Begin") + CString( sTemp ) + _T("\n") );
|
||
if ( nFlag == c_nTableCell || nFlag == c_nHeader || nFlag == c_nColumnCount || nFlag == c_nFootnote
|
||
|| nFlag == c_nShape || nFlag == c_nShapeGroup || nFlag == c_nShapeWrap || nFlag == c_nTable
|
||
|| nFlag == c_nTableXml || nFlag == c_nBlock || nFlag == c_nBlockHeadingLevel || nFlag == c_nBlockNumberingLevel
|
||
|| nFlag == c_nBaselineShift
|
||
)
|
||
return S_OK;
|
||
|
||
TCommandType *pNewCommand = new TCommandType();
|
||
pNewCommand->nType = nFlag;
|
||
pNewCommand->pPrev = m_pCurCommand;
|
||
m_pCurCommand = pNewCommand;
|
||
|
||
HRESULT hRes = S_OK;
|
||
if ( c_nPathType == nFlag )
|
||
{
|
||
SetState( rendstatePath );
|
||
// Сейчас начинаем рисовать Path
|
||
|
||
m_BlockCommandsStart = ((PageAttr)m_pDocument->pCurPage->pAttr)->pStream->nSize;
|
||
|
||
ATLTRACE2( _T("GSave: PathType\n") );
|
||
if ( FAILED( hRes = UpdateGState() ) )
|
||
return hRes;
|
||
|
||
int c = 0;
|
||
}
|
||
else if ( c_nClipType == nFlag )
|
||
{
|
||
// Запоминаем состояние без обрезающего пата
|
||
if ( FALSE == m_bClipPath )
|
||
{
|
||
ATLTRACE2( _T("GSave: ClipPathType\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
return hRes;
|
||
|
||
m_bClipPath = TRUE;
|
||
}
|
||
}
|
||
else if ( c_nResetClipType == nFlag )
|
||
{
|
||
// Откатываемся к состоянию без обрезающего пата
|
||
if ( TRUE == m_bClipPath )
|
||
{
|
||
SetState( rendstateClipReset );
|
||
|
||
ATLTRACE2( _T("GRestore: ClipPathType\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
return hRes;
|
||
|
||
m_oClipCTM.Set( 1, 0, 0, 1, 0, 0 );
|
||
|
||
m_bClipPath = FALSE;
|
||
}
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(EndCommand)(DWORD nFlag)
|
||
{
|
||
char sTemp[32];
|
||
itoa(nFlag, sTemp, 10);
|
||
|
||
ATLTRACE2( _T("End") + CString( sTemp ) + _T("\n") );
|
||
if ( nFlag == c_nTableCell || nFlag == c_nHeader || nFlag == c_nColumnCount || nFlag == c_nFootnote
|
||
|| nFlag == c_nShape || nFlag == c_nShapeGroup || nFlag == c_nShapeWrap || nFlag == c_nTable
|
||
|| nFlag == c_nTableXml || nFlag == c_nBlock || nFlag == c_nBlockHeadingLevel || nFlag == c_nBlockNumberingLevel
|
||
|| nFlag == c_nBaselineShift
|
||
)
|
||
return S_OK;
|
||
|
||
|
||
if ( !m_pCurCommand || nFlag != m_pCurCommand->nType )
|
||
return AVS_OFFICEPDFWRITER_ERROR_BAD_COMMAND_TYPE;
|
||
|
||
HRESULT hRes = S_OK;
|
||
if ( c_nPathType == nFlag )
|
||
{
|
||
// Если данный пат набивался как клип, тогда мы должны подать команду о завершении
|
||
if ( NULL != m_pCurCommand->pPrev && c_nClipType == m_pCurCommand->pPrev->nType )
|
||
{
|
||
if ( c_nClipRegionTypeWinding == m_pCurCommand->nFlag )
|
||
{
|
||
if ( FAILED( hRes = Clip() ) )
|
||
return hRes;
|
||
}
|
||
else if ( c_nClipRegionTypeEvenOdd == m_pCurCommand->nFlag )
|
||
{
|
||
if ( FAILED( hRes = EoClip() ) )
|
||
return hRes;
|
||
}
|
||
|
||
if ( FAILED( hRes = EndPath() ) )
|
||
return hRes;
|
||
|
||
float fDelta = m_oClipCTM.fA * m_oClipCTM.fD - m_oClipCTM.fB * m_oClipCTM.fC;
|
||
if ( 0.0f != fDelta )
|
||
{
|
||
float fIDelta = 1 / fDelta;
|
||
float fA = fIDelta * m_oClipCTM.fD;
|
||
float fB = fIDelta * ( -m_oClipCTM.fB );
|
||
float fC = fIDelta * ( -m_oClipCTM.fC );
|
||
float fD = fIDelta * m_oClipCTM.fA;
|
||
float fE = fIDelta * (m_oClipCTM.fC * m_oClipCTM.fF - m_oClipCTM.fE * m_oClipCTM.fD);
|
||
float fF = fIDelta * (m_oClipCTM.fE * m_oClipCTM.fB - m_oClipCTM.fA * m_oClipCTM.fF);
|
||
|
||
// Делаем матрицу CTM единичной
|
||
if ( FAILED( hRes = Concat( fA, fB, fC, fD, fE, fF ) ) )
|
||
return hRes;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
ATLTRACE2( _T("GRestore: PathType\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
return hRes;
|
||
}
|
||
}
|
||
else if ( c_nPageType == nFlag )
|
||
{
|
||
SetState( rendstateNone );
|
||
}
|
||
|
||
TCommandType *pPrev = m_pCurCommand->pPrev;
|
||
delete m_pCurCommand;
|
||
m_pCurCommand = pPrev;
|
||
|
||
return S_OK;
|
||
}
|
||
//--------- Функции для работы с Graphics Path ---------------------------------------------------
|
||
STDMETHOD(PathCommandStart)()
|
||
{
|
||
ATLTRACE2( _T("Start\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->Start();
|
||
|
||
//BSTR bsError;
|
||
//GetLastErrorString(&bsError);
|
||
//HRESULT hRes = S_OK;
|
||
//if ( FAILED ( hRes = EndPath() ) )
|
||
// return hRes;
|
||
m_bStartSubPath = TRUE;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandEnd)()
|
||
{
|
||
ATLTRACE2( _T("End\n") );
|
||
|
||
if (CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->End();
|
||
|
||
//HRESULT hRes = S_OK;
|
||
//if ( FAILED ( hRes = EndPath() ) )
|
||
// return hRes;
|
||
//m_bStartSubPath = TRUE;
|
||
|
||
// NOTE : решение хардкорное
|
||
|
||
// градиент имеет прозрачность, поэтому все команды перемещаем в форму
|
||
// TODO : переписать запись команд таким образом что бы они сыпались во временный объект
|
||
|
||
if (m_MaskWithFormCommands.GetLength())
|
||
{
|
||
if (m_XForm)
|
||
{
|
||
Stream stream = ((PageAttr)m_pDocument->pCurPage->pAttr)->pStream;
|
||
unsigned int bufferSize = stream->nSize - m_BlockCommandsStart;
|
||
if (bufferSize && stream)
|
||
{
|
||
CStringA str;
|
||
CHAR* buffer = str.GetBuffer(bufferSize + 1);
|
||
if (buffer)
|
||
{
|
||
GRestore();
|
||
|
||
StreamSeek(stream, m_BlockCommandsStart, WhenceMode::SeekSet);
|
||
StreamRead(stream, (BYTE*)buffer, &bufferSize);
|
||
StreamSeek(stream, m_BlockCommandsStart, WhenceMode::SeekWrite);
|
||
|
||
buffer[bufferSize] = L'\0';
|
||
|
||
CString data(str);
|
||
m_XForm->SetStream(data);
|
||
|
||
// Example : q /s13 gs /x14 Do Q
|
||
// к /x объекту применяется маска /s
|
||
|
||
StreamWriteStr(stream, CStringA(m_MaskWithFormCommands));
|
||
|
||
if (m_IsStrokeShape)
|
||
{
|
||
|
||
if (m_strPatternFill.GetLength()) data.Replace(m_strPatternFill, L"");
|
||
if (m_strPatternStroke.GetLength()) data.Replace(m_strPatternStroke, L"");
|
||
|
||
data.Replace(L"B\012", L"S\012");
|
||
data.Replace(L"f\012", L"s\012");
|
||
|
||
data.Replace(L"B*\012", L"S*\012");
|
||
data.Replace(L"f*\012", L"s*\012");
|
||
|
||
if (-1 == data.Find(L"Q\012")) data += L"Q\012";
|
||
|
||
StreamWriteStr(stream, CStringA(data));
|
||
}
|
||
|
||
str.ReleaseBuffer();
|
||
}
|
||
}
|
||
}
|
||
|
||
m_BlockCommandsStart = 0;
|
||
|
||
m_XForm = NULL;
|
||
m_MaskWithFormCommands = L"";
|
||
m_IsStrokeShape = FALSE;
|
||
|
||
m_strPatternFill = L"";
|
||
m_strPatternStroke = L"";
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
//
|
||
STDMETHOD(PathCommandMoveTo) (double fX, double fY)
|
||
{
|
||
ATLTRACE2( _T("Move To\n") );
|
||
|
||
HRESULT hRes = S_OK;
|
||
|
||
if ( TRUE == m_bFirstMoveTo )
|
||
{
|
||
// Текущее состояние - Path
|
||
SetState( /*m_bClip ? rendstateClipPath :*/ rendstatePath );
|
||
|
||
m_bFirstMoveTo = FALSE;
|
||
}
|
||
|
||
if ( !m_bStartSubPath || m_oPatternState.IsUse())
|
||
{
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type || m_oPatternState.IsUse())
|
||
{
|
||
if (m_oPatternState.IsUse())
|
||
{
|
||
if (NULL == m_pCurPath)
|
||
{
|
||
m_pCurPath = new CGdiPath();
|
||
m_pCurPath->Create();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (m_pCurPath)
|
||
m_pCurPath->Delete();
|
||
else
|
||
m_pCurPath = new CGdiPath();
|
||
|
||
m_pCurPath->Create();
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->MoveTo( fX, fY );
|
||
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
|
||
m_bStartSubPath = FALSE;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( FAILED( hRes = MoveTo( fX, fPageHeight - fY ) ) )
|
||
return hRes;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandLineTo) (double fX, double fY)
|
||
{
|
||
ATLTRACE2( _T("Line To\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->LineTo( fX, fY );
|
||
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( FAILED( hRes = LineTo( fX, fPageHeight - fY ) ) )
|
||
return hRes;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandLinesTo) (SAFEARRAY *pPoints)
|
||
{
|
||
ATLTRACE2( _T("Lines To\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->LinesTo( &pPoints );
|
||
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( 1 != SafeArrayGetDim(pPoints) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_BAD_SAFEARRAY;
|
||
|
||
VARTYPE vType;
|
||
// check for valid array element type
|
||
if ( FAILED(SafeArrayGetVartype(pPoints, &vType)) || VT_R8 != vType )
|
||
return AVS_OFFICEPDFWRITER_ERROR_BAD_SAFEARRAY;
|
||
|
||
double* pArray = (double*)(pPoints)->pvData;
|
||
int nPointsCount = (pPoints)->rgsabound->cElements / 2;
|
||
|
||
if ( m_bStartSubPath )
|
||
{
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
// return hRes;
|
||
if ( FAILED( hRes = PathCommandMoveTo( pArray[0], pArray[1] ) ) )
|
||
return hRes;
|
||
}
|
||
pArray += 2;
|
||
nPointsCount--;
|
||
|
||
for ( int nIndex = 0; nIndex < nPointsCount; nIndex++, pArray += 2 )
|
||
if ( FAILED( hRes = LineTo( MMToPDFCoords( pArray[0] ), fPageHeight - MMToPDFCoords( pArray[1] ) ) ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandCurveTo)(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
|
||
{
|
||
ATLTRACE2( _T("Curve To\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath|| (m_oPatternState.IsUse() && m_pCurPath) )
|
||
m_pCurPath->CurveTo( fX1, fY1, fX2, fY2, fX3, fY3 );
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( FAILED( hRes = CurveTo( MMToPDFCoords( fX1 ), fPageHeight - MMToPDFCoords( fY1 ), MMToPDFCoords( fX2 ), fPageHeight - MMToPDFCoords( fY2 ), MMToPDFCoords( fX3 ), fPageHeight - MMToPDFCoords( fY3 ) ) ) )
|
||
return hRes;
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandCurvesTo)(SAFEARRAY *pPoints)
|
||
{
|
||
ATLTRACE2( _T("Curves To\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->CurvesTo( &pPoints );
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( 1 != SafeArrayGetDim(pPoints) )
|
||
return AVS_OFFICEPDFWRITER_ERROR_BAD_SAFEARRAY;
|
||
|
||
VARTYPE vType;
|
||
// check for valid array element type
|
||
if ( FAILED(SafeArrayGetVartype(pPoints, &vType)) || VT_R8 != vType )
|
||
return AVS_OFFICEPDFWRITER_ERROR_BAD_SAFEARRAY;
|
||
|
||
double* pArray = (double*)(pPoints)->pvData;
|
||
int nPointsCount = (pPoints)->rgsabound->cElements / 2;
|
||
|
||
if ( m_bStartSubPath )
|
||
{
|
||
//if ( FAILED( hRes = GRestore() ) )
|
||
// return hRes;
|
||
if ( FAILED( hRes = PathCommandMoveTo( pArray[0], pArray[1] ) ) )
|
||
return hRes;
|
||
}
|
||
|
||
pArray += 2;
|
||
nPointsCount--;
|
||
|
||
for ( int nIndex = 0; nIndex < nPointsCount / 3; nIndex++, pArray += 6 )
|
||
{
|
||
if ( FAILED( hRes = CurveTo( MMToPDFCoords( pArray[0] ), fPageHeight - MMToPDFCoords( pArray[1] ), MMToPDFCoords( pArray[2] ), fPageHeight - MMToPDFCoords( pArray[3] ), MMToPDFCoords( pArray[4] ), fPageHeight - MMToPDFCoords( pArray[5] ) ) ) )
|
||
return hRes;
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandArcTo) (double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
|
||
{
|
||
ATLTRACE2( _T("Arc To\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->ArcTo( fX, fY, fWidth, fHeight, fStartAngle, fSweepAngle );
|
||
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
fWidth = MMToPDFCoords( fWidth );
|
||
fHeight = MMToPDFCoords( fHeight );
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( m_bStartSubPath )
|
||
{
|
||
double dStartAngle = fStartAngle * 3.141592f / 180;
|
||
float fStartX = fX + fWidth / 2.0f + fWidth / 2 * cos( AngToEllPrm( dStartAngle, fWidth / 2, fHeight / 2 ) );
|
||
float fStartY = fY + fHeight / 2.0f + fHeight / 2 * sin( AngToEllPrm ( dStartAngle, fWidth / 2, fHeight / 2 ) );
|
||
|
||
// Аналог PathCommandMoveTo, но без пересчета координат
|
||
m_bStartSubPath = FALSE;
|
||
|
||
// В случае, когда эллипс рисуется целиком используется команда AppendEllipse, в которой команда MoveTo уже есть
|
||
if ( !( fSweepAngle >= 360 ) )
|
||
if ( FAILED( hRes = MoveTo( fStartX, fPageHeight - fStartY ) ) )
|
||
return hRes;
|
||
|
||
}
|
||
|
||
|
||
BOOL bClockDirection = FALSE;
|
||
float fEndAngle = 360 - ( fSweepAngle + fStartAngle );
|
||
float fSrtAngle = 360 - fStartAngle;
|
||
if( fSweepAngle > 0 )
|
||
bClockDirection = TRUE;
|
||
|
||
if( fSweepAngle >= 360 ) // Целый эллипс
|
||
{
|
||
if ( FAILED( hRes = AppendEllipse( fX + fWidth / 2, fPageHeight - ( fY + fHeight / 2 ), fWidth / 2, fHeight / 2 ) ) )
|
||
return hRes;
|
||
}
|
||
else // Дуга эллипса
|
||
{
|
||
if ( FAILED ( hRes = AppendEllipseArc( fX + fWidth / 2, fPageHeight - ( fY + fHeight / 2 ), fWidth / 2, fHeight / 2, fSrtAngle, fEndAngle, bClockDirection ) ) )
|
||
return hRes;
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandClose)()
|
||
{
|
||
ATLTRACE2( _T("Close\n") );
|
||
|
||
if ( CGdiPath::c_nTextureBrush == m_oBrush.Type && m_pCurPath || (m_oPatternState.IsUse() && m_pCurPath))
|
||
m_pCurPath->Close();
|
||
|
||
HRESULT hRes = S_OK;
|
||
if ( FAILED ( hRes = ClosePath() ) )
|
||
return hRes;
|
||
|
||
m_bStartSubPath = TRUE;
|
||
|
||
return S_OK;
|
||
}
|
||
//
|
||
STDMETHOD(DrawPath)(long nType)
|
||
{
|
||
m_bFirstMoveTo = TRUE;
|
||
m_IsStrokeShape = FALSE;
|
||
|
||
// Обводка текста делается в CommandDrawText (а эта команда приходит для согласования с вьювером)
|
||
if ( c_nStrokeTextType == m_pCurCommand->nType )
|
||
return S_OK;
|
||
|
||
ATLTRACE2( _T("Draw Path\n") );
|
||
|
||
// TO DO: Потом надо будет этот случай убрать
|
||
if ( 0 == nType )
|
||
nType = c_nStroke;
|
||
|
||
m_bStartSubPath = FALSE;
|
||
|
||
BOOL IsBrushTexture = CGdiPath::c_nTextureBrush == m_oBrush.Type;
|
||
BOOL IsNoStroke = c_nStroke != nType;
|
||
BOOL IsBrushFileExist = FileExist(m_oBrush.TexturePath);
|
||
|
||
HRESULT hRes = S_OK;
|
||
if (IsBrushTexture && IsNoStroke && IsBrushFileExist && (m_pCurPath || m_bUseTextureRect))
|
||
{
|
||
if (c_BrushTextureModeStretch == m_oBrush.TextureMode)
|
||
{
|
||
// Меняем текущее состояние с пата на клип по пату и добавляем данный пат к клипу
|
||
m_oRendererState.change_State(rendstateClipPath);
|
||
SetState(rendstateNone);
|
||
|
||
if ( c_nWindingFillMode & nType )
|
||
{
|
||
if ( FAILED( hRes = Clip() ) )
|
||
{
|
||
return hRes;
|
||
}
|
||
}
|
||
else if ( c_nEvenOddFillMode & nType )
|
||
{
|
||
if ( FAILED( hRes = EoClip() ) )
|
||
{
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return S_FALSE;
|
||
}
|
||
|
||
if ( FAILED( hRes = EndPath()))
|
||
{
|
||
return hRes;
|
||
}
|
||
|
||
float fX = 0, fY = 0, fW = 0, fH = 0;
|
||
|
||
if ( TRUE != m_bUseTextureRect )
|
||
{
|
||
m_pCurPath->GetBounds( &fX, &fY, &fW, &fH );
|
||
}
|
||
else
|
||
{
|
||
fX = m_oBrush.Rect.X;
|
||
fY = m_oBrush.Rect.Y;
|
||
fW = m_oBrush.Rect.Width;
|
||
fH = m_oBrush.Rect.Height;
|
||
}
|
||
|
||
CString sPath = m_oBrush.TexturePath;
|
||
BSTR bsPath = sPath.AllocSysString();
|
||
|
||
m_bUseImageTransform = FALSE;
|
||
m_bUseImageTextureAlpha = TRUE;
|
||
|
||
if (FAILED(hRes = DrawImageFromFile(bsPath, fX, fY, fW, fH)))
|
||
{
|
||
::SysFreeString(bsPath);
|
||
ResetError(m_pDocument);
|
||
return hRes;
|
||
}
|
||
|
||
m_bUseImageTransform = TRUE;
|
||
m_bUseImageTextureAlpha = FALSE;
|
||
|
||
SysFreeString(bsPath);
|
||
|
||
return S_OK;
|
||
}
|
||
else if (c_BrushTextureModeTile == m_oBrush.TextureMode)
|
||
{
|
||
ApplyTileFill();
|
||
}
|
||
|
||
// TODO: добавить тайловые заливки с реверсным узором
|
||
}
|
||
else if (IsBrushTexture && IsNoStroke && !IsBrushFileExist)
|
||
{
|
||
if (c_nWindingFillMode & nType)
|
||
nType = c_nWindingFillMode;
|
||
else
|
||
nType = c_nEvenOddFillMode;
|
||
}
|
||
|
||
ApplyFillGradient();
|
||
ApplyStrokeGradient();
|
||
|
||
if (c_nWindingFillMode != nType && c_nEvenOddFillMode != nType)
|
||
{
|
||
m_IsStrokeShape = TRUE;
|
||
}
|
||
|
||
RELEASEOBJECT(m_pCurPath);
|
||
|
||
switch (nType)
|
||
{
|
||
case c_nStroke: if (FAILED(hRes = Stroke())) return hRes; break;
|
||
case c_nWindingFillMode: if (FAILED(hRes = Fill())) return hRes; break;
|
||
case c_nEvenOddFillMode: if (FAILED(hRes = EoFill())) return hRes; break;
|
||
case c_nStroke | c_nWindingFillMode: if (FAILED(hRes = FillStroke())) return hRes; break;
|
||
case c_nStroke | c_nEvenOddFillMode: if (FAILED(hRes = EoFillStroke())) return hRes; break;
|
||
default:
|
||
{
|
||
if (FAILED(hRes = Stroke()))
|
||
return hRes;
|
||
else
|
||
return AVS_OFFICEPDFWRITER_ERROR_DRAW_PATH;
|
||
}
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(PathCommandGetCurrentPoint)(double *pfX, double *pfY)
|
||
{
|
||
ATLTRACE2( _T("GetCurrentPoint\n") );
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f, fX = 0.0f, fY = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
|
||
if ( FAILED ( hRes = GetCurrentPosition( &fX, &fY ) ) )
|
||
return hRes;
|
||
|
||
fY = fPageHeight - fY;
|
||
|
||
*pfX = (double)fX;
|
||
*pfY = (double)fY;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(PathCommandText) (BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset )
|
||
{
|
||
// В данная команда может прийти либо для обводки текста, либо для клипа по тексту
|
||
CommandDrawText( bsText, fX, fY, fWidth, fHeight, fBaseLineOffset );
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(PathCommandTextEx)(BSTR bsUnicodeText, BSTR bsGidText, BSTR bsSrcCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD nFlags )
|
||
{
|
||
// В данная команда может прийти либо для обводки текста, либо для клипа по тексту
|
||
CommandDrawTextEx( bsUnicodeText, bsGidText, bsSrcCodeText, fX, fY, fWidth, fHeight, fBaseLineOffset, nFlags );
|
||
return S_OK;
|
||
}
|
||
|
||
//--------- Функции для вывода изображений -------------------------------------------------------
|
||
STDMETHOD(DrawImage)(IUnknown *pInterface, double fX, double fY, double fWidth, double fHeight)
|
||
{
|
||
SetState( rendstateImage );
|
||
|
||
//BeginCommand( c_nPathType );
|
||
//PathCommandMoveTo( fX, fY );
|
||
//PathCommandLineTo( fX + fWidth, fY + fHeight );
|
||
//DrawPath( c_nWindingFillMode );
|
||
//EndCommand( c_nPathType );
|
||
|
||
fX = MMToPDFCoords( fX );
|
||
fY = MMToPDFCoords( fY );
|
||
fWidth = MMToPDFCoords( fWidth );
|
||
fHeight = MMToPDFCoords( fHeight );
|
||
|
||
|
||
//if ( fWidth < 1 || fHeight < 1 )
|
||
// return S_OK;
|
||
|
||
HRESULT hRes = S_OK;
|
||
float fPageHeight = 0.0f;
|
||
|
||
if ( FAILED( hRes = GetHeight( &fPageHeight ) ) )
|
||
return hRes;
|
||
if ( FAILED ( hRes = LoadImageFromInterface( &pInterface, TRUE ) ) )
|
||
return hRes;
|
||
|
||
ATLTRACE2( _T("GSave: DrawImage\n") );
|
||
if ( FAILED( hRes = GSave() ) )
|
||
return hRes;
|
||
|
||
//if ( FAILED( hRes = UpdateCoordSpace() ) )
|
||
// return hRes;
|
||
|
||
if ( TRUE == m_bUseImageTransform )
|
||
{
|
||
DWORD nFlags = m_oCommandParams.nFlag;
|
||
if ( !( nFlags == 16 ) )
|
||
{
|
||
double dAngle = m_oCommandParams.dAngle;
|
||
double dLeft = m_oCommandParams.dLeft;
|
||
double dHeight = m_oCommandParams.dHeight;
|
||
double dWidth = m_oCommandParams.dWidth;
|
||
double dTop = m_oCommandParams.dTop;
|
||
|
||
if ( !(0 == nFlags && 0 == dAngle) )
|
||
{
|
||
// Миллиметры -> координаты PDF (72dpi)
|
||
|
||
dLeft = MMToPDFCoords( dLeft );
|
||
dTop = MMToPDFCoords( dTop );
|
||
dWidth = MMToPDFCoords( dWidth );
|
||
dHeight = MMToPDFCoords( dHeight );
|
||
|
||
dTop = fPageHeight - dTop;
|
||
dAngle = dAngle * 3.141592f / 180;
|
||
|
||
// Высчитываем центр прямоугольника ( относительно него производится поворот )
|
||
|
||
double dX0 = dLeft + dWidth / 2;
|
||
double dY0 = dTop - dHeight / 2;
|
||
|
||
double dA = cos( dAngle );
|
||
double dB = sin( dAngle );
|
||
double dC = -sin( dAngle );
|
||
double dD = cos( dAngle );
|
||
double dE = dX0 - dX0 * cos ( dAngle ) + dY0 * sin( dAngle );
|
||
double dF = dY0 - dX0 * sin ( dAngle ) - dY0 * cos( dAngle );
|
||
|
||
BOOL bFlipX = nFlags & 1;
|
||
BOOL bFlipY = nFlags & 2;
|
||
|
||
if ( !bFlipX && !bFlipY )
|
||
{
|
||
// Ничего не делаем
|
||
}
|
||
else if ( bFlipX && !bFlipY )
|
||
{
|
||
dA = -dA;
|
||
dC = -dC;
|
||
dE = -dE + 2 * dX0;
|
||
}
|
||
else if ( !bFlipX && bFlipY )
|
||
{
|
||
dB = -dB;
|
||
dD = -dD;
|
||
dF = -dF + 2 * dY0;
|
||
}
|
||
else
|
||
{
|
||
dA = -dA;
|
||
dB = -dB;
|
||
dC = -dC;
|
||
dD = -dD;
|
||
dE = -dE + 2 * dX0;
|
||
dF = -dF + 2 * dY0;
|
||
}
|
||
|
||
if ( FAILED( hRes = Concat( dA, dB, dC, dD, dE, dF ) ) )
|
||
return hRes;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float fA = m_oCommandParams.oMatrix.fA;
|
||
float fB = m_oCommandParams.oMatrix.fB;
|
||
float fC = m_oCommandParams.oMatrix.fC;
|
||
float fD = m_oCommandParams.oMatrix.fD;
|
||
float fE = m_oCommandParams.oMatrix.fE;
|
||
float fF = m_oCommandParams.oMatrix.fF;
|
||
|
||
if ( FAILED( hRes = Concat( fA, -fB, -fC, fD, MMToPDFCoords( fE ) + fC * fPageHeight, fPageHeight - fPageHeight * fD - MMToPDFCoords( fF ) ) ) )
|
||
return hRes;
|
||
}
|
||
}
|
||
|
||
if ( FAILED ( hRes = DrawCurrentImage( fX, fPageHeight - fY - fHeight, fWidth, fHeight ) ) )
|
||
return hRes;
|
||
|
||
ATLTRACE2( _T("GRestore: DrawImage\n") );
|
||
if ( FAILED( hRes = GRestore() ) )
|
||
return hRes;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(DrawImageFromFile)(BSTR bsFilePath, double fX, double fY, double fWidth, double fHeight)
|
||
{
|
||
NSImageExt::CImageExt oExt;
|
||
|
||
#ifdef BUILD_CONFIG_FULL_VERSION
|
||
AVSGraphics::IASCRenderer* render = NULL;
|
||
if (SUCCEEDED(QueryInterface(__uuidof(AVSGraphics::IASCRenderer), (void**)&render)))
|
||
{
|
||
if (render)
|
||
{
|
||
BOOL bRes = oExt.DrawOnRenderer(render, bsFilePath, fX, fY, fWidth, fHeight);
|
||
RELEASEINTERFACE(render);
|
||
|
||
if (bRes)
|
||
return S_OK;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
IUnknown* pImage = ImageUtils::LoadImage(CString(bsFilePath));
|
||
if (NULL == pImage)
|
||
return S_FALSE;
|
||
|
||
if ( (m_bUseImageTextureAlpha || m_bIsWhiteBackImage) && (NULL != pImage))
|
||
{
|
||
MediaCore::IAVSUncompressedVideoFrame* pUnFrame = NULL;
|
||
pImage->QueryInterface(&pUnFrame);
|
||
|
||
if (NULL != pUnFrame)
|
||
{
|
||
LONG lWidth = 0;
|
||
LONG lHeight = 0;
|
||
BYTE* pBuffer = NULL;
|
||
|
||
pUnFrame->get_Width(&lWidth);
|
||
pUnFrame->get_Height(&lHeight);
|
||
pUnFrame->get_Buffer(&pBuffer);
|
||
|
||
LONG lCountPix = lWidth * lHeight;
|
||
|
||
if ( m_bIsWhiteBackImage )
|
||
{
|
||
while (lCountPix > 0)
|
||
{
|
||
if (0 == pBuffer[3])
|
||
memset(pBuffer, 0xFF, 4);
|
||
|
||
--lCountPix;
|
||
pBuffer += 4;
|
||
}
|
||
}
|
||
else if ( m_bUseImageTextureAlpha )
|
||
{
|
||
while (lCountPix > 0)
|
||
{
|
||
pBuffer[3] *= ((double)m_oBrush.TextureAlpha / 255.0);
|
||
--lCountPix;
|
||
pBuffer += 4;
|
||
}
|
||
}
|
||
|
||
RELEASEINTERFACE(pUnFrame);
|
||
}
|
||
}
|
||
|
||
HRESULT hRes = S_OK;
|
||
if (FAILED(hRes = DrawImage(pImage, fX, fY, fWidth, fHeight)))
|
||
{
|
||
RELEASEINTERFACE(pImage);
|
||
return hRes;
|
||
}
|
||
|
||
RELEASEINTERFACE(pImage);
|
||
|
||
return S_OK;
|
||
}
|
||
//--------- Transform ----------------------------------------------------------------------------
|
||
STDMETHOD(GetCommandParams)(double *pdAngle, double *pdLeft, double *pdTop, double *pdWidth, double *pdHeight, DWORD *pnFlags )
|
||
{
|
||
*pdAngle = -m_oCommandParams.dAngle;
|
||
*pdLeft = m_oCommandParams.dLeft;
|
||
*pdHeight = m_oCommandParams.dHeight;
|
||
*pdWidth = m_oCommandParams.dWidth;
|
||
*pdTop = m_oCommandParams.dTop;
|
||
*pnFlags = m_oCommandParams.nFlag;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SetCommandParams)(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD nFlags )
|
||
{
|
||
if ( 0 != nFlags )
|
||
ATLTRACE2( _T("SetCommandParams: Flip <--------------------------------------------- \n") );
|
||
HRESULT hRes = S_OK;
|
||
|
||
m_oCommandParams.dAngle = -dAngle;
|
||
m_oCommandParams.dLeft = dLeft;
|
||
m_oCommandParams.dHeight = dHeight;
|
||
m_oCommandParams.dWidth = dWidth;
|
||
m_oCommandParams.dTop = dTop;
|
||
m_oCommandParams.nFlag = nFlags;
|
||
|
||
if ( !(0 == nFlags && 0 == dAngle) )
|
||
{
|
||
LONG lLeft = dLeft;
|
||
LONG lTop = dTop;
|
||
LONG lWidth = dWidth;
|
||
LONG lHeight = dHeight;
|
||
|
||
dAngle = dAngle * 3.141592f / 180;
|
||
|
||
// Высчитываем центр прямоугольника ( относительно него производится поворот )
|
||
|
||
double dX0 = lLeft + lWidth / 2;
|
||
double dY0 = lTop + lHeight / 2;
|
||
|
||
// Рассчитываем flip
|
||
BOOL bFlipX = ( 0 != ( 1 & nFlags ) );
|
||
BOOL bFlipY = ( 0 != ( 2 & nFlags ) );
|
||
|
||
LONG lFlipX = bFlipX ? -1 : 1;
|
||
LONG lFlipY = bFlipY ? -1 : 1;
|
||
|
||
// Наше преобразование можно записать в виде произведения матриц:
|
||
//
|
||
// | 1 0 0 | | cos(p) sin(p) 0 | | ScaleX 0 0 | | 1 0 0 |
|
||
// | 0 1 0 | * |-sin(p) cos(p) 0 | * | 0 ScaleY 0 | * | 0 1 0 |
|
||
// |-X0 -Y0 1 | | 0 0 1 | | 0 0 1 | | X0 Y0 1 |
|
||
|
||
double dCos = cos( dAngle );
|
||
double dSin = sin( dAngle );
|
||
|
||
double dA = lFlipX * dCos;
|
||
double dB = lFlipY * dSin;
|
||
double dC = -lFlipX * dSin;
|
||
double dD = lFlipY * dCos;
|
||
double dE = dX0 - lFlipX * dX0 * dCos + lFlipX * dY0 * dSin;
|
||
double dF = dY0 - lFlipY * dX0 * dSin - lFlipY * dY0 * dCos;
|
||
|
||
m_oTransform.Set( dA, dB, dC, dD, dE, dF );
|
||
}
|
||
else
|
||
{
|
||
m_oTransform.Set( 1, 0, 0, 1, 0, 0 );
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetTransform)(double dA, double dB, double dC, double dD, double dE, double dF)
|
||
{
|
||
ATLTRACE2( _T("SetTransform\n") );
|
||
|
||
m_oCommandParams.nFlag = 16;
|
||
|
||
m_oCommandParams.oMatrix.fA = m_oBaseTransform.fA * dA + m_oBaseTransform.fB * dC;
|
||
m_oCommandParams.oMatrix.fC = m_oBaseTransform.fC * dA + m_oBaseTransform.fD * dC;
|
||
m_oCommandParams.oMatrix.fE = m_oBaseTransform.fE * dA + m_oBaseTransform.fF * dC + dE;
|
||
|
||
m_oCommandParams.oMatrix.fB = m_oBaseTransform.fA * dB + m_oBaseTransform.fB * dD;
|
||
m_oCommandParams.oMatrix.fD = m_oBaseTransform.fC * dB + m_oBaseTransform.fD * dD;
|
||
m_oCommandParams.oMatrix.fF = m_oBaseTransform.fE * dB + m_oBaseTransform.fF * dD + dF;
|
||
|
||
m_oTransform.Set( dA, dB, dC, dD, dE, dF );
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(GetTransform)(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
|
||
{
|
||
*pdA = (double)m_oCommandParams.oMatrix.fA;
|
||
*pdB = (double)m_oCommandParams.oMatrix.fB;
|
||
*pdC = (double)m_oCommandParams.oMatrix.fC;
|
||
*pdD = (double)m_oCommandParams.oMatrix.fD;
|
||
*pdE = (double)m_oCommandParams.oMatrix.fE;
|
||
*pdF = (double)m_oCommandParams.oMatrix.fF;
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(ResetTransform)(void)
|
||
{
|
||
m_oCommandParams.nFlag = 16;
|
||
m_oCommandParams.oMatrix.fA = (float)1;
|
||
m_oCommandParams.oMatrix.fB = (float)0;
|
||
m_oCommandParams.oMatrix.fC = (float)0;
|
||
m_oCommandParams.oMatrix.fD = (float)1;
|
||
m_oCommandParams.oMatrix.fE = (float)0;
|
||
m_oCommandParams.oMatrix.fF = (float)0;
|
||
|
||
m_oTransform.Set( 1, 0, 0, 1, 0, 0 );
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//--------- Clip ---------------------------------------------------------------------------------
|
||
STDMETHOD(get_ClipMode)(LONG* plMode)
|
||
{
|
||
*plMode = 0;
|
||
|
||
if ( c_nClipType == m_pCurCommand->nType )
|
||
{
|
||
*plMode = m_pCurCommand->nFlag;
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(put_ClipMode)(LONG lMode)
|
||
{
|
||
if ( c_nClipType == m_pCurCommand->nType )
|
||
{
|
||
m_pCurCommand->nFlag = lMode;
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
//--------- for teamlab --------------------------------------------------------------------------
|
||
|
||
STDMETHOD (OnlineWordToPdf) (BSTR sPathXml, BSTR sDstFile, BSTR sHtmlPlace, LONG nReg);
|
||
|
||
// NODE: пока в виде заглушки
|
||
// NOTE: пока градиенты выставим в виде svg-xml
|
||
|
||
BOOL ApplyFillGradient();
|
||
BOOL ApplyStrokeGradient();
|
||
BOOL CreateLinearGradientFromSvgXml(const CString& sXml, BOOL fill);
|
||
BOOL CreateRadialGradientFromSvgXml(const CString& sXml, BOOL fill);
|
||
|
||
BOOL ApplyTileFill();
|
||
|
||
BOOL RebuildResources();
|
||
|
||
//
|
||
|
||
template<typename T> Proxy GenXRef(T* object, int Type);
|
||
|
||
PDF::Rect PathBounds();
|
||
PDF::Rect PageBounds();
|
||
};
|
||
|
||
#endif
|
||
|