diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 84557cf6f7..7e02cc5fdb 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -39,7 +39,7 @@ "../../../raster/Jp2/openjpeg", "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2" ], "define": [ - "__linux__", "_LINUX", "UNIX", "FT2_BUILD_LIBRARY", "HAVE_FCNTL_H", "FT_CONFIG_OPTION_SYSTEM_ZLIB", "BUILDING_WASM_MODULE", "CMAP_USE_MEMORY", "U_COMMON_IMPLEMENTATION", "errno=0", "THREADMODEL=0", "DEBUGLVL=0", "HAVE_MBSTATE_T", "HAVE_STDINCLUDES", "HAS_WCHAR", "HAVE_VA_COPY", "LIBXML_READER_ENABLED", "LIBXML_PUSH_ENABLED", "LIBXML_HTML_ENABLED", "LIBXML_XPATH_ENABLED", "LIBXML_OUTPUT_ENABLED", "LIBXML_C14N_ENABLED", "LIBXML_SAX1_ENABLED", "LIBXML_TREE_ENABLED", "LIBXML_XPTR_ENABLED", "IN_LIBXML", "LIBXML_STATIC", "BUILD_ZLIB_AS_SOURCES", "DISABLE_PDF_CONVERTATION", "_ARM_ALIGN_", "_tcsnicmp=strncmp", "_lseek=lseek", "_getcwd=getcwd", "NO_CONSOLE_IO", + "__linux__", "_LINUX", "UNIX", "FT2_BUILD_LIBRARY", "HAVE_FCNTL_H", "FT_CONFIG_OPTION_SYSTEM_ZLIB", "BUILDING_WASM_MODULE", "CMAP_USE_MEMORY", "U_COMMON_IMPLEMENTATION", "errno=0", "THREADMODEL=0", "DEBUGLVL=0", "HAVE_MBSTATE_T", "HAVE_STDINCLUDES", "HAS_WCHAR", "HAVE_VA_COPY", "LIBXML_READER_ENABLED", "LIBXML_PUSH_ENABLED", "LIBXML_HTML_ENABLED", "LIBXML_XPATH_ENABLED", "LIBXML_OUTPUT_ENABLED", "LIBXML_C14N_ENABLED", "LIBXML_SAX1_ENABLED", "LIBXML_TREE_ENABLED", "LIBXML_XPTR_ENABLED", "IN_LIBXML", "LIBXML_STATIC", "BUILD_ZLIB_AS_SOURCES", "_ARM_ALIGN_", "_tcsnicmp=strncmp", "_lseek=lseek", "_getcwd=getcwd", "NO_CONSOLE_IO", "USE_EXTERNAL_JPEG2000", "USE_JPIP", "OPJ_STATIC" ], "compile_files_array": [ diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 8d0aa0e47d..1faff2b285 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -77,6 +77,7 @@ HEADERS += \ ../../../MetafileToRenderer.h \ ../../../MetafileToRendererCheck.h \ ../../../MetafileToGraphicsRenderer.h \ + ../../../FormField.h \ ../../../structures.h \ ../../../GraphicsRenderer.h \ \ @@ -108,6 +109,7 @@ SOURCES += \ ../../../Image.cpp \ ../../../MetafileToRenderer.cpp \ ../../../MetafileToGraphicsRenderer.cpp \ + ../../../FormField.cpp \ \ ../../../../fontengine/ApplicationFonts.cpp \ ../../../../fontengine/FontFile.cpp \ @@ -591,7 +593,7 @@ SOURCES += \ $$DJVU_WRAPPER/GURL.cpp # PdfReader -PDF_ROOT_DIR = $$PWD/../../../../../PdfReader +PDF_ROOT_DIR = $$PWD/../../../../../PdfFile INCLUDEPATH += \ $$PDF_ROOT_DIR/lib/goo \ @@ -619,9 +621,9 @@ SOURCES -= \ $$PDF_ROOT_DIR/lib/xpdf/pdfinfo.cc SOURCES += \ - $$PDF_ROOT_DIR/Src/RendererOutputDev.cpp \ - $$PDF_ROOT_DIR/Src/Adaptors.cpp \ - $$PDF_ROOT_DIR/Src/GfxClip.cpp \ + $$PDF_ROOT_DIR/SrcReader/RendererOutputDev.cpp \ + $$PDF_ROOT_DIR/SrcReader/Adaptors.cpp \ + $$PDF_ROOT_DIR/SrcReader/GfxClip.cpp \ $$PDF_ROOT_DIR/Resources/BaseFonts.cpp \ $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.cpp \ $$PDF_ROOT_DIR/PdfReader.cpp @@ -643,10 +645,10 @@ HEADERS +=\ $$PDF_ROOT_DIR/Resources/Fonts050000l.h \ $$PDF_ROOT_DIR/Resources/BaseFonts.h \ $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.h \ - $$PDF_ROOT_DIR/Src/RendererOutputDev.h \ - $$PDF_ROOT_DIR/Src/Adaptors.h \ - $$PDF_ROOT_DIR/Src/MemoryUtils.h \ - $$PDF_ROOT_DIR/Src/GfxClip.h \ + $$PDF_ROOT_DIR/SrcReader/RendererOutputDev.h \ + $$PDF_ROOT_DIR/SrcReader/Adaptors.h \ + $$PDF_ROOT_DIR/SrcReader/MemoryUtils.h \ + $$PDF_ROOT_DIR/SrcReader/GfxClip.h \ $$PDF_ROOT_DIR/PdfReader.h HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h diff --git a/PdfFile/Src/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp similarity index 100% rename from PdfFile/Src/OnlineOfficeBinToPdf.cpp rename to PdfFile/OnlineOfficeBinToPdf.cpp diff --git a/PdfFile/Src/OnlineOfficeBinToPdf.h b/PdfFile/OnlineOfficeBinToPdf.h similarity index 98% rename from PdfFile/Src/OnlineOfficeBinToPdf.h rename to PdfFile/OnlineOfficeBinToPdf.h index f0acd449d2..c4848be42d 100644 --- a/PdfFile/Src/OnlineOfficeBinToPdf.h +++ b/PdfFile/OnlineOfficeBinToPdf.h @@ -33,7 +33,7 @@ #define _PDF_WRITER_ONLINEOFFICEBINTOPDF_H #include -#include "../PdfFile.h" +#include "PdfFile.h" namespace NSOnlineOfficeBinToPdf { diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 43525676e5..02adec7313 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -30,25 +30,25 @@ * */ #include "PdfFile.h" -#include "Src/PdfWriter.h" -#include "Src/OnlineOfficeBinToPdf.h" -#include "Src/PdfReader.h" +#include "PdfWriter.h" +#include "OnlineOfficeBinToPdf.h" +#include "PdfReader.h" -#include "../PdfReader/Src/Adaptors.h" +#include "SrcReader/Adaptors.h" #include "../DesktopEditor/common/File.h" #include "../DesktopEditor/common/Path.h" #include "../DesktopEditor/common/StringExt.h" -#include "../PdfReader/lib/xpdf/PDFDoc.h" -#include "../PdfReader/lib/xpdf/AcroForm.h" -#include "../PdfReader/lib/xpdf/TextString.h" +#include "lib/xpdf/PDFDoc.h" +#include "lib/xpdf/AcroForm.h" +#include "lib/xpdf/TextString.h" -#include "../PdfWriter/Src/Objects.h" -#include "../PdfWriter/Src/Document.h" -#include "../PdfWriter/Src/Pages.h" -#include "../PdfWriter/Src/Catalog.h" -#include "../PdfWriter/Src/EncryptDictionary.h" -#include "../PdfWriter/Src/Info.h" +#include "SrcWriter/Objects.h" +#include "SrcWriter/Document.h" +#include "SrcWriter/Pages.h" +#include "SrcWriter/Catalog.h" +#include "SrcWriter/EncryptDictionary.h" +#include "SrcWriter/Info.h" #define AddToObject(oVal)\ {\ diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index 81adb504f6..79b36f205b 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -29,61 +29,59 @@ LIBS += -lgdi32 \ core_android:DEFINES += ANDROID -PDFREADER_ROOT_DIR = $$PWD/../PdfReader - INCLUDEPATH += \ - $$PDFREADER_ROOT_DIR/lib/goo \ - $$PDFREADER_ROOT_DIR/lib/fofi \ - $$PDFREADER_ROOT_DIR/lib/splash \ - $$PDFREADER_ROOT_DIR/lib + lib/goo \ + lib/fofi \ + lib/splash \ + lib -HEADERS += $$files($$PDFREADER_ROOT_DIR/lib/*.h, true) -SOURCES += $$files($$PDFREADER_ROOT_DIR/lib/*.c, true) -SOURCES += $$files($$PDFREADER_ROOT_DIR/lib/*.cc, true) +HEADERS += $$files(lib/*.h, true) +SOURCES += $$files(lib/*.c, true) +SOURCES += $$files(lib/*.cc, true) SOURCES -= \ - $$PDFREADER_ROOT_DIR/lib/xpdf/HTMLGen.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdftohtml.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdftopng.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdftoppm.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdftops.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdftotext.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdfdetach.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdffonts.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdfimages.cc \ - $$PDFREADER_ROOT_DIR/lib/xpdf/pdfinfo.cc + lib/xpdf/HTMLGen.cc \ + lib/xpdf/pdftohtml.cc \ + lib/xpdf/pdftopng.cc \ + lib/xpdf/pdftoppm.cc \ + lib/xpdf/pdftops.cc \ + lib/xpdf/pdftotext.cc \ + lib/xpdf/pdfdetach.cc \ + lib/xpdf/pdffonts.cc \ + lib/xpdf/pdfimages.cc \ + lib/xpdf/pdfinfo.cc SOURCES += \ - $$PDFREADER_ROOT_DIR/Src/RendererOutputDev.cpp \ - $$PDFREADER_ROOT_DIR/Src/Adaptors.cpp \ - $$PDFREADER_ROOT_DIR/Src/GfxClip.cpp + SrcReader/RendererOutputDev.cpp \ + SrcReader/Adaptors.cpp \ + SrcReader/GfxClip.cpp HEADERS += \ - $$PDFREADER_ROOT_DIR/Src/RendererOutputDev.h \ - $$PDFREADER_ROOT_DIR/Src/Adaptors.h \ - $$PDFREADER_ROOT_DIR/Src/MemoryUtils.h \ - $$PDFREADER_ROOT_DIR/Src/GfxClip.h + SrcReader/RendererOutputDev.h \ + SrcReader/Adaptors.h \ + SrcReader/MemoryUtils.h \ + SrcReader/GfxClip.h # Base fonts HEADERS += \ - $$PDFREADER_ROOT_DIR/Resources/Fontd050000l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn019003l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn019004l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn019023l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn019024l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn021003l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn021004l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn021023l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn021024l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn022003l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn022004l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn022023l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fontn022024l.h \ - $$PDFREADER_ROOT_DIR/Resources/Fonts050000l.h \ - $$PDFREADER_ROOT_DIR/Resources/BaseFonts.h + Resources/Fontd050000l.h \ + Resources/Fontn019003l.h \ + Resources/Fontn019004l.h \ + Resources/Fontn019023l.h \ + Resources/Fontn019024l.h \ + Resources/Fontn021003l.h \ + Resources/Fontn021004l.h \ + Resources/Fontn021023l.h \ + Resources/Fontn021024l.h \ + Resources/Fontn022003l.h \ + Resources/Fontn022004l.h \ + Resources/Fontn022023l.h \ + Resources/Fontn022024l.h \ + Resources/Fonts050000l.h \ + Resources/BaseFonts.h SOURCES += \ - $$PDFREADER_ROOT_DIR/Resources/BaseFonts.cpp + Resources/BaseFonts.cpp CONFIG += use_external_jpeg2000 use_external_jpeg2000 { @@ -94,8 +92,8 @@ use_external_jpeg2000 { } else { DEFINES += USE_GRAPHICS_JPEG2000 } - HEADERS += $$PDFREADER_ROOT_DIR/Src/JPXStream2.h - SOURCES += $$PDFREADER_ROOT_DIR/Src/JPXStream2.cpp + HEADERS += SrcReader/JPXStream2.h + SOURCES += SrcReader/JPXStream2.cpp } #CONFIG += build_viewer_module @@ -133,74 +131,72 @@ core_windows { include($$PWD/../DesktopEditor/graphics/pro/freetype.pri) -PDFWRITER_ROOT_DIR = $$PWD/../PdfWriter - HEADERS += \ - $$PDFWRITER_ROOT_DIR/Src/AcroForm.h \ - $$PDFWRITER_ROOT_DIR/Src/Annotation.h \ - $$PDFWRITER_ROOT_DIR/Src/Catalog.h \ - $$PDFWRITER_ROOT_DIR/Src/Consts.h \ - $$PDFWRITER_ROOT_DIR/Src/Destination.h \ - $$PDFWRITER_ROOT_DIR/Src/Document.h \ - $$PDFWRITER_ROOT_DIR/Src/Encodings.h \ - $$PDFWRITER_ROOT_DIR/Src/Encrypt.h \ - $$PDFWRITER_ROOT_DIR/Src/EncryptDictionary.h \ - $$PDFWRITER_ROOT_DIR/Src/Field.h \ - $$PDFWRITER_ROOT_DIR/Src/Font.h \ - $$PDFWRITER_ROOT_DIR/Src/Font14.h \ - $$PDFWRITER_ROOT_DIR/Src/FontCidTT.h \ - $$PDFWRITER_ROOT_DIR/Src/FontTT.h \ - $$PDFWRITER_ROOT_DIR/Src/FontTTWriter.h \ - $$PDFWRITER_ROOT_DIR/Src/GState.h \ - $$PDFWRITER_ROOT_DIR/Src/Image.h \ - $$PDFWRITER_ROOT_DIR/Src/Info.h \ - $$PDFWRITER_ROOT_DIR/Src/Objects.h \ - $$PDFWRITER_ROOT_DIR/Src/Outline.h \ - $$PDFWRITER_ROOT_DIR/Src/Pages.h \ - $$PDFWRITER_ROOT_DIR/Src/Pattern.h \ - $$PDFWRITER_ROOT_DIR/Src/ResourcesDictionary.h \ - $$PDFWRITER_ROOT_DIR/Src/Shading.h \ - $$PDFWRITER_ROOT_DIR/Src/Streams.h \ - $$PDFWRITER_ROOT_DIR/Src/Types.h \ - $$PDFWRITER_ROOT_DIR/Src/Utils.h \ - $$PDFWRITER_ROOT_DIR/Src/Metadata.h \ - $$PDFWRITER_ROOT_DIR/Src/ICCProfile.h + SrcWriter/AcroForm.h \ + SrcWriter/Annotation.h \ + SrcWriter/Catalog.h \ + SrcWriter/Consts.h \ + SrcWriter/Destination.h \ + SrcWriter/Document.h \ + SrcWriter/Encodings.h \ + SrcWriter/Encrypt.h \ + SrcWriter/EncryptDictionary.h \ + SrcWriter/Field.h \ + SrcWriter/Font.h \ + SrcWriter/Font14.h \ + SrcWriter/FontCidTT.h \ + SrcWriter/FontTT.h \ + SrcWriter/FontTTWriter.h \ + SrcWriter/GState.h \ + SrcWriter/Image.h \ + SrcWriter/Info.h \ + SrcWriter/Objects.h \ + SrcWriter/Outline.h \ + SrcWriter/Pages.h \ + SrcWriter/Pattern.h \ + SrcWriter/ResourcesDictionary.h \ + SrcWriter/Shading.h \ + SrcWriter/Streams.h \ + SrcWriter/Types.h \ + SrcWriter/Utils.h \ + SrcWriter/Metadata.h \ + SrcWriter/ICCProfile.h SOURCES += \ - $$PDFWRITER_ROOT_DIR/Src/AcroForm.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Annotation.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Catalog.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Destination.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Document.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Encrypt.cpp \ - $$PDFWRITER_ROOT_DIR/Src/EncryptDictionary.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Field.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Font.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Font14.cpp \ - $$PDFWRITER_ROOT_DIR/Src/FontCidTT.cpp \ - $$PDFWRITER_ROOT_DIR/Src/FontTT.cpp \ - $$PDFWRITER_ROOT_DIR/Src/FontTTWriter.cpp \ - $$PDFWRITER_ROOT_DIR/Src/GState.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Image.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Info.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Objects.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Outline.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Pages.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Pattern.cpp \ - $$PDFWRITER_ROOT_DIR/Src/ResourcesDictionary.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Shading.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Streams.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Utils.cpp \ - $$PDFWRITER_ROOT_DIR/Src/Metadata.cpp + SrcWriter/AcroForm.cpp \ + SrcWriter/Annotation.cpp \ + SrcWriter/Catalog.cpp \ + SrcWriter/Destination.cpp \ + SrcWriter/Document.cpp \ + SrcWriter/Encrypt.cpp \ + SrcWriter/EncryptDictionary.cpp \ + SrcWriter/Field.cpp \ + SrcWriter/Font.cpp \ + SrcWriter/Font14.cpp \ + SrcWriter/FontCidTT.cpp \ + SrcWriter/FontTT.cpp \ + SrcWriter/FontTTWriter.cpp \ + SrcWriter/GState.cpp \ + SrcWriter/Image.cpp \ + SrcWriter/Info.cpp \ + SrcWriter/Objects.cpp \ + SrcWriter/Outline.cpp \ + SrcWriter/Pages.cpp \ + SrcWriter/Pattern.cpp \ + SrcWriter/ResourcesDictionary.cpp \ + SrcWriter/Shading.cpp \ + SrcWriter/Streams.cpp \ + SrcWriter/Utils.cpp \ + SrcWriter/Metadata.cpp # PdfFile HEADERS += PdfFile.h \ - Src/PdfWriter.h \ - Src/PdfReader.h \ - Src/OnlineOfficeBinToPdf.h + PdfWriter.h \ + PdfReader.h \ + OnlineOfficeBinToPdf.h SOURCES += PdfFile.cpp \ - Src/PdfWriter.cpp \ - Src/PdfReader.cpp \ - Src/OnlineOfficeBinToPdf.cpp + PdfWriter.cpp \ + PdfReader.cpp \ + OnlineOfficeBinToPdf.cpp diff --git a/PdfFile/Src/PdfReader.cpp b/PdfFile/PdfReader.cpp similarity index 96% rename from PdfFile/Src/PdfReader.cpp rename to PdfFile/PdfReader.cpp index 3984c172b5..cdc4e74ff1 100644 --- a/PdfFile/Src/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -34,26 +34,23 @@ #include "PdfReader.h" -#include "../../PdfReader/Src/Adaptors.h" -#include "../../PdfReader/lib/xpdf/ErrorCodes.h" - #include "../../DesktopEditor/graphics/IRenderer.h" #include "../../DesktopEditor/common/Directory.h" #include "../../DesktopEditor/common/StringExt.h" - -#include "../../PdfReader/lib/xpdf/PDFDoc.h" -#include "../../PdfReader/lib/xpdf/GlobalParams.h" -#include "../../PdfReader/lib/xpdf/ErrorCodes.h" -#include "../../PdfReader/lib/xpdf/TextString.h" -#include "../../PdfReader/lib/xpdf/Lexer.h" -#include "../../PdfReader/lib/xpdf/Parser.h" -#include "../../PdfReader/Src/Adaptors.h" - #include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" -#include "../../PdfReader/lib/xpdf/Outline.h" -#include "../../PdfReader/lib/xpdf/Link.h" -#include "../../PdfReader/lib/xpdf/TextOutputDev.h" -#include "../../PdfReader/lib/goo/GList.h" + +#include "lib/xpdf/PDFDoc.h" +#include "lib/xpdf/GlobalParams.h" +#include "lib/xpdf/ErrorCodes.h" +#include "lib/xpdf/TextString.h" +#include "lib/xpdf/Lexer.h" +#include "lib/xpdf/Parser.h" +#include "SrcReader/Adaptors.h" +#include "lib/xpdf/Outline.h" +#include "lib/xpdf/Link.h" +#include "lib/xpdf/TextOutputDev.h" +#include "lib/goo/GList.h" + #include CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) diff --git a/PdfFile/Src/PdfReader.h b/PdfFile/PdfReader.h similarity index 98% rename from PdfFile/Src/PdfReader.h rename to PdfFile/PdfReader.h index 7df24f9f92..bd169aaaac 100644 --- a/PdfFile/Src/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -34,7 +34,7 @@ #include "../../DesktopEditor/graphics/pro/Fonts.h" #include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../PdfReader/Src/RendererOutputDev.h" +#include "SrcReader/RendererOutputDev.h" class PDFDoc; class CPdfReader diff --git a/PdfFile/Src/PdfWriter.cpp b/PdfFile/PdfWriter.cpp similarity index 99% rename from PdfFile/Src/PdfWriter.cpp rename to PdfFile/PdfWriter.cpp index 3035efb006..97ff411613 100644 --- a/PdfFile/Src/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -34,15 +34,15 @@ #include "PdfWriter.h" -#include "../../PdfWriter/Src/Document.h" -#include "../../PdfWriter/Src/Pages.h" -#include "../../PdfWriter/Src/Image.h" -#include "../../PdfWriter/Src/Font.h" -#include "../../PdfWriter/Src/FontCidTT.h" -#include "../../PdfWriter/Src/FontTT.h" -#include "../../PdfWriter/Src/Annotation.h" -#include "../../PdfWriter/Src/Destination.h" -#include "../../PdfWriter/Src/Field.h" +#include "SrcWriter/Document.h" +#include "SrcWriter/Pages.h" +#include "SrcWriter/Image.h" +#include "SrcWriter/Font.h" +#include "SrcWriter/FontCidTT.h" +#include "SrcWriter/FontTT.h" +#include "SrcWriter/Annotation.h" +#include "SrcWriter/Destination.h" +#include "SrcWriter/Field.h" #include "../../DesktopEditor/graphics/Image.h" #include "../../DesktopEditor/graphics/structures.h" diff --git a/PdfFile/Src/PdfWriter.h b/PdfFile/PdfWriter.h similarity index 100% rename from PdfFile/Src/PdfWriter.h rename to PdfFile/PdfWriter.h diff --git a/PdfReader/Resources/BaseFonts.cpp b/PdfFile/Resources/BaseFonts.cpp similarity index 100% rename from PdfReader/Resources/BaseFonts.cpp rename to PdfFile/Resources/BaseFonts.cpp diff --git a/PdfReader/Resources/BaseFonts.h b/PdfFile/Resources/BaseFonts.h similarity index 100% rename from PdfReader/Resources/BaseFonts.h rename to PdfFile/Resources/BaseFonts.h diff --git a/PdfReader/Resources/CMap/Adobe-CNS1.cidToUnicode b/PdfFile/Resources/CMap/Adobe-CNS1.cidToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Adobe-CNS1.cidToUnicode rename to PdfFile/Resources/CMap/Adobe-CNS1.cidToUnicode diff --git a/PdfReader/Resources/CMap/Adobe-GB1.cidToUnicode b/PdfFile/Resources/CMap/Adobe-GB1.cidToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Adobe-GB1.cidToUnicode rename to PdfFile/Resources/CMap/Adobe-GB1.cidToUnicode diff --git a/PdfReader/Resources/CMap/Adobe-Japan1.cidToUnicode b/PdfFile/Resources/CMap/Adobe-Japan1.cidToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Adobe-Japan1.cidToUnicode rename to PdfFile/Resources/CMap/Adobe-Japan1.cidToUnicode diff --git a/PdfReader/Resources/CMap/Adobe-KR.cidToUnicode b/PdfFile/Resources/CMap/Adobe-KR.cidToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Adobe-KR.cidToUnicode rename to PdfFile/Resources/CMap/Adobe-KR.cidToUnicode diff --git a/PdfReader/Resources/CMap/Adobe-Korea1.cidToUnicode b/PdfFile/Resources/CMap/Adobe-Korea1.cidToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Adobe-Korea1.cidToUnicode rename to PdfFile/Resources/CMap/Adobe-Korea1.cidToUnicode diff --git a/PdfReader/Resources/CMap/Big5.unicodeMap b/PdfFile/Resources/CMap/Big5.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/Big5.unicodeMap rename to PdfFile/Resources/CMap/Big5.unicodeMap diff --git a/PdfReader/Resources/CMap/Big5ascii.unicodeMap b/PdfFile/Resources/CMap/Big5ascii.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/Big5ascii.unicodeMap rename to PdfFile/Resources/CMap/Big5ascii.unicodeMap diff --git a/PdfReader/Resources/CMap/Bulgarian.nameToUnicode b/PdfFile/Resources/CMap/Bulgarian.nameToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Bulgarian.nameToUnicode rename to PdfFile/Resources/CMap/Bulgarian.nameToUnicode diff --git a/PdfReader/Resources/CMap/CMap/78-EUC-H b/PdfFile/Resources/CMap/CMap/78-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-EUC-H rename to PdfFile/Resources/CMap/CMap/78-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/78-EUC-V b/PdfFile/Resources/CMap/CMap/78-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-EUC-V rename to PdfFile/Resources/CMap/CMap/78-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/78-H b/PdfFile/Resources/CMap/CMap/78-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-H rename to PdfFile/Resources/CMap/CMap/78-H diff --git a/PdfReader/Resources/CMap/CMap/78-RKSJ-H b/PdfFile/Resources/CMap/CMap/78-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-RKSJ-H rename to PdfFile/Resources/CMap/CMap/78-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/78-RKSJ-V b/PdfFile/Resources/CMap/CMap/78-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-RKSJ-V rename to PdfFile/Resources/CMap/CMap/78-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/78-V b/PdfFile/Resources/CMap/CMap/78-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/78-V rename to PdfFile/Resources/CMap/CMap/78-V diff --git a/PdfReader/Resources/CMap/CMap/78ms-RKSJ-H b/PdfFile/Resources/CMap/CMap/78ms-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/78ms-RKSJ-H rename to PdfFile/Resources/CMap/CMap/78ms-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/78ms-RKSJ-V b/PdfFile/Resources/CMap/CMap/78ms-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/78ms-RKSJ-V rename to PdfFile/Resources/CMap/CMap/78ms-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/83pv-RKSJ-H b/PdfFile/Resources/CMap/CMap/83pv-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/83pv-RKSJ-H rename to PdfFile/Resources/CMap/CMap/83pv-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/90ms-RKSJ-H b/PdfFile/Resources/CMap/CMap/90ms-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/90ms-RKSJ-H rename to PdfFile/Resources/CMap/CMap/90ms-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/90ms-RKSJ-UCS2 b/PdfFile/Resources/CMap/CMap/90ms-RKSJ-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/90ms-RKSJ-UCS2 rename to PdfFile/Resources/CMap/CMap/90ms-RKSJ-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/90ms-RKSJ-V b/PdfFile/Resources/CMap/CMap/90ms-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/90ms-RKSJ-V rename to PdfFile/Resources/CMap/CMap/90ms-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/90msp-RKSJ-H b/PdfFile/Resources/CMap/CMap/90msp-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/90msp-RKSJ-H rename to PdfFile/Resources/CMap/CMap/90msp-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/90msp-RKSJ-V b/PdfFile/Resources/CMap/CMap/90msp-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/90msp-RKSJ-V rename to PdfFile/Resources/CMap/CMap/90msp-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/90pv-RKSJ-H b/PdfFile/Resources/CMap/CMap/90pv-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/90pv-RKSJ-H rename to PdfFile/Resources/CMap/CMap/90pv-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/90pv-RKSJ-UCS2 b/PdfFile/Resources/CMap/CMap/90pv-RKSJ-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/90pv-RKSJ-UCS2 rename to PdfFile/Resources/CMap/CMap/90pv-RKSJ-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/90pv-RKSJ-UCS2C b/PdfFile/Resources/CMap/CMap/90pv-RKSJ-UCS2C similarity index 100% rename from PdfReader/Resources/CMap/CMap/90pv-RKSJ-UCS2C rename to PdfFile/Resources/CMap/CMap/90pv-RKSJ-UCS2C diff --git a/PdfReader/Resources/CMap/CMap/90pv-RKSJ-V b/PdfFile/Resources/CMap/CMap/90pv-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/90pv-RKSJ-V rename to PdfFile/Resources/CMap/CMap/90pv-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/Add-H b/PdfFile/Resources/CMap/CMap/Add-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/Add-H rename to PdfFile/Resources/CMap/CMap/Add-H diff --git a/PdfReader/Resources/CMap/CMap/Add-RKSJ-H b/PdfFile/Resources/CMap/CMap/Add-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/Add-RKSJ-H rename to PdfFile/Resources/CMap/CMap/Add-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/Add-RKSJ-V b/PdfFile/Resources/CMap/CMap/Add-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/Add-RKSJ-V rename to PdfFile/Resources/CMap/CMap/Add-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/Add-V b/PdfFile/Resources/CMap/CMap/Add-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/Add-V rename to PdfFile/Resources/CMap/CMap/Add-V diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-0 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-0 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-0 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-0 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-1 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-1 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-1 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-1 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-2 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-2 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-3 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-3 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-3 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-3 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-4 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-4 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-4 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-4 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-5 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-5 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-5 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-5 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-6 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-6 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-6 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-6 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-7 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-7 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-7 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-7 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-CNS1-UCS2 b/PdfFile/Resources/CMap/CMap/Adobe-CNS1-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-CNS1-UCS2 rename to PdfFile/Resources/CMap/CMap/Adobe-CNS1-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-0 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-0 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-0 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-0 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-1 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-1 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-1 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-1 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-2 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-2 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-3 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-3 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-3 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-3 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-4 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-4 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-4 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-4 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-5 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-5 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-5 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-5 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-GB1-UCS2 b/PdfFile/Resources/CMap/CMap/Adobe-GB1-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-GB1-UCS2 rename to PdfFile/Resources/CMap/CMap/Adobe-GB1-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-0 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-0 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-0 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-0 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-1 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-1 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-1 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-1 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-2 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-2 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-3 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-3 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-3 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-3 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-4 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-4 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-4 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-4 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-5 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-5 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-5 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-5 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-6 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-6 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-6 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-6 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-7 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-7 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-7 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-7 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Japan1-UCS2 b/PdfFile/Resources/CMap/CMap/Adobe-Japan1-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Japan1-UCS2 rename to PdfFile/Resources/CMap/CMap/Adobe-Japan1-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-0 b/PdfFile/Resources/CMap/CMap/Adobe-KR-0 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-0 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-0 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-1 b/PdfFile/Resources/CMap/CMap/Adobe-KR-1 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-1 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-1 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-2 b/PdfFile/Resources/CMap/CMap/Adobe-KR-2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-2 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-3 b/PdfFile/Resources/CMap/CMap/Adobe-KR-3 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-3 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-3 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-4 b/PdfFile/Resources/CMap/CMap/Adobe-KR-4 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-4 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-4 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-5 b/PdfFile/Resources/CMap/CMap/Adobe-KR-5 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-5 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-5 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-6 b/PdfFile/Resources/CMap/CMap/Adobe-KR-6 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-6 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-6 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-7 b/PdfFile/Resources/CMap/CMap/Adobe-KR-7 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-7 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-7 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-8 b/PdfFile/Resources/CMap/CMap/Adobe-KR-8 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-8 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-8 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-KR-9 b/PdfFile/Resources/CMap/CMap/Adobe-KR-9 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-KR-9 rename to PdfFile/Resources/CMap/CMap/Adobe-KR-9 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Korea1-0 b/PdfFile/Resources/CMap/CMap/Adobe-Korea1-0 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Korea1-0 rename to PdfFile/Resources/CMap/CMap/Adobe-Korea1-0 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Korea1-1 b/PdfFile/Resources/CMap/CMap/Adobe-Korea1-1 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Korea1-1 rename to PdfFile/Resources/CMap/CMap/Adobe-Korea1-1 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Korea1-2 b/PdfFile/Resources/CMap/CMap/Adobe-Korea1-2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Korea1-2 rename to PdfFile/Resources/CMap/CMap/Adobe-Korea1-2 diff --git a/PdfReader/Resources/CMap/CMap/Adobe-Korea1-UCS2 b/PdfFile/Resources/CMap/CMap/Adobe-Korea1-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/Adobe-Korea1-UCS2 rename to PdfFile/Resources/CMap/CMap/Adobe-Korea1-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/B5-H b/PdfFile/Resources/CMap/CMap/B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5-H rename to PdfFile/Resources/CMap/CMap/B5-H diff --git a/PdfReader/Resources/CMap/CMap/B5-V b/PdfFile/Resources/CMap/CMap/B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5-V rename to PdfFile/Resources/CMap/CMap/B5-V diff --git a/PdfReader/Resources/CMap/CMap/B5pc-H b/PdfFile/Resources/CMap/CMap/B5pc-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5pc-H rename to PdfFile/Resources/CMap/CMap/B5pc-H diff --git a/PdfReader/Resources/CMap/CMap/B5pc-UCS2 b/PdfFile/Resources/CMap/CMap/B5pc-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5pc-UCS2 rename to PdfFile/Resources/CMap/CMap/B5pc-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/B5pc-UCS2C b/PdfFile/Resources/CMap/CMap/B5pc-UCS2C similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5pc-UCS2C rename to PdfFile/Resources/CMap/CMap/B5pc-UCS2C diff --git a/PdfReader/Resources/CMap/CMap/B5pc-V b/PdfFile/Resources/CMap/CMap/B5pc-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/B5pc-V rename to PdfFile/Resources/CMap/CMap/B5pc-V diff --git a/PdfReader/Resources/CMap/CMap/CNS-EUC-H b/PdfFile/Resources/CMap/CMap/CNS-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS-EUC-H rename to PdfFile/Resources/CMap/CMap/CNS-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/CNS-EUC-V b/PdfFile/Resources/CMap/CMap/CNS-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS-EUC-V rename to PdfFile/Resources/CMap/CMap/CNS-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/CNS1-H b/PdfFile/Resources/CMap/CMap/CNS1-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS1-H rename to PdfFile/Resources/CMap/CMap/CNS1-H diff --git a/PdfReader/Resources/CMap/CMap/CNS1-V b/PdfFile/Resources/CMap/CMap/CNS1-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS1-V rename to PdfFile/Resources/CMap/CMap/CNS1-V diff --git a/PdfReader/Resources/CMap/CMap/CNS2-H b/PdfFile/Resources/CMap/CMap/CNS2-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS2-H rename to PdfFile/Resources/CMap/CMap/CNS2-H diff --git a/PdfReader/Resources/CMap/CMap/CNS2-V b/PdfFile/Resources/CMap/CMap/CNS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/CNS2-V rename to PdfFile/Resources/CMap/CMap/CNS2-V diff --git a/PdfReader/Resources/CMap/CMap/ETHK-B5-H b/PdfFile/Resources/CMap/CMap/ETHK-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETHK-B5-H rename to PdfFile/Resources/CMap/CMap/ETHK-B5-H diff --git a/PdfReader/Resources/CMap/CMap/ETHK-B5-V b/PdfFile/Resources/CMap/CMap/ETHK-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETHK-B5-V rename to PdfFile/Resources/CMap/CMap/ETHK-B5-V diff --git a/PdfReader/Resources/CMap/CMap/ETen-B5-H b/PdfFile/Resources/CMap/CMap/ETen-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETen-B5-H rename to PdfFile/Resources/CMap/CMap/ETen-B5-H diff --git a/PdfReader/Resources/CMap/CMap/ETen-B5-UCS2 b/PdfFile/Resources/CMap/CMap/ETen-B5-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETen-B5-UCS2 rename to PdfFile/Resources/CMap/CMap/ETen-B5-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/ETen-B5-V b/PdfFile/Resources/CMap/CMap/ETen-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETen-B5-V rename to PdfFile/Resources/CMap/CMap/ETen-B5-V diff --git a/PdfReader/Resources/CMap/CMap/ETenms-B5-H b/PdfFile/Resources/CMap/CMap/ETenms-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETenms-B5-H rename to PdfFile/Resources/CMap/CMap/ETenms-B5-H diff --git a/PdfReader/Resources/CMap/CMap/ETenms-B5-V b/PdfFile/Resources/CMap/CMap/ETenms-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/ETenms-B5-V rename to PdfFile/Resources/CMap/CMap/ETenms-B5-V diff --git a/PdfReader/Resources/CMap/CMap/EUC-H b/PdfFile/Resources/CMap/CMap/EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/EUC-H rename to PdfFile/Resources/CMap/CMap/EUC-H diff --git a/PdfReader/Resources/CMap/CMap/EUC-V b/PdfFile/Resources/CMap/CMap/EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/EUC-V rename to PdfFile/Resources/CMap/CMap/EUC-V diff --git a/PdfReader/Resources/CMap/CMap/Ext-H b/PdfFile/Resources/CMap/CMap/Ext-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/Ext-H rename to PdfFile/Resources/CMap/CMap/Ext-H diff --git a/PdfReader/Resources/CMap/CMap/Ext-RKSJ-H b/PdfFile/Resources/CMap/CMap/Ext-RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/Ext-RKSJ-H rename to PdfFile/Resources/CMap/CMap/Ext-RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/Ext-RKSJ-V b/PdfFile/Resources/CMap/CMap/Ext-RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/Ext-RKSJ-V rename to PdfFile/Resources/CMap/CMap/Ext-RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/Ext-V b/PdfFile/Resources/CMap/CMap/Ext-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/Ext-V rename to PdfFile/Resources/CMap/CMap/Ext-V diff --git a/PdfReader/Resources/CMap/CMap/GB-EUC-H b/PdfFile/Resources/CMap/CMap/GB-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GB-EUC-H rename to PdfFile/Resources/CMap/CMap/GB-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GB-EUC-V b/PdfFile/Resources/CMap/CMap/GB-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GB-EUC-V rename to PdfFile/Resources/CMap/CMap/GB-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/GB-H b/PdfFile/Resources/CMap/CMap/GB-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GB-H rename to PdfFile/Resources/CMap/CMap/GB-H diff --git a/PdfReader/Resources/CMap/CMap/GB-V b/PdfFile/Resources/CMap/CMap/GB-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GB-V rename to PdfFile/Resources/CMap/CMap/GB-V diff --git a/PdfReader/Resources/CMap/CMap/GBK-EUC-H b/PdfFile/Resources/CMap/CMap/GBK-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBK-EUC-H rename to PdfFile/Resources/CMap/CMap/GBK-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GBK-EUC-UCS2 b/PdfFile/Resources/CMap/CMap/GBK-EUC-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBK-EUC-UCS2 rename to PdfFile/Resources/CMap/CMap/GBK-EUC-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/GBK-EUC-V b/PdfFile/Resources/CMap/CMap/GBK-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBK-EUC-V rename to PdfFile/Resources/CMap/CMap/GBK-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/GBK2K-H b/PdfFile/Resources/CMap/CMap/GBK2K-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBK2K-H rename to PdfFile/Resources/CMap/CMap/GBK2K-H diff --git a/PdfReader/Resources/CMap/CMap/GBK2K-V b/PdfFile/Resources/CMap/CMap/GBK2K-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBK2K-V rename to PdfFile/Resources/CMap/CMap/GBK2K-V diff --git a/PdfReader/Resources/CMap/CMap/GBKp-EUC-H b/PdfFile/Resources/CMap/CMap/GBKp-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBKp-EUC-H rename to PdfFile/Resources/CMap/CMap/GBKp-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GBKp-EUC-V b/PdfFile/Resources/CMap/CMap/GBKp-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBKp-EUC-V rename to PdfFile/Resources/CMap/CMap/GBKp-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/GBT-EUC-H b/PdfFile/Resources/CMap/CMap/GBT-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBT-EUC-H rename to PdfFile/Resources/CMap/CMap/GBT-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GBT-EUC-V b/PdfFile/Resources/CMap/CMap/GBT-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBT-EUC-V rename to PdfFile/Resources/CMap/CMap/GBT-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/GBT-H b/PdfFile/Resources/CMap/CMap/GBT-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBT-H rename to PdfFile/Resources/CMap/CMap/GBT-H diff --git a/PdfReader/Resources/CMap/CMap/GBT-V b/PdfFile/Resources/CMap/CMap/GBT-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBT-V rename to PdfFile/Resources/CMap/CMap/GBT-V diff --git a/PdfReader/Resources/CMap/CMap/GBTpc-EUC-H b/PdfFile/Resources/CMap/CMap/GBTpc-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBTpc-EUC-H rename to PdfFile/Resources/CMap/CMap/GBTpc-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GBTpc-EUC-V b/PdfFile/Resources/CMap/CMap/GBTpc-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBTpc-EUC-V rename to PdfFile/Resources/CMap/CMap/GBTpc-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/GBpc-EUC-H b/PdfFile/Resources/CMap/CMap/GBpc-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBpc-EUC-H rename to PdfFile/Resources/CMap/CMap/GBpc-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/GBpc-EUC-UCS2 b/PdfFile/Resources/CMap/CMap/GBpc-EUC-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBpc-EUC-UCS2 rename to PdfFile/Resources/CMap/CMap/GBpc-EUC-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/GBpc-EUC-UCS2C b/PdfFile/Resources/CMap/CMap/GBpc-EUC-UCS2C similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBpc-EUC-UCS2C rename to PdfFile/Resources/CMap/CMap/GBpc-EUC-UCS2C diff --git a/PdfReader/Resources/CMap/CMap/GBpc-EUC-V b/PdfFile/Resources/CMap/CMap/GBpc-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/GBpc-EUC-V rename to PdfFile/Resources/CMap/CMap/GBpc-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/H b/PdfFile/Resources/CMap/CMap/H similarity index 100% rename from PdfReader/Resources/CMap/CMap/H rename to PdfFile/Resources/CMap/CMap/H diff --git a/PdfReader/Resources/CMap/CMap/HKdla-B5-H b/PdfFile/Resources/CMap/CMap/HKdla-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKdla-B5-H rename to PdfFile/Resources/CMap/CMap/HKdla-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKdla-B5-V b/PdfFile/Resources/CMap/CMap/HKdla-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKdla-B5-V rename to PdfFile/Resources/CMap/CMap/HKdla-B5-V diff --git a/PdfReader/Resources/CMap/CMap/HKdlb-B5-H b/PdfFile/Resources/CMap/CMap/HKdlb-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKdlb-B5-H rename to PdfFile/Resources/CMap/CMap/HKdlb-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKdlb-B5-V b/PdfFile/Resources/CMap/CMap/HKdlb-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKdlb-B5-V rename to PdfFile/Resources/CMap/CMap/HKdlb-B5-V diff --git a/PdfReader/Resources/CMap/CMap/HKgccs-B5-H b/PdfFile/Resources/CMap/CMap/HKgccs-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKgccs-B5-H rename to PdfFile/Resources/CMap/CMap/HKgccs-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKgccs-B5-V b/PdfFile/Resources/CMap/CMap/HKgccs-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKgccs-B5-V rename to PdfFile/Resources/CMap/CMap/HKgccs-B5-V diff --git a/PdfReader/Resources/CMap/CMap/HKm314-B5-H b/PdfFile/Resources/CMap/CMap/HKm314-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKm314-B5-H rename to PdfFile/Resources/CMap/CMap/HKm314-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKm314-B5-V b/PdfFile/Resources/CMap/CMap/HKm314-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKm314-B5-V rename to PdfFile/Resources/CMap/CMap/HKm314-B5-V diff --git a/PdfReader/Resources/CMap/CMap/HKm471-B5-H b/PdfFile/Resources/CMap/CMap/HKm471-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKm471-B5-H rename to PdfFile/Resources/CMap/CMap/HKm471-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKm471-B5-V b/PdfFile/Resources/CMap/CMap/HKm471-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKm471-B5-V rename to PdfFile/Resources/CMap/CMap/HKm471-B5-V diff --git a/PdfReader/Resources/CMap/CMap/HKscs-B5-H b/PdfFile/Resources/CMap/CMap/HKscs-B5-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKscs-B5-H rename to PdfFile/Resources/CMap/CMap/HKscs-B5-H diff --git a/PdfReader/Resources/CMap/CMap/HKscs-B5-V b/PdfFile/Resources/CMap/CMap/HKscs-B5-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/HKscs-B5-V rename to PdfFile/Resources/CMap/CMap/HKscs-B5-V diff --git a/PdfReader/Resources/CMap/CMap/Hankaku b/PdfFile/Resources/CMap/CMap/Hankaku similarity index 100% rename from PdfReader/Resources/CMap/CMap/Hankaku rename to PdfFile/Resources/CMap/CMap/Hankaku diff --git a/PdfReader/Resources/CMap/CMap/Hiragana b/PdfFile/Resources/CMap/CMap/Hiragana similarity index 100% rename from PdfReader/Resources/CMap/CMap/Hiragana rename to PdfFile/Resources/CMap/CMap/Hiragana diff --git a/PdfReader/Resources/CMap/CMap/KSC-EUC-H b/PdfFile/Resources/CMap/CMap/KSC-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-EUC-H rename to PdfFile/Resources/CMap/CMap/KSC-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/KSC-EUC-V b/PdfFile/Resources/CMap/CMap/KSC-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-EUC-V rename to PdfFile/Resources/CMap/CMap/KSC-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/KSC-H b/PdfFile/Resources/CMap/CMap/KSC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-H rename to PdfFile/Resources/CMap/CMap/KSC-H diff --git a/PdfReader/Resources/CMap/CMap/KSC-Johab-H b/PdfFile/Resources/CMap/CMap/KSC-Johab-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-Johab-H rename to PdfFile/Resources/CMap/CMap/KSC-Johab-H diff --git a/PdfReader/Resources/CMap/CMap/KSC-Johab-V b/PdfFile/Resources/CMap/CMap/KSC-Johab-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-Johab-V rename to PdfFile/Resources/CMap/CMap/KSC-Johab-V diff --git a/PdfReader/Resources/CMap/CMap/KSC-V b/PdfFile/Resources/CMap/CMap/KSC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSC-V rename to PdfFile/Resources/CMap/CMap/KSC-V diff --git a/PdfReader/Resources/CMap/CMap/KSCms-UHC-H b/PdfFile/Resources/CMap/CMap/KSCms-UHC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCms-UHC-H rename to PdfFile/Resources/CMap/CMap/KSCms-UHC-H diff --git a/PdfReader/Resources/CMap/CMap/KSCms-UHC-HW-H b/PdfFile/Resources/CMap/CMap/KSCms-UHC-HW-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCms-UHC-HW-H rename to PdfFile/Resources/CMap/CMap/KSCms-UHC-HW-H diff --git a/PdfReader/Resources/CMap/CMap/KSCms-UHC-HW-V b/PdfFile/Resources/CMap/CMap/KSCms-UHC-HW-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCms-UHC-HW-V rename to PdfFile/Resources/CMap/CMap/KSCms-UHC-HW-V diff --git a/PdfReader/Resources/CMap/CMap/KSCms-UHC-UCS2 b/PdfFile/Resources/CMap/CMap/KSCms-UHC-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCms-UHC-UCS2 rename to PdfFile/Resources/CMap/CMap/KSCms-UHC-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/KSCms-UHC-V b/PdfFile/Resources/CMap/CMap/KSCms-UHC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCms-UHC-V rename to PdfFile/Resources/CMap/CMap/KSCms-UHC-V diff --git a/PdfReader/Resources/CMap/CMap/KSCpc-EUC-H b/PdfFile/Resources/CMap/CMap/KSCpc-EUC-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCpc-EUC-H rename to PdfFile/Resources/CMap/CMap/KSCpc-EUC-H diff --git a/PdfReader/Resources/CMap/CMap/KSCpc-EUC-UCS2 b/PdfFile/Resources/CMap/CMap/KSCpc-EUC-UCS2 similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCpc-EUC-UCS2 rename to PdfFile/Resources/CMap/CMap/KSCpc-EUC-UCS2 diff --git a/PdfReader/Resources/CMap/CMap/KSCpc-EUC-UCS2C b/PdfFile/Resources/CMap/CMap/KSCpc-EUC-UCS2C similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCpc-EUC-UCS2C rename to PdfFile/Resources/CMap/CMap/KSCpc-EUC-UCS2C diff --git a/PdfReader/Resources/CMap/CMap/KSCpc-EUC-V b/PdfFile/Resources/CMap/CMap/KSCpc-EUC-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/KSCpc-EUC-V rename to PdfFile/Resources/CMap/CMap/KSCpc-EUC-V diff --git a/PdfReader/Resources/CMap/CMap/Katakana b/PdfFile/Resources/CMap/CMap/Katakana similarity index 100% rename from PdfReader/Resources/CMap/CMap/Katakana rename to PdfFile/Resources/CMap/CMap/Katakana diff --git a/PdfReader/Resources/CMap/CMap/LICENSE.md b/PdfFile/Resources/CMap/CMap/LICENSE.md similarity index 100% rename from PdfReader/Resources/CMap/CMap/LICENSE.md rename to PdfFile/Resources/CMap/CMap/LICENSE.md diff --git a/PdfReader/Resources/CMap/CMap/NWP-H b/PdfFile/Resources/CMap/CMap/NWP-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/NWP-H rename to PdfFile/Resources/CMap/CMap/NWP-H diff --git a/PdfReader/Resources/CMap/CMap/NWP-V b/PdfFile/Resources/CMap/CMap/NWP-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/NWP-V rename to PdfFile/Resources/CMap/CMap/NWP-V diff --git a/PdfReader/Resources/CMap/CMap/RKSJ-H b/PdfFile/Resources/CMap/CMap/RKSJ-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/RKSJ-H rename to PdfFile/Resources/CMap/CMap/RKSJ-H diff --git a/PdfReader/Resources/CMap/CMap/RKSJ-V b/PdfFile/Resources/CMap/CMap/RKSJ-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/RKSJ-V rename to PdfFile/Resources/CMap/CMap/RKSJ-V diff --git a/PdfReader/Resources/CMap/CMap/Roman b/PdfFile/Resources/CMap/CMap/Roman similarity index 100% rename from PdfReader/Resources/CMap/CMap/Roman rename to PdfFile/Resources/CMap/CMap/Roman diff --git a/PdfReader/Resources/CMap/CMap/UniAKR-UTF16-H b/PdfFile/Resources/CMap/CMap/UniAKR-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniAKR-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniAKR-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniAKR-UTF32-H b/PdfFile/Resources/CMap/CMap/UniAKR-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniAKR-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniAKR-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniAKR-UTF8-H b/PdfFile/Resources/CMap/CMap/UniAKR-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniAKR-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniAKR-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UCS2-H b/PdfFile/Resources/CMap/CMap/UniCNS-UCS2-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UCS2-H rename to PdfFile/Resources/CMap/CMap/UniCNS-UCS2-H diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UCS2-V b/PdfFile/Resources/CMap/CMap/UniCNS-UCS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UCS2-V rename to PdfFile/Resources/CMap/CMap/UniCNS-UCS2-V diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF16-H b/PdfFile/Resources/CMap/CMap/UniCNS-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF16-V b/PdfFile/Resources/CMap/CMap/UniCNS-UTF16-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF16-V rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF16-V diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF32-H b/PdfFile/Resources/CMap/CMap/UniCNS-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF32-V b/PdfFile/Resources/CMap/CMap/UniCNS-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF8-H b/PdfFile/Resources/CMap/CMap/UniCNS-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniCNS-UTF8-V b/PdfFile/Resources/CMap/CMap/UniCNS-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniCNS-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniCNS-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UCS2-H b/PdfFile/Resources/CMap/CMap/UniGB-UCS2-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UCS2-H rename to PdfFile/Resources/CMap/CMap/UniGB-UCS2-H diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UCS2-V b/PdfFile/Resources/CMap/CMap/UniGB-UCS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UCS2-V rename to PdfFile/Resources/CMap/CMap/UniGB-UCS2-V diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF16-H b/PdfFile/Resources/CMap/CMap/UniGB-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniGB-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF16-V b/PdfFile/Resources/CMap/CMap/UniGB-UTF16-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF16-V rename to PdfFile/Resources/CMap/CMap/UniGB-UTF16-V diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF32-H b/PdfFile/Resources/CMap/CMap/UniGB-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniGB-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF32-V b/PdfFile/Resources/CMap/CMap/UniGB-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniGB-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF8-H b/PdfFile/Resources/CMap/CMap/UniGB-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniGB-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniGB-UTF8-V b/PdfFile/Resources/CMap/CMap/UniGB-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniGB-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniGB-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UCS2-H b/PdfFile/Resources/CMap/CMap/UniJIS-UCS2-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UCS2-H rename to PdfFile/Resources/CMap/CMap/UniJIS-UCS2-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UCS2-HW-H b/PdfFile/Resources/CMap/CMap/UniJIS-UCS2-HW-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UCS2-HW-H rename to PdfFile/Resources/CMap/CMap/UniJIS-UCS2-HW-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UCS2-HW-V b/PdfFile/Resources/CMap/CMap/UniJIS-UCS2-HW-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UCS2-HW-V rename to PdfFile/Resources/CMap/CMap/UniJIS-UCS2-HW-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UCS2-V b/PdfFile/Resources/CMap/CMap/UniJIS-UCS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UCS2-V rename to PdfFile/Resources/CMap/CMap/UniJIS-UCS2-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF16-H b/PdfFile/Resources/CMap/CMap/UniJIS-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF16-V b/PdfFile/Resources/CMap/CMap/UniJIS-UTF16-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF16-V rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF16-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF32-H b/PdfFile/Resources/CMap/CMap/UniJIS-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF32-V b/PdfFile/Resources/CMap/CMap/UniJIS-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF8-H b/PdfFile/Resources/CMap/CMap/UniJIS-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS-UTF8-V b/PdfFile/Resources/CMap/CMap/UniJIS-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniJIS-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF16-H b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF16-V b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF16-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF16-V rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF16-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF32-H b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF32-V b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF8-H b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniJIS2004-UTF8-V b/PdfFile/Resources/CMap/CMap/UniJIS2004-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJIS2004-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniJIS2004-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/UniJISPro-UCS2-HW-V b/PdfFile/Resources/CMap/CMap/UniJISPro-UCS2-HW-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISPro-UCS2-HW-V rename to PdfFile/Resources/CMap/CMap/UniJISPro-UCS2-HW-V diff --git a/PdfReader/Resources/CMap/CMap/UniJISPro-UCS2-V b/PdfFile/Resources/CMap/CMap/UniJISPro-UCS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISPro-UCS2-V rename to PdfFile/Resources/CMap/CMap/UniJISPro-UCS2-V diff --git a/PdfReader/Resources/CMap/CMap/UniJISPro-UTF8-V b/PdfFile/Resources/CMap/CMap/UniJISPro-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISPro-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniJISPro-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/UniJISX0213-UTF32-H b/PdfFile/Resources/CMap/CMap/UniJISX0213-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISX0213-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniJISX0213-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniJISX0213-UTF32-V b/PdfFile/Resources/CMap/CMap/UniJISX0213-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISX0213-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniJISX0213-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniJISX02132004-UTF32-H b/PdfFile/Resources/CMap/CMap/UniJISX02132004-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISX02132004-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniJISX02132004-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniJISX02132004-UTF32-V b/PdfFile/Resources/CMap/CMap/UniJISX02132004-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniJISX02132004-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniJISX02132004-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UCS2-H b/PdfFile/Resources/CMap/CMap/UniKS-UCS2-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UCS2-H rename to PdfFile/Resources/CMap/CMap/UniKS-UCS2-H diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UCS2-V b/PdfFile/Resources/CMap/CMap/UniKS-UCS2-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UCS2-V rename to PdfFile/Resources/CMap/CMap/UniKS-UCS2-V diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF16-H b/PdfFile/Resources/CMap/CMap/UniKS-UTF16-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF16-H rename to PdfFile/Resources/CMap/CMap/UniKS-UTF16-H diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF16-V b/PdfFile/Resources/CMap/CMap/UniKS-UTF16-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF16-V rename to PdfFile/Resources/CMap/CMap/UniKS-UTF16-V diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF32-H b/PdfFile/Resources/CMap/CMap/UniKS-UTF32-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF32-H rename to PdfFile/Resources/CMap/CMap/UniKS-UTF32-H diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF32-V b/PdfFile/Resources/CMap/CMap/UniKS-UTF32-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF32-V rename to PdfFile/Resources/CMap/CMap/UniKS-UTF32-V diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF8-H b/PdfFile/Resources/CMap/CMap/UniKS-UTF8-H similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF8-H rename to PdfFile/Resources/CMap/CMap/UniKS-UTF8-H diff --git a/PdfReader/Resources/CMap/CMap/UniKS-UTF8-V b/PdfFile/Resources/CMap/CMap/UniKS-UTF8-V similarity index 100% rename from PdfReader/Resources/CMap/CMap/UniKS-UTF8-V rename to PdfFile/Resources/CMap/CMap/UniKS-UTF8-V diff --git a/PdfReader/Resources/CMap/CMap/V b/PdfFile/Resources/CMap/CMap/V similarity index 100% rename from PdfReader/Resources/CMap/CMap/V rename to PdfFile/Resources/CMap/CMap/V diff --git a/PdfReader/Resources/CMap/CMap/WP-Symbol b/PdfFile/Resources/CMap/CMap/WP-Symbol similarity index 100% rename from PdfReader/Resources/CMap/CMap/WP-Symbol rename to PdfFile/Resources/CMap/CMap/WP-Symbol diff --git a/PdfReader/Resources/CMap/EUC-CN.unicodeMap b/PdfFile/Resources/CMap/EUC-CN.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/EUC-CN.unicodeMap rename to PdfFile/Resources/CMap/EUC-CN.unicodeMap diff --git a/PdfReader/Resources/CMap/EUC-JP.unicodeMap b/PdfFile/Resources/CMap/EUC-JP.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/EUC-JP.unicodeMap rename to PdfFile/Resources/CMap/EUC-JP.unicodeMap diff --git a/PdfReader/Resources/CMap/GBK.unicodeMap b/PdfFile/Resources/CMap/GBK.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/GBK.unicodeMap rename to PdfFile/Resources/CMap/GBK.unicodeMap diff --git a/PdfReader/Resources/CMap/Greek.nameToUnicode b/PdfFile/Resources/CMap/Greek.nameToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Greek.nameToUnicode rename to PdfFile/Resources/CMap/Greek.nameToUnicode diff --git a/PdfReader/Resources/CMap/ISO-2022-CN.unicodeMap b/PdfFile/Resources/CMap/ISO-2022-CN.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-2022-CN.unicodeMap rename to PdfFile/Resources/CMap/ISO-2022-CN.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-2022-JP.unicodeMap b/PdfFile/Resources/CMap/ISO-2022-JP.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-2022-JP.unicodeMap rename to PdfFile/Resources/CMap/ISO-2022-JP.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-2022-KR.unicodeMap b/PdfFile/Resources/CMap/ISO-2022-KR.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-2022-KR.unicodeMap rename to PdfFile/Resources/CMap/ISO-2022-KR.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-8859-6.unicodeMap b/PdfFile/Resources/CMap/ISO-8859-6.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-8859-6.unicodeMap rename to PdfFile/Resources/CMap/ISO-8859-6.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-8859-7.unicodeMap b/PdfFile/Resources/CMap/ISO-8859-7.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-8859-7.unicodeMap rename to PdfFile/Resources/CMap/ISO-8859-7.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-8859-8.unicodeMap b/PdfFile/Resources/CMap/ISO-8859-8.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-8859-8.unicodeMap rename to PdfFile/Resources/CMap/ISO-8859-8.unicodeMap diff --git a/PdfReader/Resources/CMap/ISO-8859-9.unicodeMap b/PdfFile/Resources/CMap/ISO-8859-9.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/ISO-8859-9.unicodeMap rename to PdfFile/Resources/CMap/ISO-8859-9.unicodeMap diff --git a/PdfReader/Resources/CMap/KOI8-R.unicodeMap b/PdfFile/Resources/CMap/KOI8-R.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/KOI8-R.unicodeMap rename to PdfFile/Resources/CMap/KOI8-R.unicodeMap diff --git a/PdfReader/Resources/CMap/Latin2.unicodeMap b/PdfFile/Resources/CMap/Latin2.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/Latin2.unicodeMap rename to PdfFile/Resources/CMap/Latin2.unicodeMap diff --git a/PdfReader/Resources/CMap/Shift-JIS.unicodeMap b/PdfFile/Resources/CMap/Shift-JIS.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/Shift-JIS.unicodeMap rename to PdfFile/Resources/CMap/Shift-JIS.unicodeMap diff --git a/PdfReader/Resources/CMap/TIS-620.unicodeMap b/PdfFile/Resources/CMap/TIS-620.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/TIS-620.unicodeMap rename to PdfFile/Resources/CMap/TIS-620.unicodeMap diff --git a/PdfReader/Resources/CMap/Thai.nameToUnicode b/PdfFile/Resources/CMap/Thai.nameToUnicode similarity index 100% rename from PdfReader/Resources/CMap/Thai.nameToUnicode rename to PdfFile/Resources/CMap/Thai.nameToUnicode diff --git a/PdfReader/Resources/CMap/Windows-1255.unicodeMap b/PdfFile/Resources/CMap/Windows-1255.unicodeMap similarity index 100% rename from PdfReader/Resources/CMap/Windows-1255.unicodeMap rename to PdfFile/Resources/CMap/Windows-1255.unicodeMap diff --git a/PdfReader/Resources/CMapMemory/autogen.py b/PdfFile/Resources/CMapMemory/autogen.py similarity index 100% rename from PdfReader/Resources/CMapMemory/autogen.py rename to PdfFile/Resources/CMapMemory/autogen.py diff --git a/PdfReader/Resources/CMapMemory/cmap_memory.cpp b/PdfFile/Resources/CMapMemory/cmap_memory.cpp similarity index 100% rename from PdfReader/Resources/CMapMemory/cmap_memory.cpp rename to PdfFile/Resources/CMapMemory/cmap_memory.cpp diff --git a/PdfReader/Resources/CMapMemory/cmap_memory.h b/PdfFile/Resources/CMapMemory/cmap_memory.h similarity index 100% rename from PdfReader/Resources/CMapMemory/cmap_memory.h rename to PdfFile/Resources/CMapMemory/cmap_memory.h diff --git a/PdfReader/Resources/Fontd050000l.h b/PdfFile/Resources/Fontd050000l.h similarity index 100% rename from PdfReader/Resources/Fontd050000l.h rename to PdfFile/Resources/Fontd050000l.h diff --git a/PdfReader/Resources/Fontn019003l.h b/PdfFile/Resources/Fontn019003l.h similarity index 100% rename from PdfReader/Resources/Fontn019003l.h rename to PdfFile/Resources/Fontn019003l.h diff --git a/PdfReader/Resources/Fontn019004l.h b/PdfFile/Resources/Fontn019004l.h similarity index 100% rename from PdfReader/Resources/Fontn019004l.h rename to PdfFile/Resources/Fontn019004l.h diff --git a/PdfReader/Resources/Fontn019023l.h b/PdfFile/Resources/Fontn019023l.h similarity index 100% rename from PdfReader/Resources/Fontn019023l.h rename to PdfFile/Resources/Fontn019023l.h diff --git a/PdfReader/Resources/Fontn019024l.h b/PdfFile/Resources/Fontn019024l.h similarity index 100% rename from PdfReader/Resources/Fontn019024l.h rename to PdfFile/Resources/Fontn019024l.h diff --git a/PdfReader/Resources/Fontn021003l.h b/PdfFile/Resources/Fontn021003l.h similarity index 100% rename from PdfReader/Resources/Fontn021003l.h rename to PdfFile/Resources/Fontn021003l.h diff --git a/PdfReader/Resources/Fontn021004l.h b/PdfFile/Resources/Fontn021004l.h similarity index 100% rename from PdfReader/Resources/Fontn021004l.h rename to PdfFile/Resources/Fontn021004l.h diff --git a/PdfReader/Resources/Fontn021023l.h b/PdfFile/Resources/Fontn021023l.h similarity index 100% rename from PdfReader/Resources/Fontn021023l.h rename to PdfFile/Resources/Fontn021023l.h diff --git a/PdfReader/Resources/Fontn021024l.h b/PdfFile/Resources/Fontn021024l.h similarity index 100% rename from PdfReader/Resources/Fontn021024l.h rename to PdfFile/Resources/Fontn021024l.h diff --git a/PdfReader/Resources/Fontn022003l.h b/PdfFile/Resources/Fontn022003l.h similarity index 100% rename from PdfReader/Resources/Fontn022003l.h rename to PdfFile/Resources/Fontn022003l.h diff --git a/PdfReader/Resources/Fontn022004l.h b/PdfFile/Resources/Fontn022004l.h similarity index 100% rename from PdfReader/Resources/Fontn022004l.h rename to PdfFile/Resources/Fontn022004l.h diff --git a/PdfReader/Resources/Fontn022023l.h b/PdfFile/Resources/Fontn022023l.h similarity index 100% rename from PdfReader/Resources/Fontn022023l.h rename to PdfFile/Resources/Fontn022023l.h diff --git a/PdfReader/Resources/Fontn022024l.h b/PdfFile/Resources/Fontn022024l.h similarity index 100% rename from PdfReader/Resources/Fontn022024l.h rename to PdfFile/Resources/Fontn022024l.h diff --git a/PdfReader/Resources/Fonts/COPYING b/PdfFile/Resources/Fonts/COPYING similarity index 100% rename from PdfReader/Resources/Fonts/COPYING rename to PdfFile/Resources/Fonts/COPYING diff --git a/PdfReader/Resources/Fonts/LICENSE b/PdfFile/Resources/Fonts/LICENSE similarity index 100% rename from PdfReader/Resources/Fonts/LICENSE rename to PdfFile/Resources/Fonts/LICENSE diff --git a/PdfReader/Resources/Fonts/d050000l.afm b/PdfFile/Resources/Fonts/d050000l.afm similarity index 100% rename from PdfReader/Resources/Fonts/d050000l.afm rename to PdfFile/Resources/Fonts/d050000l.afm diff --git a/PdfReader/Resources/Fonts/d050000l.pfb b/PdfFile/Resources/Fonts/d050000l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/d050000l.pfb rename to PdfFile/Resources/Fonts/d050000l.pfb diff --git a/PdfReader/Resources/Fonts/d050000l.pfm b/PdfFile/Resources/Fonts/d050000l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/d050000l.pfm rename to PdfFile/Resources/Fonts/d050000l.pfm diff --git a/PdfReader/Resources/Fonts/n019003l.afm b/PdfFile/Resources/Fonts/n019003l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n019003l.afm rename to PdfFile/Resources/Fonts/n019003l.afm diff --git a/PdfReader/Resources/Fonts/n019003l.pfb b/PdfFile/Resources/Fonts/n019003l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n019003l.pfb rename to PdfFile/Resources/Fonts/n019003l.pfb diff --git a/PdfReader/Resources/Fonts/n019003l.pfm b/PdfFile/Resources/Fonts/n019003l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n019003l.pfm rename to PdfFile/Resources/Fonts/n019003l.pfm diff --git a/PdfReader/Resources/Fonts/n019004l.afm b/PdfFile/Resources/Fonts/n019004l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n019004l.afm rename to PdfFile/Resources/Fonts/n019004l.afm diff --git a/PdfReader/Resources/Fonts/n019004l.pfb b/PdfFile/Resources/Fonts/n019004l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n019004l.pfb rename to PdfFile/Resources/Fonts/n019004l.pfb diff --git a/PdfReader/Resources/Fonts/n019004l.pfm b/PdfFile/Resources/Fonts/n019004l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n019004l.pfm rename to PdfFile/Resources/Fonts/n019004l.pfm diff --git a/PdfReader/Resources/Fonts/n019023l.afm b/PdfFile/Resources/Fonts/n019023l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n019023l.afm rename to PdfFile/Resources/Fonts/n019023l.afm diff --git a/PdfReader/Resources/Fonts/n019023l.pfb b/PdfFile/Resources/Fonts/n019023l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n019023l.pfb rename to PdfFile/Resources/Fonts/n019023l.pfb diff --git a/PdfReader/Resources/Fonts/n019023l.pfm b/PdfFile/Resources/Fonts/n019023l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n019023l.pfm rename to PdfFile/Resources/Fonts/n019023l.pfm diff --git a/PdfReader/Resources/Fonts/n019024l.afm b/PdfFile/Resources/Fonts/n019024l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n019024l.afm rename to PdfFile/Resources/Fonts/n019024l.afm diff --git a/PdfReader/Resources/Fonts/n019024l.pfb b/PdfFile/Resources/Fonts/n019024l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n019024l.pfb rename to PdfFile/Resources/Fonts/n019024l.pfb diff --git a/PdfReader/Resources/Fonts/n019024l.pfm b/PdfFile/Resources/Fonts/n019024l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n019024l.pfm rename to PdfFile/Resources/Fonts/n019024l.pfm diff --git a/PdfReader/Resources/Fonts/n021003l.afm b/PdfFile/Resources/Fonts/n021003l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n021003l.afm rename to PdfFile/Resources/Fonts/n021003l.afm diff --git a/PdfReader/Resources/Fonts/n021003l.pfb b/PdfFile/Resources/Fonts/n021003l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n021003l.pfb rename to PdfFile/Resources/Fonts/n021003l.pfb diff --git a/PdfReader/Resources/Fonts/n021003l.pfm b/PdfFile/Resources/Fonts/n021003l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n021003l.pfm rename to PdfFile/Resources/Fonts/n021003l.pfm diff --git a/PdfReader/Resources/Fonts/n021004l.afm b/PdfFile/Resources/Fonts/n021004l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n021004l.afm rename to PdfFile/Resources/Fonts/n021004l.afm diff --git a/PdfReader/Resources/Fonts/n021004l.pfb b/PdfFile/Resources/Fonts/n021004l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n021004l.pfb rename to PdfFile/Resources/Fonts/n021004l.pfb diff --git a/PdfReader/Resources/Fonts/n021004l.pfm b/PdfFile/Resources/Fonts/n021004l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n021004l.pfm rename to PdfFile/Resources/Fonts/n021004l.pfm diff --git a/PdfReader/Resources/Fonts/n021023l.afm b/PdfFile/Resources/Fonts/n021023l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n021023l.afm rename to PdfFile/Resources/Fonts/n021023l.afm diff --git a/PdfReader/Resources/Fonts/n021023l.pfb b/PdfFile/Resources/Fonts/n021023l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n021023l.pfb rename to PdfFile/Resources/Fonts/n021023l.pfb diff --git a/PdfReader/Resources/Fonts/n021023l.pfm b/PdfFile/Resources/Fonts/n021023l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n021023l.pfm rename to PdfFile/Resources/Fonts/n021023l.pfm diff --git a/PdfReader/Resources/Fonts/n021024l.afm b/PdfFile/Resources/Fonts/n021024l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n021024l.afm rename to PdfFile/Resources/Fonts/n021024l.afm diff --git a/PdfReader/Resources/Fonts/n021024l.pfb b/PdfFile/Resources/Fonts/n021024l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n021024l.pfb rename to PdfFile/Resources/Fonts/n021024l.pfb diff --git a/PdfReader/Resources/Fonts/n021024l.pfm b/PdfFile/Resources/Fonts/n021024l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n021024l.pfm rename to PdfFile/Resources/Fonts/n021024l.pfm diff --git a/PdfReader/Resources/Fonts/n022003l.afm b/PdfFile/Resources/Fonts/n022003l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n022003l.afm rename to PdfFile/Resources/Fonts/n022003l.afm diff --git a/PdfReader/Resources/Fonts/n022003l.pfb b/PdfFile/Resources/Fonts/n022003l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n022003l.pfb rename to PdfFile/Resources/Fonts/n022003l.pfb diff --git a/PdfReader/Resources/Fonts/n022003l.pfm b/PdfFile/Resources/Fonts/n022003l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n022003l.pfm rename to PdfFile/Resources/Fonts/n022003l.pfm diff --git a/PdfReader/Resources/Fonts/n022004l.afm b/PdfFile/Resources/Fonts/n022004l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n022004l.afm rename to PdfFile/Resources/Fonts/n022004l.afm diff --git a/PdfReader/Resources/Fonts/n022004l.pfb b/PdfFile/Resources/Fonts/n022004l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n022004l.pfb rename to PdfFile/Resources/Fonts/n022004l.pfb diff --git a/PdfReader/Resources/Fonts/n022004l.pfm b/PdfFile/Resources/Fonts/n022004l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n022004l.pfm rename to PdfFile/Resources/Fonts/n022004l.pfm diff --git a/PdfReader/Resources/Fonts/n022023l.afm b/PdfFile/Resources/Fonts/n022023l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n022023l.afm rename to PdfFile/Resources/Fonts/n022023l.afm diff --git a/PdfReader/Resources/Fonts/n022023l.pfb b/PdfFile/Resources/Fonts/n022023l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n022023l.pfb rename to PdfFile/Resources/Fonts/n022023l.pfb diff --git a/PdfReader/Resources/Fonts/n022023l.pfm b/PdfFile/Resources/Fonts/n022023l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n022023l.pfm rename to PdfFile/Resources/Fonts/n022023l.pfm diff --git a/PdfReader/Resources/Fonts/n022024l.afm b/PdfFile/Resources/Fonts/n022024l.afm similarity index 100% rename from PdfReader/Resources/Fonts/n022024l.afm rename to PdfFile/Resources/Fonts/n022024l.afm diff --git a/PdfReader/Resources/Fonts/n022024l.pfb b/PdfFile/Resources/Fonts/n022024l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/n022024l.pfb rename to PdfFile/Resources/Fonts/n022024l.pfb diff --git a/PdfReader/Resources/Fonts/n022024l.pfm b/PdfFile/Resources/Fonts/n022024l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/n022024l.pfm rename to PdfFile/Resources/Fonts/n022024l.pfm diff --git a/PdfReader/Resources/Fonts/s050000l.afm b/PdfFile/Resources/Fonts/s050000l.afm similarity index 100% rename from PdfReader/Resources/Fonts/s050000l.afm rename to PdfFile/Resources/Fonts/s050000l.afm diff --git a/PdfReader/Resources/Fonts/s050000l.pfb b/PdfFile/Resources/Fonts/s050000l.pfb similarity index 100% rename from PdfReader/Resources/Fonts/s050000l.pfb rename to PdfFile/Resources/Fonts/s050000l.pfb diff --git a/PdfReader/Resources/Fonts/s050000l.pfm b/PdfFile/Resources/Fonts/s050000l.pfm similarity index 100% rename from PdfReader/Resources/Fonts/s050000l.pfm rename to PdfFile/Resources/Fonts/s050000l.pfm diff --git a/PdfReader/Resources/Fonts050000l.h b/PdfFile/Resources/Fonts050000l.h similarity index 100% rename from PdfReader/Resources/Fonts050000l.h rename to PdfFile/Resources/Fonts050000l.h diff --git a/PdfReader/Src/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp similarity index 100% rename from PdfReader/Src/Adaptors.cpp rename to PdfFile/SrcReader/Adaptors.cpp diff --git a/PdfReader/Src/Adaptors.h b/PdfFile/SrcReader/Adaptors.h similarity index 100% rename from PdfReader/Src/Adaptors.h rename to PdfFile/SrcReader/Adaptors.h diff --git a/PdfReader/Src/GfxClip.cpp b/PdfFile/SrcReader/GfxClip.cpp similarity index 100% rename from PdfReader/Src/GfxClip.cpp rename to PdfFile/SrcReader/GfxClip.cpp diff --git a/PdfReader/Src/GfxClip.h b/PdfFile/SrcReader/GfxClip.h similarity index 100% rename from PdfReader/Src/GfxClip.h rename to PdfFile/SrcReader/GfxClip.h diff --git a/PdfReader/Src/JPXStream2.cpp b/PdfFile/SrcReader/JPXStream2.cpp similarity index 100% rename from PdfReader/Src/JPXStream2.cpp rename to PdfFile/SrcReader/JPXStream2.cpp diff --git a/PdfReader/Src/JPXStream2.h b/PdfFile/SrcReader/JPXStream2.h similarity index 100% rename from PdfReader/Src/JPXStream2.h rename to PdfFile/SrcReader/JPXStream2.h diff --git a/PdfReader/Src/MemoryUtils.h b/PdfFile/SrcReader/MemoryUtils.h similarity index 100% rename from PdfReader/Src/MemoryUtils.h rename to PdfFile/SrcReader/MemoryUtils.h diff --git a/PdfReader/Src/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp similarity index 99% rename from PdfReader/Src/RendererOutputDev.cpp rename to PdfFile/SrcReader/RendererOutputDev.cpp index c729fd2d50..d8a425f3f6 100644 --- a/PdfReader/Src/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -30,7 +30,7 @@ * */ -#include "../Src/Adaptors.h" +#include "Adaptors.h" #include "../lib/xpdf/ErrorCodes.h" #include "../lib/xpdf/GfxState.h" #include "../lib/xpdf/GfxFont.h" @@ -54,10 +54,6 @@ #include "../../DesktopEditor/graphics/BaseThread.h" #include "../Resources/BaseFonts.h" -#ifndef DISABLE_PDF_CONVERTATION -#include "../../PdfWriter/PdfRenderer.h" -#endif - #ifndef BUILDING_WASM_MODULE #define FONTS_USE_AFM_SETTINGS #else diff --git a/PdfReader/Src/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h similarity index 97% rename from PdfReader/Src/RendererOutputDev.h rename to PdfFile/SrcReader/RendererOutputDev.h index 98069ac26f..4a08fa2d1b 100644 --- a/PdfReader/Src/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -1,342 +1,342 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_RENDERER_OUTPUTDEV_H -#define _PDF_READER_RENDERER_OUTPUTDEV_H - -#include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/Graphics.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" -#include "../../DesktopEditor/graphics/structures.h" -#include "../PdfReader.h" -#include "../lib/xpdf/Gfx.h" - -#include "../lib/xpdf/OutputDev.h" -#include "../lib/xpdf/Object.h" -#include "../lib/xpdf/GlobalParams.h" -#include "XmlUtils.h" -#include "Adaptors.h" -#include "MemoryUtils.h" -#include "GfxClip.h" -#include -#ifdef BUILDING_WASM_MODULE -#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" -#endif - -namespace PdfReader -{ - - - //------------------------------------------------------------------------------------------------------------------------------- - struct TFontEntry - { - Ref oRef; // Ссылка на объект-шрифт - std::wstring wsFilePath; // Путь к шрифту на диске - std::wstring wsFontName; // Имя шрифта, которое записано в PDF(ветка для случаев, когда имя шрифта в самом шрифте не указано) - int *pCodeToGID; // Таблица код - номер глифа в шрифте - int *pCodeToUnicode; // Таблица код - юникодное значение - unsigned int unLenGID; // Количество элементов в таблицах - unsigned int unLenUnicode; // - bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости - - }; - - class CFontList - { - public: - - CFontList(); - ~CFontList(); - void LoadFromFile(std::wstring wsDirPath); - void SaveToFile(std::wstring wsDirPath); - bool Find(Ref oRef, TFontEntry *pEntry); - bool Find2(Ref oRef, TFontEntry **ppEntry); - void Remove(Ref oRef); - TFontEntry *Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int nLenGID, unsigned int nLenUnicode); - void Clear(); - bool GetFont(Ref *pRef, TFontEntry *pEntry); - private: - - TFontEntry* Lookup(Ref& oRef) - { - CRefFontMap::const_iterator oPos = m_oFontMap.find(oRef); - if (m_oFontMap.end() != oPos) - return oPos->second; - - return NULL; - } - void Add(Ref& oRef, TFontEntry* pFontEntry) - { - // До вызова данной функции надо проверять есть ли элемент с данным ключом - m_oFontMap.insert(std::pair(oRef, pFontEntry)); - } - - private: - - typedef std::map CRefFontMap; - CRefFontMap m_oFontMap; - NSCriticalSection::CRITICAL_SECTION m_oCS; // Критическая секция - }; - //------------------------------------------------------------------------------------------------------------------------------- - template - inline static double PDFCoordsToMM(T tX) - { - return ((double)tX / 72.0) * 25.4; - } - - //------------------------------------------------------------------------------------------------------------------------------- - static void FileWrite(void *pStream, char *sData, int nLen) - { - ::fwrite(sData, 1, nLen, (FILE *)pStream); - } - //------------------------------------------------------------------------------------------------------------------------------- - // RendererOutputDev - //------------------------------------------------------------------------------------------------------------------------------- - - class RendererOutputDev : public OutputDev - { - public: - RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList = NULL); - virtual ~RendererOutputDev(); - - virtual GBool upsideDown() - { - return false; - } - virtual GBool useDrawChar() - { - return true; - } - virtual GBool useTilingPatternFill() - { - if (m_bDrawOnlyText) - return true; - - return false; - } - virtual GBool useFunctionalShadedFills() - { - return true; - } - virtual GBool useAxialShadedFills() - { - return true; - } - virtual GBool useRadialShadedFills() - { - return true; - } - virtual GBool useGouraundTriangleFills() - { - return true; - } - virtual GBool usePatchMeshFills() - { - return true; - } - virtual GBool useClipTo() - { - return false;//true; - } - virtual GBool interpretType3Chars() - { - return true; - } - virtual GBool useFillAndStroke() - { - return true; - } - virtual GBool useSimpleTransparentGroup() - { - return true; - } - virtual GBool useSimpleTilingPatternFill() - { - if (NULL == m_pRenderer) - return false; - - // TODO: m_pRenderer->GetAdditionalParam(L"TilingHtmlPattern"); - - return false; - } - virtual GBool isStopped() - { - if (NULL != m_pbBreak) - return *m_pbBreak; - else - return false; - } - //--------------------------------------------------------------------------------------------------------------------------- - virtual void startPage(int nPageIndex, GfxState *pGState); - virtual void endPage(); - //----- Save/Restore GState - virtual void saveState(GfxState *pGState); - virtual void restoreState(GfxState *pGState); - //----- Изменение параметров в GState - virtual void updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32); - virtual void updateLineDash(GfxState *pGState); - virtual void updateFlatness(GfxState *pGState); - virtual void updateLineJoin(GfxState *pGState); - virtual void updateLineCap(GfxState *pGState); - virtual void updateMiterLimit(GfxState *pGState); - virtual void updateLineWidth(GfxState *pGState); - virtual void updateStrokeAdjust(GfxState *pGState); - virtual void updateFillColor(GfxState *pGState); - virtual void updateStrokeColor(GfxState *pGState); - virtual void updateBlendMode(GfxState *pGState); - virtual void updateFillOpacity(GfxState *pGState); - virtual void updateStrokeOpacity(GfxState *pGState); - virtual void updateAll(GfxState *pGState); - virtual void updateRender(GfxState *pGState); - //----- Изменение текстовых параметров - virtual void updateFont(GfxState *pGState); - //----- Рисование Path - virtual void stroke(GfxState *pGState); - virtual void fill(GfxState *pGState); - virtual void eoFill(GfxState *pGState); - virtual void FillStroke(GfxState *pGState); - virtual void EoFillStroke(GfxState *pGState); - virtual void tilingPatternFill(GfxState *pGState, Object *pStream, int nPaintType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep); - virtual void StartTilingFill(GfxState *pGState); - virtual void EndTilingFill(); - //todo overide - virtual GBool shadedFill(GfxState *state, GfxShading *shading); - virtual bool FunctionShadedFill(GfxState *pGState, GfxFunctionShading *pShading); - virtual bool AxialShadedFill(GfxState *pGState, GfxAxialShading *pShading); - virtual bool RadialShadedFill(GfxState *pGState, GfxRadialShading *pShading); - virtual bool GouraundTriangleFill(GfxState *pGState, const std::vector &colors, const std::vector &points); - virtual bool PatchMeshFill(GfxState *pGState, GfxPatch* pPatch, GfxPatchMeshShading *pShading); - virtual void StartShadedFill(GfxState *pGState); - virtual void EndShadedFill(); - virtual void StartTilingFillIteration(); - virtual void EndTilingFillIteration(); - virtual void StartSimpleTilingFill(GfxState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix); - virtual void EndSimpleTilingFill(); - //----- Path clipping - virtual void clip(GfxState *pGState); - virtual void clipAttack(GfxState *pGState) - { - updateClipAttack(pGState); - } - virtual void eoClip(GfxState *pGState); - virtual void clipToStrokePath(GfxState *pGState); - virtual void clipToPath(GfxState *pGState, GfxPath *pPath, double *pMatrix, bool bEO); - //----- Вывод текста - virtual void endTextObject(GfxState *pGState); - virtual void beginStringOp(GfxState *pGState); - virtual void endStringOp(GfxState *pGState); - virtual void drawString(GfxState *pGState, GString *seString); - virtual void drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen); - GBool beginType3Char(GfxState *state, double x, double y, - double dx, double dy, - CharCode code, Unicode *u, int uLen) { - return false; - } - void endType3Char(GfxState *pGState); - void Type3D0(GfxState *pGState, double dWx, double dWy); - void Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy); - //----- Вывод картинок - virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; - virtual void setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; - virtual void drawImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) override; - virtual void drawMaskedImage(GfxState *pGState, - Object *pRef, - Stream *pStream, - int nWidth, int nHeight, - GfxImageColorMap *pColorMap, - Object* pMaskRef, - Stream *pMaskStream, - int nMaskWidth, int nMaskHeight, - GBool bMaskInvert, - GBool interpolate) override; - virtual void drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, - int nWidth, int nHeight, - GfxImageColorMap *pColorMap, - Object *maskRef, Stream *pMaskStream, - int nMaskWidth, int nMaskHeight, - GfxImageColorMap *pMaskColorMap, - double *pMatte, GBool interpolate) override; - //----- Transparency groups и SMasks - virtual void beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask); - virtual void endTransparencyGroup(GfxState *pGState); - virtual void paintTransparencyGroup(GfxState *pGState, double *pBBox); - virtual void setSoftMask(GfxState *pGState, double *pBBox, GBool bAlpha, Function *pTransferFunc, GfxColor *pBackdropColor); - virtual void clearSoftMask(GfxState *pGState); - //----- Дополнительные функции для данного устройства - void NewPDF(XRef *pXref); - void SetBreak(bool* pbBreak) - { - m_pbBreak = pbBreak; - } - - private: - - void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); - void DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM); - void ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double* pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth = 0, double dHeight = 0, double dBaseLineOffset = 0); - void updateClip(GfxState *pGState); - void updateClipAttack(GfxState *pGState); - void DoTransform(double *pMatrix, double *pdShiftX, double *pdShiftY, bool bText = false); - private: - - IRenderer* m_pRenderer; - long m_lRendererType; - double m_arrMatrix[6]; - NSFonts::IFontManager* m_pFontManager; - - //GfxTextClip *m_pBufferTextClip; - - XRef *m_pXref; // Таблица Xref для данного PDF-документа - CFontList *m_pFontList; - - bool *m_pbBreak; // Внешняя остановка рендерера - - std::deque m_sClip; - bool m_bClipChanged; - - bool m_bTiling; - bool m_bTransparentGroup; - bool m_bIsolatedTransparentGroup; - bool m_bTransparentGroupSoftMask; - bool m_bTransparentGroupSoftMaskEnd; - std::vector m_arrTransparentGroupSoftMask; - - unsigned char* m_pSoftMask; - int m_nSoftMaskWidth; - int m_nSoftMaskHeight; - - bool m_bDrawOnlyText; // Special option for html-renderer - - }; -} - -#endif // _PDF_READER_RENDERER_OUTPUTDEV_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_READER_RENDERER_OUTPUTDEV_H +#define _PDF_READER_RENDERER_OUTPUTDEV_H + +#include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/graphics/pro/Graphics.h" +#include "../../DesktopEditor/graphics/TemporaryCS.h" +#include "../../DesktopEditor/graphics/structures.h" +//#include "../PdfReader.h" +#include "../lib/xpdf/Gfx.h" + +#include "../lib/xpdf/OutputDev.h" +#include "../lib/xpdf/Object.h" +#include "../lib/xpdf/GlobalParams.h" +#include "XmlUtils.h" +#include "Adaptors.h" +#include "MemoryUtils.h" +#include "GfxClip.h" +#include +#ifdef BUILDING_WASM_MODULE +#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" +#endif + +namespace PdfReader +{ + + + //------------------------------------------------------------------------------------------------------------------------------- + struct TFontEntry + { + Ref oRef; // Ссылка на объект-шрифт + std::wstring wsFilePath; // Путь к шрифту на диске + std::wstring wsFontName; // Имя шрифта, которое записано в PDF(ветка для случаев, когда имя шрифта в самом шрифте не указано) + int *pCodeToGID; // Таблица код - номер глифа в шрифте + int *pCodeToUnicode; // Таблица код - юникодное значение + unsigned int unLenGID; // Количество элементов в таблицах + unsigned int unLenUnicode; // + bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости + + }; + + class CFontList + { + public: + + CFontList(); + ~CFontList(); + void LoadFromFile(std::wstring wsDirPath); + void SaveToFile(std::wstring wsDirPath); + bool Find(Ref oRef, TFontEntry *pEntry); + bool Find2(Ref oRef, TFontEntry **ppEntry); + void Remove(Ref oRef); + TFontEntry *Add(Ref oRef, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int nLenGID, unsigned int nLenUnicode); + void Clear(); + bool GetFont(Ref *pRef, TFontEntry *pEntry); + private: + + TFontEntry* Lookup(Ref& oRef) + { + CRefFontMap::const_iterator oPos = m_oFontMap.find(oRef); + if (m_oFontMap.end() != oPos) + return oPos->second; + + return NULL; + } + void Add(Ref& oRef, TFontEntry* pFontEntry) + { + // До вызова данной функции надо проверять есть ли элемент с данным ключом + m_oFontMap.insert(std::pair(oRef, pFontEntry)); + } + + private: + + typedef std::map CRefFontMap; + CRefFontMap m_oFontMap; + NSCriticalSection::CRITICAL_SECTION m_oCS; // Критическая секция + }; + //------------------------------------------------------------------------------------------------------------------------------- + template + inline static double PDFCoordsToMM(T tX) + { + return ((double)tX / 72.0) * 25.4; + } + + //------------------------------------------------------------------------------------------------------------------------------- + static void FileWrite(void *pStream, char *sData, int nLen) + { + ::fwrite(sData, 1, nLen, (FILE *)pStream); + } + //------------------------------------------------------------------------------------------------------------------------------- + // RendererOutputDev + //------------------------------------------------------------------------------------------------------------------------------- + + class RendererOutputDev : public OutputDev + { + public: + RendererOutputDev(IRenderer *pRenderer, NSFonts::IFontManager* pFontManager, CFontList *pFontList = NULL); + virtual ~RendererOutputDev(); + + virtual GBool upsideDown() + { + return false; + } + virtual GBool useDrawChar() + { + return true; + } + virtual GBool useTilingPatternFill() + { + if (m_bDrawOnlyText) + return true; + + return false; + } + virtual GBool useFunctionalShadedFills() + { + return true; + } + virtual GBool useAxialShadedFills() + { + return true; + } + virtual GBool useRadialShadedFills() + { + return true; + } + virtual GBool useGouraundTriangleFills() + { + return true; + } + virtual GBool usePatchMeshFills() + { + return true; + } + virtual GBool useClipTo() + { + return false;//true; + } + virtual GBool interpretType3Chars() + { + return true; + } + virtual GBool useFillAndStroke() + { + return true; + } + virtual GBool useSimpleTransparentGroup() + { + return true; + } + virtual GBool useSimpleTilingPatternFill() + { + if (NULL == m_pRenderer) + return false; + + // TODO: m_pRenderer->GetAdditionalParam(L"TilingHtmlPattern"); + + return false; + } + virtual GBool isStopped() + { + if (NULL != m_pbBreak) + return *m_pbBreak; + else + return false; + } + //--------------------------------------------------------------------------------------------------------------------------- + virtual void startPage(int nPageIndex, GfxState *pGState); + virtual void endPage(); + //----- Save/Restore GState + virtual void saveState(GfxState *pGState); + virtual void restoreState(GfxState *pGState); + //----- Изменение параметров в GState + virtual void updateCTM(GfxState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32); + virtual void updateLineDash(GfxState *pGState); + virtual void updateFlatness(GfxState *pGState); + virtual void updateLineJoin(GfxState *pGState); + virtual void updateLineCap(GfxState *pGState); + virtual void updateMiterLimit(GfxState *pGState); + virtual void updateLineWidth(GfxState *pGState); + virtual void updateStrokeAdjust(GfxState *pGState); + virtual void updateFillColor(GfxState *pGState); + virtual void updateStrokeColor(GfxState *pGState); + virtual void updateBlendMode(GfxState *pGState); + virtual void updateFillOpacity(GfxState *pGState); + virtual void updateStrokeOpacity(GfxState *pGState); + virtual void updateAll(GfxState *pGState); + virtual void updateRender(GfxState *pGState); + //----- Изменение текстовых параметров + virtual void updateFont(GfxState *pGState); + //----- Рисование Path + virtual void stroke(GfxState *pGState); + virtual void fill(GfxState *pGState); + virtual void eoFill(GfxState *pGState); + virtual void FillStroke(GfxState *pGState); + virtual void EoFillStroke(GfxState *pGState); + virtual void tilingPatternFill(GfxState *pGState, Object *pStream, int nPaintType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep); + virtual void StartTilingFill(GfxState *pGState); + virtual void EndTilingFill(); + //todo overide + virtual GBool shadedFill(GfxState *state, GfxShading *shading); + virtual bool FunctionShadedFill(GfxState *pGState, GfxFunctionShading *pShading); + virtual bool AxialShadedFill(GfxState *pGState, GfxAxialShading *pShading); + virtual bool RadialShadedFill(GfxState *pGState, GfxRadialShading *pShading); + virtual bool GouraundTriangleFill(GfxState *pGState, const std::vector &colors, const std::vector &points); + virtual bool PatchMeshFill(GfxState *pGState, GfxPatch* pPatch, GfxPatchMeshShading *pShading); + virtual void StartShadedFill(GfxState *pGState); + virtual void EndShadedFill(); + virtual void StartTilingFillIteration(); + virtual void EndTilingFillIteration(); + virtual void StartSimpleTilingFill(GfxState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix); + virtual void EndSimpleTilingFill(); + //----- Path clipping + virtual void clip(GfxState *pGState); + virtual void clipAttack(GfxState *pGState) + { + updateClipAttack(pGState); + } + virtual void eoClip(GfxState *pGState); + virtual void clipToStrokePath(GfxState *pGState); + virtual void clipToPath(GfxState *pGState, GfxPath *pPath, double *pMatrix, bool bEO); + //----- Вывод текста + virtual void endTextObject(GfxState *pGState); + virtual void beginStringOp(GfxState *pGState); + virtual void endStringOp(GfxState *pGState); + virtual void drawString(GfxState *pGState, GString *seString); + virtual void drawChar(GfxState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen); + GBool beginType3Char(GfxState *state, double x, double y, + double dx, double dy, + CharCode code, Unicode *u, int uLen) { + return false; + } + void endType3Char(GfxState *pGState); + void Type3D0(GfxState *pGState, double dWx, double dWy); + void Type3D1(GfxState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy); + //----- Вывод картинок + virtual void drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; + virtual void setSoftMaskFromImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GBool bInvert, GBool bInlineImage, GBool interpolate) override; + virtual void drawImage(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GfxImageColorMap *pColorMap, int *pMaskColors, GBool bInlineImg, GBool interpolate) override; + virtual void drawMaskedImage(GfxState *pGState, + Object *pRef, + Stream *pStream, + int nWidth, int nHeight, + GfxImageColorMap *pColorMap, + Object* pMaskRef, + Stream *pMaskStream, + int nMaskWidth, int nMaskHeight, + GBool bMaskInvert, + GBool interpolate) override; + virtual void drawSoftMaskedImage(GfxState *pGState, Object *pRef, Stream *pStream, + int nWidth, int nHeight, + GfxImageColorMap *pColorMap, + Object *maskRef, Stream *pMaskStream, + int nMaskWidth, int nMaskHeight, + GfxImageColorMap *pMaskColorMap, + double *pMatte, GBool interpolate) override; + //----- Transparency groups и SMasks + virtual void beginTransparencyGroup(GfxState *pGState, double *pBBox, GfxColorSpace *pBlendingColorSpace, GBool bIsolated, GBool bKnockout, GBool bForSoftMask); + virtual void endTransparencyGroup(GfxState *pGState); + virtual void paintTransparencyGroup(GfxState *pGState, double *pBBox); + virtual void setSoftMask(GfxState *pGState, double *pBBox, GBool bAlpha, Function *pTransferFunc, GfxColor *pBackdropColor); + virtual void clearSoftMask(GfxState *pGState); + //----- Дополнительные функции для данного устройства + void NewPDF(XRef *pXref); + void SetBreak(bool* pbBreak) + { + m_pbBreak = pbBreak; + } + + private: + + void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); + void DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM); + void ClipToText(const std::wstring& wsFontName, const std::wstring& wsFontPath, double dFontSize, int nFontStyle, double* pMatrix, const std::wstring& wsText, double dX, double dY, double dWidth = 0, double dHeight = 0, double dBaseLineOffset = 0); + void updateClip(GfxState *pGState); + void updateClipAttack(GfxState *pGState); + void DoTransform(double *pMatrix, double *pdShiftX, double *pdShiftY, bool bText = false); + private: + + IRenderer* m_pRenderer; + long m_lRendererType; + double m_arrMatrix[6]; + NSFonts::IFontManager* m_pFontManager; + + //GfxTextClip *m_pBufferTextClip; + + XRef *m_pXref; // Таблица Xref для данного PDF-документа + CFontList *m_pFontList; + + bool *m_pbBreak; // Внешняя остановка рендерера + + std::deque m_sClip; + bool m_bClipChanged; + + bool m_bTiling; + bool m_bTransparentGroup; + bool m_bIsolatedTransparentGroup; + bool m_bTransparentGroupSoftMask; + bool m_bTransparentGroupSoftMaskEnd; + std::vector m_arrTransparentGroupSoftMask; + + unsigned char* m_pSoftMask; + int m_nSoftMaskWidth; + int m_nSoftMaskHeight; + + bool m_bDrawOnlyText; // Special option for html-renderer + + }; +} + +#endif // _PDF_READER_RENDERER_OUTPUTDEV_H diff --git a/PdfReader/old/XmlUtils.h b/PdfFile/SrcReader/XmlUtils.h similarity index 96% rename from PdfReader/old/XmlUtils.h rename to PdfFile/SrcReader/XmlUtils.h index bc7079e2e2..146a3f8ab7 100644 --- a/PdfReader/old/XmlUtils.h +++ b/PdfFile/SrcReader/XmlUtils.h @@ -1,210 +1,210 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_XML_UTILS_H -#define _PDF_READER_XML_UTILS_H - -#include -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Base64.h" -#include - -namespace PdfReader -{ - class CXmlWriter - { - public: - - CXmlWriter() - { - m_wsXml.clear(); - } - - const wchar_t* GetXmlString() - { - return m_wsXml.c_str(); - } - void SetXmlString(const std::wstring& wsXml) - { - m_wsXml = wsXml; - } - bool SaveToFile(const std::wstring& wsFilePath, bool bEncodingToUTF8 = false) - { - return NSFile::CFileBinary::SaveToFile(wsFilePath, m_wsXml); - } - void WriteString(const std::wstring& wsString) - { - m_wsXml += wsString; - } - void WriteInteger(int nValue, int Base = 10) - { - m_wsXml += std::to_wstring(nValue); - } - void WriteDouble(double dValue) - { - m_wsXml += std::to_wstring(dValue); - } - void WriteBoolean(bool bValue) - { - if (bValue) - m_wsXml += L"true"; - else - m_wsXml += L"false"; - } - void WriteNodeBegin(const std::wstring& wsNodeName, bool bAttributed = false) - { - m_wsXml += L"<" + wsNodeName; - - if (!bAttributed) - m_wsXml += L">"; - } - void WriteNodeEnd(const std::wstring& wsNodeName, bool bEmptyNode = false, bool bEndNode = true) - { - if (bEmptyNode) - { - if (bEndNode) - m_wsXml += L" />"; - else - m_wsXml += L">"; - } - else - m_wsXml += L""; - } - void WriteNode(const std::wstring& wsNodeName, const std::wstring& wsNodeValue) - { - if (0 == wsNodeValue.length()) - m_wsXml += L"<" + wsNodeName + L"/>"; - else - m_wsXml += L"<" + wsNodeName + L">" + wsNodeValue + L""; - } - void WriteNode(const std::wstring& wsNodeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") - { - WriteNodeBegin(wsNodeName); - WriteString(wsTextBeforeValue); - WriteInteger(nValue, nBase); - WriteString(wsTextAfterValue); - WriteNodeEnd(wsNodeName); - } - void WriteNode(const std::wstring& wsNodeName, double dValue) - { - WriteNodeBegin(wsNodeName); - WriteDouble(dValue); - WriteNodeEnd(wsNodeName); - } - void WriteAttribute(const std::wstring& wsAttributeName, const std::wstring& wsAttributeValue) - { - m_wsXml += L" " + wsAttributeName + L"=\"" + wsAttributeValue + L"\""; - } - void WriteAttribute(const std::wstring& wsAttributeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") - { - WriteString(L" " + wsAttributeName + L"="); - WriteString(L"\""); - WriteString(wsTextBeforeValue); - WriteInteger(nValue, nBase); - WriteString(wsTextAfterValue); - WriteString(L"\""); - } - void WriteAttribute(const std::wstring& wsAttributeName, double dValue) - { - WriteString(L" " + wsAttributeName + L"="); - WriteString(L"\""); - WriteDouble(dValue); - WriteString(L"\""); - } - public: - static void ReplaceSpecialCharacters(std::wstring& wsString) - { - ReplaceAll(wsString, L"&", L"&"); - ReplaceAll(wsString, L"<", L"<"); - ReplaceAll(wsString, L">", L">"); - ReplaceAll(wsString, L"\"", L"""); - ReplaceAll(wsString, L"'", L"'"); - } - static void ReplaceAll(std::wstring& wsSrc, const std::wstring& wsFrom, const std::wstring& wsTo) - { - if (wsFrom.empty()) - return; - - int nFromLen = wsFrom.length(); - int nToLen = wsTo.length(); - - size_t nStartPos = 0; - while (std::string::npos != (nStartPos = wsSrc.find(wsFrom, nStartPos))) - { - wsSrc.replace(nStartPos, nFromLen, wsTo); - nStartPos += nToLen; - } - } - - private: - - std::wstring m_wsXml; - - }; - - class CBase64 - { - public: - - void Encode(unsigned char* pSrc, int nSrcLen) - { - m_sBuffer.clear(); - int nRequiredLen = NSBase64::Base64EncodeGetRequiredLength(nSrcLen); - if (0 == nRequiredLen) - return; - - unsigned char* pDst = new unsigned char[nRequiredLen + 1]; - if (!pDst) - return; - - pDst[nRequiredLen] = 0x00; - - int nDstLen; - NSBase64::Base64Encode(pSrc, nSrcLen, pDst, &nDstLen); - m_sBuffer.append((char*)pDst); - delete[] pDst; - } - std::string& GetString() - { - return m_sBuffer; - } - const char* GetCString() - { - return m_sBuffer.c_str(); - } - - private: - - std::string m_sBuffer; - }; -} - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_READER_XML_UTILS_H +#define _PDF_READER_XML_UTILS_H + +#include +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/common/Base64.h" +#include + +namespace PdfReader +{ + class CXmlWriter + { + public: + + CXmlWriter() + { + m_wsXml.clear(); + } + + const wchar_t* GetXmlString() + { + return m_wsXml.c_str(); + } + void SetXmlString(const std::wstring& wsXml) + { + m_wsXml = wsXml; + } + bool SaveToFile(const std::wstring& wsFilePath, bool bEncodingToUTF8 = false) + { + return NSFile::CFileBinary::SaveToFile(wsFilePath, m_wsXml); + } + void WriteString(const std::wstring& wsString) + { + m_wsXml += wsString; + } + void WriteInteger(int nValue, int Base = 10) + { + m_wsXml += std::to_wstring(nValue); + } + void WriteDouble(double dValue) + { + m_wsXml += std::to_wstring(dValue); + } + void WriteBoolean(bool bValue) + { + if (bValue) + m_wsXml += L"true"; + else + m_wsXml += L"false"; + } + void WriteNodeBegin(const std::wstring& wsNodeName, bool bAttributed = false) + { + m_wsXml += L"<" + wsNodeName; + + if (!bAttributed) + m_wsXml += L">"; + } + void WriteNodeEnd(const std::wstring& wsNodeName, bool bEmptyNode = false, bool bEndNode = true) + { + if (bEmptyNode) + { + if (bEndNode) + m_wsXml += L" />"; + else + m_wsXml += L">"; + } + else + m_wsXml += L""; + } + void WriteNode(const std::wstring& wsNodeName, const std::wstring& wsNodeValue) + { + if (0 == wsNodeValue.length()) + m_wsXml += L"<" + wsNodeName + L"/>"; + else + m_wsXml += L"<" + wsNodeName + L">" + wsNodeValue + L""; + } + void WriteNode(const std::wstring& wsNodeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") + { + WriteNodeBegin(wsNodeName); + WriteString(wsTextBeforeValue); + WriteInteger(nValue, nBase); + WriteString(wsTextAfterValue); + WriteNodeEnd(wsNodeName); + } + void WriteNode(const std::wstring& wsNodeName, double dValue) + { + WriteNodeBegin(wsNodeName); + WriteDouble(dValue); + WriteNodeEnd(wsNodeName); + } + void WriteAttribute(const std::wstring& wsAttributeName, const std::wstring& wsAttributeValue) + { + m_wsXml += L" " + wsAttributeName + L"=\"" + wsAttributeValue + L"\""; + } + void WriteAttribute(const std::wstring& wsAttributeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") + { + WriteString(L" " + wsAttributeName + L"="); + WriteString(L"\""); + WriteString(wsTextBeforeValue); + WriteInteger(nValue, nBase); + WriteString(wsTextAfterValue); + WriteString(L"\""); + } + void WriteAttribute(const std::wstring& wsAttributeName, double dValue) + { + WriteString(L" " + wsAttributeName + L"="); + WriteString(L"\""); + WriteDouble(dValue); + WriteString(L"\""); + } + public: + static void ReplaceSpecialCharacters(std::wstring& wsString) + { + ReplaceAll(wsString, L"&", L"&"); + ReplaceAll(wsString, L"<", L"<"); + ReplaceAll(wsString, L">", L">"); + ReplaceAll(wsString, L"\"", L"""); + ReplaceAll(wsString, L"'", L"'"); + } + static void ReplaceAll(std::wstring& wsSrc, const std::wstring& wsFrom, const std::wstring& wsTo) + { + if (wsFrom.empty()) + return; + + int nFromLen = wsFrom.length(); + int nToLen = wsTo.length(); + + size_t nStartPos = 0; + while (std::string::npos != (nStartPos = wsSrc.find(wsFrom, nStartPos))) + { + wsSrc.replace(nStartPos, nFromLen, wsTo); + nStartPos += nToLen; + } + } + + private: + + std::wstring m_wsXml; + + }; + + class CBase64 + { + public: + + void Encode(unsigned char* pSrc, int nSrcLen) + { + m_sBuffer.clear(); + int nRequiredLen = NSBase64::Base64EncodeGetRequiredLength(nSrcLen); + if (0 == nRequiredLen) + return; + + unsigned char* pDst = new unsigned char[nRequiredLen + 1]; + if (!pDst) + return; + + pDst[nRequiredLen] = 0x00; + + int nDstLen; + NSBase64::Base64Encode(pSrc, nSrcLen, pDst, &nDstLen); + m_sBuffer.append((char*)pDst); + delete[] pDst; + } + std::string& GetString() + { + return m_sBuffer; + } + const char* GetCString() + { + return m_sBuffer.c_str(); + } + + private: + + std::string m_sBuffer; + }; +} + #endif // _PDF_READER_XML_UTILS_H \ No newline at end of file diff --git a/PdfWriter/Src/AcroForm.cpp b/PdfFile/SrcWriter/AcroForm.cpp similarity index 100% rename from PdfWriter/Src/AcroForm.cpp rename to PdfFile/SrcWriter/AcroForm.cpp diff --git a/PdfWriter/Src/AcroForm.h b/PdfFile/SrcWriter/AcroForm.h similarity index 100% rename from PdfWriter/Src/AcroForm.h rename to PdfFile/SrcWriter/AcroForm.h diff --git a/PdfWriter/Src/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp similarity index 96% rename from PdfWriter/Src/Annotation.cpp rename to PdfFile/SrcWriter/Annotation.cpp index ab3fc21a87..6d20f27348 100644 --- a/PdfWriter/Src/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1,215 +1,215 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Annotation.h" -#include "Pages.h" - -#ifndef BS_DEF_WIDTH -#define BS_DEF_WIDTH 1 -#endif - -namespace PdfWriter -{ - const static char* c_sAnnotTypeNames[] = - { - "Text", - "Link", - "Sound", - "FreeText", - "Stamp", - "Square", - "Circle", - "StrikeOut", - "Highlight", - "Underline", - "Ink", - "FileAttachment", - "Popup" - }; - const static char* c_sAnnotIconNames[] = - { - "Comment", - "Key", - "Note", - "Help", - "NewParagraph", - "Paragraph", - "Insert" - }; - - //---------------------------------------------------------------------------------------- - // CAnnotation - //---------------------------------------------------------------------------------------- - CAnnotation::CAnnotation(CXref* pXref, EAnnotType eType, const TRect& oRect) - { - pXref->Add(this); - - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - - Add("Rect", pArray); - - if (oRect.fTop < oRect.fBottom) - { - pArray->Add(oRect.fLeft); - pArray->Add(oRect.fTop); - pArray->Add(oRect.fRight); - pArray->Add(oRect.fBottom); - } - else - { - pArray->Add(oRect.fLeft); - pArray->Add(oRect.fBottom); - pArray->Add(oRect.fRight); - pArray->Add(oRect.fTop); - } - - Add("Type", "Annot"); - Add("Subtype", c_sAnnotTypeNames[(int)eType]); - - // Для PDFA нужно, чтобы 0, 1, 4 биты были выключены, а второй включен - Add("F", 4); - } - void CAnnotation::SetBorderStyle(EBorderSubtype eSubtype, float fWidth, unsigned short nDashOn, unsigned short nDashOff, unsigned short nDashPhase) - { - CDictObject* pBorderStyleDict = new CDictObject(); - if (!pBorderStyleDict) - return; - - Add("BS", pBorderStyleDict); - - if (::fabs(BS_DEF_WIDTH - fWidth) > 0.01) - pBorderStyleDict->Add("W", fWidth); - - if (fWidth < 0.01) - return; - - if (border_subtype_Dashed == eSubtype) - { - CArrayObject* pDash = new CArrayObject(); - if (!pDash) - return; - - pBorderStyleDict->Add("D", pDash); - pBorderStyleDict->Add("Type", "Border"); - pDash->Add(nDashOn); - pDash->Add(nDashOff); - - if (0 != nDashPhase) - pDash->Add(nDashOff); - } - - switch (eSubtype) - { - case border_subtype_Solid: pBorderStyleDict->Add("S", "S"); break; - case border_subtype_Dashed: pBorderStyleDict->Add("S", "D"); break; - case border_subtype_Beveled: pBorderStyleDict->Add("S", "B"); break; - case border_subtype_Inset: pBorderStyleDict->Add("S", "I"); break; - case border_subtype_Underlined: pBorderStyleDict->Add("S", "U"); break; - } - } - //---------------------------------------------------------------------------------------- - // CLinkAnnotation - //---------------------------------------------------------------------------------------- - CLinkAnnotation::CLinkAnnotation(CXref* pXref, const TRect& oRect, CDestination* pDestination) : CAnnotation(pXref, AnnotLink, oRect) - { - Add("Dest", (CObjectBase*)pDestination); - } - void CLinkAnnotation::SetBorderStyle(float fWidth, unsigned short nDashOn, unsigned short nDashOff) - { - fWidth = std::max(fWidth, 0.f); - - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - - Add("Border", pArray); - - pArray->Add(0); - pArray->Add(0); - pArray->Add(fWidth); - - if (nDashOn && nDashOff) - { - CArrayObject* pDash = new CArrayObject(); - if (!pDash) - return; - - pArray->Add(pDash); - - pDash->Add(nDashOn); - pDash->Add(nDashOff); - } - } - void CLinkAnnotation::SetHighlightMode(EAnnotHighlightMode eMode) - { - switch (eMode) - { - case AnnotNoHighlight: Add("H", "N"); break; - case AnnotInvertBorder: Add("H", "O"); break; - case AnnotDownAppearance: Add("H", "P"); break; - default: Remove("H"); break; - } - } - //---------------------------------------------------------------------------------------- - // CTextAnnotation - //---------------------------------------------------------------------------------------- - CTextAnnotation::CTextAnnotation(CXref* pXref, const TRect& oRect, const char* sText) : CAnnotation(pXref, AnnotTextNotes, oRect) - { - Add("Contents", new CStringObject(sText)); - } - void SetIcon(EAnnotIcon eIcon); - void SetOpened(bool bOpened); - void CTextAnnotation::SetIcon(EAnnotIcon eIcon) - { - eIcon = (EAnnotIcon)std::min(std::max(AnnotIconMin, eIcon), AnnotIconMax); - Add("Name", c_sAnnotIconNames[(int)eIcon]); - } - void CTextAnnotation::SetOpened(bool bOpened) - { - Add("Open", new CBoolObject(bOpened)); - } - //---------------------------------------------------------------------------------------- - // CUriLinkAnnotation - //---------------------------------------------------------------------------------------- - CUriLinkAnnotation::CUriLinkAnnotation(CXref* pXref, const TRect& oRect, const char* sUri) : CAnnotation(pXref, AnnotLink, oRect) - { - CDictObject* pAction = new CDictObject(); - if (!pAction) - return; - - Add("A", pAction); - pAction->Add("Type", "Action"); - pAction->Add("S", "URI"); - pAction->Add("URI", new CStringObject(sUri)); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Annotation.h" +#include "Pages.h" + +#ifndef BS_DEF_WIDTH +#define BS_DEF_WIDTH 1 +#endif + +namespace PdfWriter +{ + const static char* c_sAnnotTypeNames[] = + { + "Text", + "Link", + "Sound", + "FreeText", + "Stamp", + "Square", + "Circle", + "StrikeOut", + "Highlight", + "Underline", + "Ink", + "FileAttachment", + "Popup" + }; + const static char* c_sAnnotIconNames[] = + { + "Comment", + "Key", + "Note", + "Help", + "NewParagraph", + "Paragraph", + "Insert" + }; + + //---------------------------------------------------------------------------------------- + // CAnnotation + //---------------------------------------------------------------------------------------- + CAnnotation::CAnnotation(CXref* pXref, EAnnotType eType, const TRect& oRect) + { + pXref->Add(this); + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + Add("Rect", pArray); + + if (oRect.fTop < oRect.fBottom) + { + pArray->Add(oRect.fLeft); + pArray->Add(oRect.fTop); + pArray->Add(oRect.fRight); + pArray->Add(oRect.fBottom); + } + else + { + pArray->Add(oRect.fLeft); + pArray->Add(oRect.fBottom); + pArray->Add(oRect.fRight); + pArray->Add(oRect.fTop); + } + + Add("Type", "Annot"); + Add("Subtype", c_sAnnotTypeNames[(int)eType]); + + // Для PDFA нужно, чтобы 0, 1, 4 биты были выключены, а второй включен + Add("F", 4); + } + void CAnnotation::SetBorderStyle(EBorderSubtype eSubtype, float fWidth, unsigned short nDashOn, unsigned short nDashOff, unsigned short nDashPhase) + { + CDictObject* pBorderStyleDict = new CDictObject(); + if (!pBorderStyleDict) + return; + + Add("BS", pBorderStyleDict); + + if (::fabs(BS_DEF_WIDTH - fWidth) > 0.01) + pBorderStyleDict->Add("W", fWidth); + + if (fWidth < 0.01) + return; + + if (border_subtype_Dashed == eSubtype) + { + CArrayObject* pDash = new CArrayObject(); + if (!pDash) + return; + + pBorderStyleDict->Add("D", pDash); + pBorderStyleDict->Add("Type", "Border"); + pDash->Add(nDashOn); + pDash->Add(nDashOff); + + if (0 != nDashPhase) + pDash->Add(nDashOff); + } + + switch (eSubtype) + { + case border_subtype_Solid: pBorderStyleDict->Add("S", "S"); break; + case border_subtype_Dashed: pBorderStyleDict->Add("S", "D"); break; + case border_subtype_Beveled: pBorderStyleDict->Add("S", "B"); break; + case border_subtype_Inset: pBorderStyleDict->Add("S", "I"); break; + case border_subtype_Underlined: pBorderStyleDict->Add("S", "U"); break; + } + } + //---------------------------------------------------------------------------------------- + // CLinkAnnotation + //---------------------------------------------------------------------------------------- + CLinkAnnotation::CLinkAnnotation(CXref* pXref, const TRect& oRect, CDestination* pDestination) : CAnnotation(pXref, AnnotLink, oRect) + { + Add("Dest", (CObjectBase*)pDestination); + } + void CLinkAnnotation::SetBorderStyle(float fWidth, unsigned short nDashOn, unsigned short nDashOff) + { + fWidth = std::max(fWidth, 0.f); + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + + Add("Border", pArray); + + pArray->Add(0); + pArray->Add(0); + pArray->Add(fWidth); + + if (nDashOn && nDashOff) + { + CArrayObject* pDash = new CArrayObject(); + if (!pDash) + return; + + pArray->Add(pDash); + + pDash->Add(nDashOn); + pDash->Add(nDashOff); + } + } + void CLinkAnnotation::SetHighlightMode(EAnnotHighlightMode eMode) + { + switch (eMode) + { + case AnnotNoHighlight: Add("H", "N"); break; + case AnnotInvertBorder: Add("H", "O"); break; + case AnnotDownAppearance: Add("H", "P"); break; + default: Remove("H"); break; + } + } + //---------------------------------------------------------------------------------------- + // CTextAnnotation + //---------------------------------------------------------------------------------------- + CTextAnnotation::CTextAnnotation(CXref* pXref, const TRect& oRect, const char* sText) : CAnnotation(pXref, AnnotTextNotes, oRect) + { + Add("Contents", new CStringObject(sText)); + } + void SetIcon(EAnnotIcon eIcon); + void SetOpened(bool bOpened); + void CTextAnnotation::SetIcon(EAnnotIcon eIcon) + { + eIcon = (EAnnotIcon)std::min(std::max(AnnotIconMin, eIcon), AnnotIconMax); + Add("Name", c_sAnnotIconNames[(int)eIcon]); + } + void CTextAnnotation::SetOpened(bool bOpened) + { + Add("Open", new CBoolObject(bOpened)); + } + //---------------------------------------------------------------------------------------- + // CUriLinkAnnotation + //---------------------------------------------------------------------------------------- + CUriLinkAnnotation::CUriLinkAnnotation(CXref* pXref, const TRect& oRect, const char* sUri) : CAnnotation(pXref, AnnotLink, oRect) + { + CDictObject* pAction = new CDictObject(); + if (!pAction) + return; + + Add("A", pAction); + pAction->Add("Type", "Action"); + pAction->Add("S", "URI"); + pAction->Add("URI", new CStringObject(sUri)); + } +} diff --git a/PdfWriter/Src/Annotation.h b/PdfFile/SrcWriter/Annotation.h similarity index 100% rename from PdfWriter/Src/Annotation.h rename to PdfFile/SrcWriter/Annotation.h diff --git a/PdfWriter/Src/Catalog.cpp b/PdfFile/SrcWriter/Catalog.cpp similarity index 96% rename from PdfWriter/Src/Catalog.cpp rename to PdfFile/SrcWriter/Catalog.cpp index b57dfc65f7..876ba2c7f3 100644 --- a/PdfWriter/Src/Catalog.cpp +++ b/PdfFile/SrcWriter/Catalog.cpp @@ -1,198 +1,198 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Catalog.h" -#include "Destination.h" -#include "Pages.h" -#include "Utils.h" -#include "Metadata.h" -#include "Streams.h" -#include "ICCProfile.h" - -namespace PdfWriter -{ - static const char* c_sPageLayoutNames[] = - { - "SinglePage", - "OneColumn", - "TwoColumnLeft", - "TwoColumnRight", - "TwoPageLeft", - "TwoPageRight", - NULL - }; - static const char* c_sPageModeNames[] = - { - "UseNone", - "UseOutlines", - "UseThumbs", - "FullScreen", - "UseOC", - "UseAttachments", - NULL - }; - //---------------------------------------------------------------------------------------- - // CCatalog - //---------------------------------------------------------------------------------------- - CCatalog::CCatalog(CXref* pXref) - { - pXref->Add(this); - - Add("Type", "Catalog"); - Add("Pages", new CPageTree(pXref)); - - if (pXref->IsPDFA()) - { - CDictObject* pMarkInfo = new CDictObject(); - pMarkInfo->Add("Marked", true); - Add("MarkInfo", pMarkInfo); - Add("StructTreeRoot", new CStructureTreeRoot(pXref)); - - - CArrayObject* pArray = new CArrayObject(); - Add("OutputIntents", pArray); - - CDictObject* pRGB = new CDictObject(); - pArray->Add(pRGB); - - pRGB->Add("Type", "OutputIntent"); - pRGB->Add("S", "GTS_PDFA1"); - pRGB->Add("OutputConditionIdentifier", new CStringObject("sRGB IEC61966-2.1")); - - CDictObject* pRGBProfile = new CDictObject(pXref); - pRGB->Add("DestOutputProfile", pRGBProfile); - pRGB->Add("RegistryName", new CStringObject("http://www.color.org")); - - pRGBProfile->Add("N", 3); - -#ifndef FILTER_FLATE_DECODE_DISABLED - pRGBProfile->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - pRGBProfile->GetStream()->Write((unsigned char*)c_arrICCsRGB, c_nSizeICCsRGB, false); - } - } - CCatalog::CCatalog(CXref* pXref, bool bEmpty) - { - pXref->Add(this); - } - CPageTree* CCatalog::GetRoot() const - { - return (CPageTree*)Get("Pages"); - } - EPageLayout CCatalog::GetPageLayout() const - { - CNameObject* pLayout = (CNameObject*)Get("PageLayout"); - if (!pLayout) - return pagelayout_Single; - - unsigned int unIndex = 0; - while (c_sPageLayoutNames[unIndex]) - { - if (0 == StrCmp(pLayout->Get(), c_sPageLayoutNames[unIndex])) - return (EPageLayout)unIndex; - - unIndex++; - } - - return pagelayout_Single; - } - void CCatalog::SetPageLayout(EPageLayout eLayout) - { - return Add("PageLayout", c_sPageLayoutNames[(int)eLayout]); - } - EPageMode CCatalog::GetPageMode() const - { - CNameObject* pMode = (CNameObject*)Get("PageMode"); - if (!pMode) - return pagemode_UseNone; - - unsigned int unIndex = 0; - while (c_sPageModeNames[unIndex]) - { - if (0 == StrCmp(pMode->Get(), c_sPageModeNames[unIndex])) - return (EPageMode)unIndex; - - unIndex++; - } - - return pagemode_UseNone; - } - void CCatalog::SetPageMode(EPageMode eMode) - { - Add("PageMode", c_sPageModeNames[(int)eMode]); - } - void CCatalog::SetOpenAction(CDestination* pOpenAction) - { - if (!pOpenAction) - Remove("OpenAction"); - else - Add("OpenAction", pOpenAction); - } - void CCatalog::AddPageLabel(unsigned int unPageNum, CDictObject* pPageLabel) - { - CDictObject* pLabels = (CDictObject*)Get("PageLabels"); - if (!pLabels) - { - pLabels = new CDictObject(); - if (!pLabels) - return; - - Add("PageLabels", pLabels); - } - - CArrayObject* pNums = (CArrayObject*)pLabels->Get("Nums"); - if (!pNums) - { - pNums = new CArrayObject(); - if (!pNums) - return; - - pLabels->Add("Nums", pNums); - } - - pNums->Add(unPageNum); - pNums->Add(pPageLabel); - } - CMetadata* CCatalog::AddMetadata(CXref* pXref, CInfoDict* pInfo) - { - CMetadata* pMetadata = new CMetadata(pXref, pInfo); - Add("Metadata", pMetadata); - return pMetadata; - } - //---------------------------------------------------------------------------------------- - // CStructureTreeRoot - //---------------------------------------------------------------------------------------- - CStructureTreeRoot::CStructureTreeRoot(CXref* pXref) - { - pXref->Add(this); - Add("Type", "StructTreeRoot"); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Catalog.h" +#include "Destination.h" +#include "Pages.h" +#include "Utils.h" +#include "Metadata.h" +#include "Streams.h" +#include "ICCProfile.h" + +namespace PdfWriter +{ + static const char* c_sPageLayoutNames[] = + { + "SinglePage", + "OneColumn", + "TwoColumnLeft", + "TwoColumnRight", + "TwoPageLeft", + "TwoPageRight", + NULL + }; + static const char* c_sPageModeNames[] = + { + "UseNone", + "UseOutlines", + "UseThumbs", + "FullScreen", + "UseOC", + "UseAttachments", + NULL + }; + //---------------------------------------------------------------------------------------- + // CCatalog + //---------------------------------------------------------------------------------------- + CCatalog::CCatalog(CXref* pXref) + { + pXref->Add(this); + + Add("Type", "Catalog"); + Add("Pages", new CPageTree(pXref)); + + if (pXref->IsPDFA()) + { + CDictObject* pMarkInfo = new CDictObject(); + pMarkInfo->Add("Marked", true); + Add("MarkInfo", pMarkInfo); + Add("StructTreeRoot", new CStructureTreeRoot(pXref)); + + + CArrayObject* pArray = new CArrayObject(); + Add("OutputIntents", pArray); + + CDictObject* pRGB = new CDictObject(); + pArray->Add(pRGB); + + pRGB->Add("Type", "OutputIntent"); + pRGB->Add("S", "GTS_PDFA1"); + pRGB->Add("OutputConditionIdentifier", new CStringObject("sRGB IEC61966-2.1")); + + CDictObject* pRGBProfile = new CDictObject(pXref); + pRGB->Add("DestOutputProfile", pRGBProfile); + pRGB->Add("RegistryName", new CStringObject("http://www.color.org")); + + pRGBProfile->Add("N", 3); + +#ifndef FILTER_FLATE_DECODE_DISABLED + pRGBProfile->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + pRGBProfile->GetStream()->Write((unsigned char*)c_arrICCsRGB, c_nSizeICCsRGB, false); + } + } + CCatalog::CCatalog(CXref* pXref, bool bEmpty) + { + pXref->Add(this); + } + CPageTree* CCatalog::GetRoot() const + { + return (CPageTree*)Get("Pages"); + } + EPageLayout CCatalog::GetPageLayout() const + { + CNameObject* pLayout = (CNameObject*)Get("PageLayout"); + if (!pLayout) + return pagelayout_Single; + + unsigned int unIndex = 0; + while (c_sPageLayoutNames[unIndex]) + { + if (0 == StrCmp(pLayout->Get(), c_sPageLayoutNames[unIndex])) + return (EPageLayout)unIndex; + + unIndex++; + } + + return pagelayout_Single; + } + void CCatalog::SetPageLayout(EPageLayout eLayout) + { + return Add("PageLayout", c_sPageLayoutNames[(int)eLayout]); + } + EPageMode CCatalog::GetPageMode() const + { + CNameObject* pMode = (CNameObject*)Get("PageMode"); + if (!pMode) + return pagemode_UseNone; + + unsigned int unIndex = 0; + while (c_sPageModeNames[unIndex]) + { + if (0 == StrCmp(pMode->Get(), c_sPageModeNames[unIndex])) + return (EPageMode)unIndex; + + unIndex++; + } + + return pagemode_UseNone; + } + void CCatalog::SetPageMode(EPageMode eMode) + { + Add("PageMode", c_sPageModeNames[(int)eMode]); + } + void CCatalog::SetOpenAction(CDestination* pOpenAction) + { + if (!pOpenAction) + Remove("OpenAction"); + else + Add("OpenAction", pOpenAction); + } + void CCatalog::AddPageLabel(unsigned int unPageNum, CDictObject* pPageLabel) + { + CDictObject* pLabels = (CDictObject*)Get("PageLabels"); + if (!pLabels) + { + pLabels = new CDictObject(); + if (!pLabels) + return; + + Add("PageLabels", pLabels); + } + + CArrayObject* pNums = (CArrayObject*)pLabels->Get("Nums"); + if (!pNums) + { + pNums = new CArrayObject(); + if (!pNums) + return; + + pLabels->Add("Nums", pNums); + } + + pNums->Add(unPageNum); + pNums->Add(pPageLabel); + } + CMetadata* CCatalog::AddMetadata(CXref* pXref, CInfoDict* pInfo) + { + CMetadata* pMetadata = new CMetadata(pXref, pInfo); + Add("Metadata", pMetadata); + return pMetadata; + } + //---------------------------------------------------------------------------------------- + // CStructureTreeRoot + //---------------------------------------------------------------------------------------- + CStructureTreeRoot::CStructureTreeRoot(CXref* pXref) + { + pXref->Add(this); + Add("Type", "StructTreeRoot"); + } +} diff --git a/PdfWriter/Src/Catalog.h b/PdfFile/SrcWriter/Catalog.h similarity index 100% rename from PdfWriter/Src/Catalog.h rename to PdfFile/SrcWriter/Catalog.h diff --git a/PdfWriter/Src/Consts.h b/PdfFile/SrcWriter/Consts.h similarity index 97% rename from PdfWriter/Src/Consts.h rename to PdfFile/SrcWriter/Consts.h index 193dee5dec..f803932831 100644 --- a/PdfWriter/Src/Consts.h +++ b/PdfFile/SrcWriter/Consts.h @@ -1,103 +1,103 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_CONSTS_H -#define _PDF_WRITER_SRC_CONSTS_H - -#define OK 0 -#define NOERROR 0 - -// Стандартный размер буфера в memory-stream-object -#define STREAM_BUF_SIZ 4096 - -#define MAX_OPENED_FT_FACES 30 - -// Необходимый размер буффера для конвертирования с символьную строку. -#define SHORT_BUFFER_SIZE 32 -#define REAL_LEN 31//11 -#define INT_LEN 11 -#define TEXT_DEFAULT_LEN 256 -#define DATE_TIME_STR_LEN 23 - -// Соответсвующие длины в таблицу cross-reference-table -#define BYTE_OFFSET_LEN 10 -#define OBJ_ID_LEN 7 -#define GEN_NO_LEN 5 - -// Стандартный размер страницы (А4) -#define DEF_PAGE_WIDTH 595.276 -#define DEF_PAGE_HEIGHT 841.89 - -// Типы компрессии - -#define COMP_NONE 0x00 -#define COMP_TEXT 0x01 -#define COMP_IMAGE 0x02 -#define COMP_METADATA 0x04 -#define COMP_ALL 0x0F -// #define COMP_BEST_COMPRESS 0x10 -// #define COMP_BEST_SPEED 0x20 -#define COMP_MASK 0xFF - - -// Permission flags (only Revision 2 is supported) - -#define ENABLE_READ 0 -#define ENABLE_PRINT 4 -#define ENABLE_EDIT_ALL 8 -#define ENABLE_COPY 16 -#define ENABLE_EDIT 32 - -// Варианты просмотра документа - -#define HIDE_TOOLBAR 1 -#define HIDE_MENUBAR 2 -#define HIDE_WINDOW_UI 4 -#define FIT_WINDOW 8 -#define CENTER_WINDOW 16 - - -// Ограничения, в соответствии со спецификацией -#define LIMIT_MAX_INT 2147483647 -#define LIMIT_MIN_INT -2147483647 - -#define LIMIT_MAX_REAL 3.402823466e+38F -#define LIMIT_MIN_REAL -3.402823466e+38F - -#define LIMIT_MAX_STRING_LEN 65535 -#define LIMIT_MAX_NAME_LEN 127 - -#define LIMIT_MAX_ARRAY 8191 -#define LIMIT_MAX_DICT_ELEMENT 4095 -#define LIMIT_MAX_XREF_ELEMENT 8388607 -#define MAX_GENERATION_NUM 65535 - -#endif // _PDF_WRITER_SRC_CONSTS_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_CONSTS_H +#define _PDF_WRITER_SRC_CONSTS_H + +#define OK 0 +#define NOERROR 0 + +// Стандартный размер буфера в memory-stream-object +#define STREAM_BUF_SIZ 4096 + +#define MAX_OPENED_FT_FACES 30 + +// Необходимый размер буффера для конвертирования с символьную строку. +#define SHORT_BUFFER_SIZE 32 +#define REAL_LEN 31//11 +#define INT_LEN 11 +#define TEXT_DEFAULT_LEN 256 +#define DATE_TIME_STR_LEN 23 + +// Соответсвующие длины в таблицу cross-reference-table +#define BYTE_OFFSET_LEN 10 +#define OBJ_ID_LEN 7 +#define GEN_NO_LEN 5 + +// Стандартный размер страницы (А4) +#define DEF_PAGE_WIDTH 595.276 +#define DEF_PAGE_HEIGHT 841.89 + +// Типы компрессии + +#define COMP_NONE 0x00 +#define COMP_TEXT 0x01 +#define COMP_IMAGE 0x02 +#define COMP_METADATA 0x04 +#define COMP_ALL 0x0F +// #define COMP_BEST_COMPRESS 0x10 +// #define COMP_BEST_SPEED 0x20 +#define COMP_MASK 0xFF + + +// Permission flags (only Revision 2 is supported) + +#define ENABLE_READ 0 +#define ENABLE_PRINT 4 +#define ENABLE_EDIT_ALL 8 +#define ENABLE_COPY 16 +#define ENABLE_EDIT 32 + +// Варианты просмотра документа + +#define HIDE_TOOLBAR 1 +#define HIDE_MENUBAR 2 +#define HIDE_WINDOW_UI 4 +#define FIT_WINDOW 8 +#define CENTER_WINDOW 16 + + +// Ограничения, в соответствии со спецификацией +#define LIMIT_MAX_INT 2147483647 +#define LIMIT_MIN_INT -2147483647 + +#define LIMIT_MAX_REAL 3.402823466e+38F +#define LIMIT_MIN_REAL -3.402823466e+38F + +#define LIMIT_MAX_STRING_LEN 65535 +#define LIMIT_MAX_NAME_LEN 127 + +#define LIMIT_MAX_ARRAY 8191 +#define LIMIT_MAX_DICT_ELEMENT 4095 +#define LIMIT_MAX_XREF_ELEMENT 8388607 +#define MAX_GENERATION_NUM 65535 + +#endif // _PDF_WRITER_SRC_CONSTS_H diff --git a/PdfWriter/Src/Destination.cpp b/PdfFile/SrcWriter/Destination.cpp similarity index 96% rename from PdfWriter/Src/Destination.cpp rename to PdfFile/SrcWriter/Destination.cpp index 25e36be5bd..a95c3179c2 100644 --- a/PdfWriter/Src/Destination.cpp +++ b/PdfFile/SrcWriter/Destination.cpp @@ -1,153 +1,153 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Destination.h" -#include "Pages.h" - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CDestination - //---------------------------------------------------------------------------------------- - CDestination::CDestination(CPage* pPage, CXref* pXref) - { - pXref->Add(this); - - // Первый элемент массива должен быть страницей, которой принадлежит объект - Add((CObjectBase*)pPage); - Add("Fit"); // Значение по умолчанию Fit - } - bool CDestination::IsValid() const - { - if (m_arrList.size() < 2) - return false; - - CObjectBase* pObject = Get(0, false); - if ((object_type_DICT != pObject->GetType() || dict_type_PAGE != ((CDictObject*)pObject)->GetDictType()) && - (object_type_PROXY != pObject->GetType() || object_type_DICT != ((CProxyObject*)pObject)->Get()->GetType() || dict_type_PAGE != ((CDictObject*)((CProxyObject*)pObject)->Get())->GetDictType())) - return false; - - return true; - } - void CDestination::PrepareArray() - { - CPage* pPage = (CPage*)Get(0); - - if (m_arrList.size() > 1) - { - Clear(); - Add((CObjectBase*)pPage); - } - } - void CDestination::SetXYZ(float fLeft, float fTop, float fZoom) - { - if (!IsValid()) - return; - - // Если параметр приближения задан некорректно, тогда оставляем его нетронутым(что соответствует значению 0) - if (fZoom < 0.08 || fZoom > 32) - fZoom = 0; - - fLeft = std::max(fLeft, 0.f); - fTop = std::max(fTop, 0.f); - - PrepareArray(); - Add("XYZ"); - Add(fLeft); - Add(fTop); - Add(fZoom); - } - void CDestination::SetFit() - { - if (!IsValid()) - return; - - PrepareArray(); - Add("Fit"); - } - void CDestination::SetFitH(float fTop) - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitH"); - Add(fTop); - } - void CDestination::SetFitV(float fLeft) - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitV"); - Add(fLeft); - } - void CDestination::SetFitR(float fLeft, float fBottom, float fRight, float fTop) - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitR"); - Add(fLeft); - Add(fBottom); - Add(fRight); - Add(fTop); - } - void CDestination::SetFitB() - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitB"); - } - void CDestination::SetFitBH(float fTop) - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitBH"); - Add(fTop); - } - void CDestination::SetFitBV(float fLeft) - { - if (!IsValid()) - return; - - PrepareArray(); - Add("FitBV"); - Add(fLeft); - } -} - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Destination.h" +#include "Pages.h" + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CDestination + //---------------------------------------------------------------------------------------- + CDestination::CDestination(CPage* pPage, CXref* pXref) + { + pXref->Add(this); + + // Первый элемент массива должен быть страницей, которой принадлежит объект + Add((CObjectBase*)pPage); + Add("Fit"); // Значение по умолчанию Fit + } + bool CDestination::IsValid() const + { + if (m_arrList.size() < 2) + return false; + + CObjectBase* pObject = Get(0, false); + if ((object_type_DICT != pObject->GetType() || dict_type_PAGE != ((CDictObject*)pObject)->GetDictType()) && + (object_type_PROXY != pObject->GetType() || object_type_DICT != ((CProxyObject*)pObject)->Get()->GetType() || dict_type_PAGE != ((CDictObject*)((CProxyObject*)pObject)->Get())->GetDictType())) + return false; + + return true; + } + void CDestination::PrepareArray() + { + CPage* pPage = (CPage*)Get(0); + + if (m_arrList.size() > 1) + { + Clear(); + Add((CObjectBase*)pPage); + } + } + void CDestination::SetXYZ(float fLeft, float fTop, float fZoom) + { + if (!IsValid()) + return; + + // Если параметр приближения задан некорректно, тогда оставляем его нетронутым(что соответствует значению 0) + if (fZoom < 0.08 || fZoom > 32) + fZoom = 0; + + fLeft = std::max(fLeft, 0.f); + fTop = std::max(fTop, 0.f); + + PrepareArray(); + Add("XYZ"); + Add(fLeft); + Add(fTop); + Add(fZoom); + } + void CDestination::SetFit() + { + if (!IsValid()) + return; + + PrepareArray(); + Add("Fit"); + } + void CDestination::SetFitH(float fTop) + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitH"); + Add(fTop); + } + void CDestination::SetFitV(float fLeft) + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitV"); + Add(fLeft); + } + void CDestination::SetFitR(float fLeft, float fBottom, float fRight, float fTop) + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitR"); + Add(fLeft); + Add(fBottom); + Add(fRight); + Add(fTop); + } + void CDestination::SetFitB() + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitB"); + } + void CDestination::SetFitBH(float fTop) + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitBH"); + Add(fTop); + } + void CDestination::SetFitBV(float fLeft) + { + if (!IsValid()) + return; + + PrepareArray(); + Add("FitBV"); + Add(fLeft); + } +} + diff --git a/PdfWriter/Src/Destination.h b/PdfFile/SrcWriter/Destination.h similarity index 100% rename from PdfWriter/Src/Destination.h rename to PdfFile/SrcWriter/Destination.h diff --git a/PdfWriter/Src/Document.cpp b/PdfFile/SrcWriter/Document.cpp similarity index 96% rename from PdfWriter/Src/Document.cpp rename to PdfFile/SrcWriter/Document.cpp index ac1484c7d5..e8f200ab70 100644 --- a/PdfWriter/Src/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1,1415 +1,1415 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Document.h" -#include "Info.h" -#include "Catalog.h" -#include "Streams.h" -#include "EncryptDictionary.h" -#include "Encrypt.h" -#include "Pages.h" -#include "Outline.h" -#include "Destination.h" -#include "GState.h" -#include "Annotation.h" -#include "Image.h" -#include "Font14.h" -#include "FontCidTT.h" -#include "FontTT.h" -#include "Shading.h" -#include "Pattern.h" -#include "AcroForm.h" -#include "Field.h" -#include "ResourcesDictionary.h" - -#include "../../DesktopEditor/agg-2.4/include/agg_span_hatch.h" -#include "../../DesktopEditor/common/SystemUtils.h" - -#ifdef CreateFont -#undef CreateFont -#endif - -#ifndef VALUE2STR -#define VALUE_TO_STRING(x) #x -#define VALUE2STR(x) VALUE_TO_STRING(x) -#endif - -namespace PdfWriter -{ - const char* c_sPdfHeader = "%PDF-1.7\015%\315\312\322\251\015"; - const char* c_sPdfAHeader = "%PDF-1.4\015%\315\312\322\251\015"; - //---------------------------------------------------------------------------------------- - // CDocument - //---------------------------------------------------------------------------------------- - CDocument::CDocument() - { - m_pCatalog = NULL; - m_pOutlines = NULL; - m_pXref = NULL; - m_pLastXref = NULL; - m_pPageTree = NULL; - m_pCurPage = NULL; - m_nCurPageNum = -1; - m_unFormFields = 0; - m_pInfo = NULL; - m_pTrailer = NULL; - m_pResources = NULL; - m_bEncrypt = false; - m_pEncryptDict = NULL; - m_unCompressMode = COMP_NONE; - m_pJbig2 = NULL; - memset((void*)m_sTTFontTag, 0x00, 8); - m_pTransparencyGroup = NULL; - m_pFreeTypeLibrary = NULL; - m_pAcroForm = NULL; - m_pFieldsResources = NULL; - m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; - - m_bPDFAConformance = false; - } - CDocument::~CDocument() - { - Close(); - } - bool CDocument::CreateNew() - { - Close(); - - m_pXref = new CXref(this, 0); - if (!m_pXref) - return false; - - m_pTrailer = m_pXref->GetTrailer(); - if (!m_pTrailer) - return false; - - m_pCatalog = new CCatalog(m_pXref); - if (!m_pCatalog) - return false; - - m_pCatalog->SetPageMode(pagemode_UseNone); - m_pCatalog->SetPageLayout(pagelayout_OneColumn); - - m_pPageTree = m_pCatalog->GetRoot(); - if (!m_pPageTree) - return false; - - m_pInfo = new CInfoDict(m_pXref); - if (!m_pInfo) - return false; - - m_pInfo->SetTime(InfoCreationDate); - m_pInfo->SetTime(InfoModaDate); - - std::wstring sCreator = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (sCreator.empty()) - sCreator = NSSystemUtils::gc_EnvApplicationNameDefault; - std::string sCreatorA = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sCreator); - -#if defined(INTVER) - std::string sVersion = VALUE2STR(INTVER); - sCreatorA += ("/" + sVersion); -#endif - - m_pInfo->SetInfo(InfoProducer, sCreatorA.c_str()); - m_pInfo->SetInfo(InfoCreator, sCreatorA.c_str()); - - CMetadata* pMetadata = m_pCatalog->AddMetadata(m_pXref, m_pInfo); - if (IsPDFA()) - { - CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); - if (!pID) - { - BYTE arrId[16]; - CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); - - pID = new CArrayObject(); - m_pTrailer->Add("ID", pID); - - pID->Add(new CBinaryObject(arrId, 16)); - pID->Add(new CBinaryObject(arrId, 16)); - } - } - - m_nCurPageNum = -1; - - m_vExtGrStates.clear(); - m_vFillAlpha.clear(); - m_vStrokeAlpha.clear(); - m_vRadioGroups.clear(); - - m_pTransparencyGroup = NULL; - - return true; - } - void CDocument::Close() - { - // Все объекты удаляются внутри CXref - RELEASEOBJECT(m_pXref); - - m_pLastXref = NULL; - m_pTrailer = NULL; - m_pResources = NULL; - m_pCatalog = NULL; - m_pOutlines = NULL; - m_pPageTree = NULL; - m_pCurPage = NULL; - m_nCurPageNum = 0; - m_unFormFields = 0; - m_bEncrypt = false; - m_pEncryptDict = NULL; - m_pInfo = NULL; - m_unCompressMode = COMP_NONE; - m_pJbig2 = NULL; - m_pTransparencyGroup= NULL; - m_pAcroForm = NULL; - m_pFieldsResources = NULL; - memset((void*)m_sTTFontTag, 0x00, 8); - m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; - - m_vExtGrStates.clear(); - m_vStrokeAlpha.clear(); - m_vFillAlpha.clear(); - m_vShadings.clear(); - m_vCidTTFonts.clear(); - m_vTTFonts.clear(); - m_vFreeTypeFonts.clear(); - m_vSignatures.clear(); - if (m_pFreeTypeLibrary) - { - FT_Done_FreeType(m_pFreeTypeLibrary); - m_pFreeTypeLibrary = NULL; - } - } - bool CDocument::SaveToFile(const std::wstring& wsPath, bool bAdd) - { - CFileStream* pStream = new CFileStream(); - if (!pStream || !pStream->OpenFile(wsPath, bAdd)) - return false; - - if (m_pJbig2) - m_pJbig2->FlushStreams(); - - SaveToStream((CStream*)pStream); - delete pStream; - - Sign(wsPath, m_pXref->GetSizeXRef()); - - return true; - } - void CDocument::SaveToStream(CStream* pStream) - { - unsigned long nRet = OK; - - // Пишем заголовок - if (IsPDFA()) - pStream->WriteStr(c_sPdfAHeader); - else - pStream->WriteStr(c_sPdfHeader); - - if (false == m_wsDocumentID.empty()) - { - std::string sDocumentID = "%DocumentID " + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_wsDocumentID); - pStream->WriteStr(sDocumentID.c_str()); - } - - // Добавляем в Trailer необходимые элементы - m_pTrailer->Add("Root", m_pCatalog); - m_pTrailer->Add("Info", m_pInfo); - - // Шифруем документ, если это необходимо - CEncrypt* pEncrypt = NULL; - if (m_bEncrypt) - { - pEncrypt = m_pEncryptDict->GetEncrypt(); - PrepareEncryption(); - } - - m_pXref->WriteToStream(pStream, pEncrypt); - } - void CDocument::PrepareEncryption() - { - CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt(); - if (!pEncrypt) - return; - - m_pEncryptDict->Prepare(m_pInfo, m_pXref); - - CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); - if (!pID) - { - pID = new CArrayObject(); - m_pTrailer->Add("ID", pID); - } - else - pID->Clear(); - - pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); - pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); - } - void CDocument::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) - { - if (IsPDFA()) - return; - - if (!m_pEncryptDict) - m_pEncryptDict = new CEncryptDict(m_pXref); - - if (!m_pEncryptDict) - return; - - m_pEncryptDict->SetPasswords(wsOwnerPassword, wsUserPassword); - - m_pTrailer->Add("Encrypt", m_pEncryptDict); - m_bEncrypt = true; - } - CPage* CDocument::AddPage() - { - CPage* pPage = new CPage(m_pXref, m_pPageTree, this); - m_pPageTree->AddPage(pPage); - m_pCurPage = pPage; - -#ifndef FILTER_FLATE_DECODE_DISABLED - if (m_unCompressMode & COMP_TEXT) - pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - - m_nCurPageNum++; - return pPage; - } - CPage* CDocument::GetPage(const unsigned int &unPage) - { - if (unPage >= m_pPageTree->GetCount()) - return NULL; - - return m_pPageTree->GetPage(unPage); - } - unsigned int CDocument::GetPagesCount() const - { - return m_pPageTree->GetCount(); - } - void CDocument::SetDocumentID(const std::wstring& documentID) - { - m_wsDocumentID = documentID; - } - void CDocument::SetTitle(const std::string& sTitle) - { - if (!m_pInfo) - return; - m_pInfo->SetInfo(InfoTitle, sTitle.c_str()); - } - void CDocument::SetAuthor(const std::string& sAuthor) - { - if (!m_pInfo) - return; - m_pInfo->SetInfo(InfoAuthor, sAuthor.c_str()); - } - void CDocument::SetSubject(const std::string& sSubject) - { - if (!m_pInfo) - return; - m_pInfo->SetInfo(InfoSubject, sSubject.c_str()); - } - void CDocument::SetKeywords(const std::string& sKeywords) - { - if (!m_pInfo) - return; - m_pInfo->SetInfo(InfoKeyWords, sKeywords.c_str()); - } - - void CDocument::SetPermission(unsigned int unPermission) - { - if (!m_bEncrypt) - return; - - CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt(); - pEncrypt->SetPermission(unPermission); - } - void CDocument::SetCompressionMode(unsigned int unMode) - { - m_unCompressMode = unMode; - } - unsigned int CDocument::GetCompressionMode() const - { - return m_unCompressMode; - } - void CDocument::SetPDFAConformanceMode(bool isPDFA) - { - m_bPDFAConformance = isPDFA; - } - bool CDocument::IsPDFA() const - { - return m_bPDFAConformance; - } - void CDocument::AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) - { - CDictObject* pPageLabel = CreatePageLabel(eStyle, unFirstPage, sPrefix); - if (!pPageLabel) - return; - - m_pCatalog->AddPageLabel(m_nCurPageNum, pPageLabel); - } - void CDocument::AddPageLabel(unsigned int unPageNum, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) - { - CDictObject* pPageLabel = CreatePageLabel(eStyle, unFirstPage, sPrefix); - if (!pPageLabel) - return; - - m_pCatalog->AddPageLabel(unPageNum, pPageLabel); - } - CDictObject* CDocument::CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) - { - CDictObject* pLabel = new CDictObject(); - if (!pLabel) - return NULL; - - eStyle = std::min(std::max(eStyle, pagenumstyle_Min), pagenumstyle_Max); - switch (eStyle) - { - case pagenumstyle_UpperRoman: pLabel->Add("S", "R"); break; - case pagenumstyle_LowerRoman: pLabel->Add("S", "r"); break; - case pagenumstyle_UpperLetters: pLabel->Add("S", "A"); break; - case pagenumstyle_LowerLetters: pLabel->Add("S", "a"); break; - case pagenumstyle_Decimal: pLabel->Add("S", "D"); break; - } - - if (sPrefix && 0 != sPrefix[0]) - pLabel->Add("P", new CStringObject(sPrefix)); - - if (0 != unFirstPage) - pLabel->Add("St", unFirstPage); - - return pLabel; - } - COutline* CDocument::CreateOutline(COutline* pParent, const char* sTitle) - { - if (!pParent) - { - if (!m_pOutlines) - { - m_pOutlines = new COutline(m_pXref); - if (m_pOutlines) - m_pCatalog->Add("Outlines", m_pOutlines); - else - return NULL; - } - - pParent = m_pOutlines; - } - - return new COutline(pParent, sTitle, m_pXref); - } - CDestination* CDocument::CreateDestination(unsigned int unPageIndex) - { - if (unPageIndex >= m_pPageTree->GetCount()) - return NULL; - - CPage* pPage = m_pPageTree->GetPage(unPageIndex); - if (pPage) - return new CDestination(pPage, m_pXref); - return NULL; - } - CExtGrState* CDocument::FindExtGrState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) - { - CExtGrState* pExtGrState = NULL; - for (unsigned int unIndex = 0, unCount = m_vExtGrStates.size(); unIndex < unCount; unIndex++) - { - pExtGrState = m_vExtGrStates.at(unIndex); - - if (dAlphaStroke != pExtGrState->GetAlphaStroke()) - continue; - - if (dAlphaFill != pExtGrState->GetAlphaFill()) - continue; - - if (eMode != pExtGrState->GetBlendMode()) - continue; - - if ((0 == nStrokeAdjustment ? false : true) != pExtGrState->GetStrokeAdjustment()) - continue; - - return pExtGrState; - } - - return NULL; - } - CExtGrState* CDocument::GetExtGState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) - { - if (IsPDFA()) - return NULL; - - CExtGrState* pExtGrState = FindExtGrState(dAlphaStroke, dAlphaFill, eMode, nStrokeAdjustment); - - if (!pExtGrState) - { - pExtGrState = new CExtGrState(m_pXref); - if (!pExtGrState) - return NULL; - - if (-1 != dAlphaStroke) - pExtGrState->SetAlphaStroke(dAlphaStroke); - - if (-1 != dAlphaFill) - pExtGrState->SetAlphaFill(dAlphaFill); - - if (blendmode_Unknown != eMode) - pExtGrState->SetBlendMode(eMode); - - if (-1 != nStrokeAdjustment) - pExtGrState->SetStrokeAdjustment(0 == nStrokeAdjustment ? false : true); - - m_vExtGrStates.push_back(pExtGrState); - } - - return pExtGrState; - } - CExtGrState* CDocument::GetStrokeAlpha(double dAlpha) - { - if (IsPDFA()) - return NULL; - - CExtGrState* pExtGrState = NULL; - for (unsigned int unIndex = 0, unCount = m_vStrokeAlpha.size(); unIndex < unCount; unIndex++) - { - pExtGrState = m_vStrokeAlpha.at(unIndex); - - if (fabs(dAlpha - pExtGrState->GetAlphaStroke()) < 0.001) - return pExtGrState; - } - - pExtGrState = new CExtGrState(m_pXref); - if (!pExtGrState) - return NULL; - - pExtGrState->SetAlphaStroke(dAlpha); - - m_vStrokeAlpha.push_back(pExtGrState); - return pExtGrState; - } - CExtGrState* CDocument::GetFillAlpha(double dAlpha) - { - if (IsPDFA()) - return NULL; - - CExtGrState* pExtGrState = NULL; - for (unsigned int unIndex = 0, unCount = m_vFillAlpha.size(); unIndex < unCount; unIndex++) - { - pExtGrState = m_vFillAlpha.at(unIndex); - - if (fabs(dAlpha - pExtGrState->GetAlphaFill()) < 0.001) - return pExtGrState; - } - - pExtGrState = new CExtGrState(m_pXref); - if (!pExtGrState) - return NULL; - - pExtGrState->SetAlphaFill(dAlpha); - - m_vFillAlpha.push_back(pExtGrState); - return pExtGrState; - } - CAnnotation* CDocument::CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText) - { - CAnnotation* pAnnot = new CTextAnnotation(m_pXref, oRect, sText); - if (pAnnot) - { - CPage* pPage = m_pPageTree->GetPage(unPageNum); - if (pPage) - pPage->AddAnnotation(pAnnot); - } - - return pAnnot; - } - CAnnotation* CDocument::CreateLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, CDestination* pDest) - { - CAnnotation* pAnnot = new CLinkAnnotation(m_pXref, oRect, pDest); - - if (pAnnot) - { - CPage* pPage = m_pPageTree->GetPage(unPageNum); - if (pPage) - pPage->AddAnnotation(pAnnot); - } - - return pAnnot; - } - CAnnotation* CDocument::CreateLinkAnnot(CPage* pPage, const TRect& oRect, CDestination* pDest) - { - CAnnotation* pAnnot = new CLinkAnnotation(m_pXref, oRect, pDest); - - if (pAnnot) - pPage->AddAnnotation(pAnnot); - - return pAnnot; - } - CAnnotation* CDocument::CreateUriLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, const char* sUri) - { - CAnnotation* pAnnot = new CUriLinkAnnotation(m_pXref, oRect, sUri); - - if (pAnnot) - { - CPage* pPage = m_pPageTree->GetPage(unPageNum); - if (pPage) - pPage->AddAnnotation(pAnnot); - } - - return pAnnot; - } - CAnnotation* CDocument::CreateUriLinkAnnot(CPage* pPage, const TRect& oRect, const char* sUrl) - { - CAnnotation* pAnnot = new CUriLinkAnnotation(m_pXref, oRect, sUrl); - - if (pAnnot) - pPage->AddAnnotation(pAnnot); - - return pAnnot; - } - CImageDict* CDocument::CreateImage() - { - return new CImageDict(m_pXref, this); - } - CFont14* CDocument::CreateFont14(EStandard14Fonts eType) - { - return new CFont14(m_pXref, this, eType); - } - CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) - { - CFontCidTrueType* pFont = FindCidTrueTypeFont(wsFontPath, unIndex); - if (pFont) - return pFont; - - pFont = new CFontCidTrueType(m_pXref, this, wsFontPath, unIndex); - if (!pFont) - return NULL; - - // 0 GID всегда используется для .notdef символа, не используем данный код для настоящих символов - unsigned int unUnicode = 0; - pFont->EncodeGID(0, &unUnicode, 1); - - m_vCidTTFonts.push_back(TFontInfo(wsFontPath, unIndex, pFont)); - return pFont; - } - CFontCidTrueType* CDocument::FindCidTrueTypeFont(const std::wstring &wsFontPath, unsigned int unIndex) - { - for (int nIndex = 0, nCount = m_vCidTTFonts.size(); nIndex < nCount; nIndex++) - { - TFontInfo& oInfo = m_vCidTTFonts.at(nIndex); - if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) - return (CFontCidTrueType*)oInfo.pFont; - } - - return NULL; - } - CFontTrueType* CDocument::CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) - { - for (int nIndex = 0, nCount = m_vTTFonts.size(); nIndex < nCount; nIndex++) - { - TFontInfo& oInfo = m_vTTFonts.at(nIndex); - if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) - return (CFontTrueType*)oInfo.pFont; - } - - CFontTrueType* pFont = new CFontTrueType(m_pXref, this, wsFontPath, unIndex); - if (!pFont) - return NULL; - - m_vTTFonts.push_back(TFontInfo(wsFontPath, unIndex, pFont)); - return pFont; - } - CFontTrueType* CDocument::CreateTrueTypeFont(CFontCidTrueType* pCidFont) - { - for (int nIndex = 0, nCount = m_vCidTTFonts.size(); nIndex < nCount; nIndex++) - { - TFontInfo& oInfo = m_vCidTTFonts.at(nIndex); - if (pCidFont == (CFontCidTrueType*)oInfo.pFont) - { - return CreateTrueTypeFont(oInfo.wsPath, oInfo.unIndex); - } - } - - return NULL; - } - CFont14* CDocument::GetDefaultCheckboxFont() - { - if (!m_pDefaultCheckBoxFont) - m_pDefaultCheckBoxFont = new CFont14(m_pXref, this, EStandard14Fonts::standard14fonts_ZapfDingbats); - - return m_pDefaultCheckBoxFont; - } - char* CDocument::GetTTFontTag() - { - if (0 == m_sTTFontTag[0]) - { - MemCpy((BYTE*)m_sTTFontTag, (BYTE*)"BAAAAA+", 7); - } - else - { - for (unsigned int nIndex = 0; nIndex <= 5; nIndex++) - { - m_sTTFontTag[nIndex] += 1; - if (m_sTTFontTag[nIndex] > 'Z') - m_sTTFontTag[nIndex] = 'A'; - else - break; - } - } - - return m_sTTFontTag; - } - void CDocument::AddFreeTypeFont(CFontCidTrueType* pFont) - { - for (int nIndex = 0, nCount = m_vFreeTypeFonts.size(); nIndex < nCount; nIndex++) - { - if (pFont == m_vFreeTypeFonts.at(nIndex)) - { - if (nIndex >= 10) - { - m_vFreeTypeFonts.erase(m_vFreeTypeFonts.begin() + nIndex); - m_vFreeTypeFonts.insert(m_vFreeTypeFonts.begin(), pFont); - } - return; - } - } - - m_vFreeTypeFonts.insert(m_vFreeTypeFonts.begin(), pFont); - - int nFontsCount = m_vFreeTypeFonts.size(); - if (nFontsCount > MAX_OPENED_FT_FACES) - { - for (int nFontIndex = MAX_OPENED_FT_FACES; nFontIndex < nFontsCount; nFontIndex++) - { - CFontCidTrueType* pFont = m_vFreeTypeFonts.at(nFontIndex); - pFont->CloseFontFace(); - } - m_vFreeTypeFonts.erase(m_vFreeTypeFonts.begin() + MAX_OPENED_FT_FACES, m_vFreeTypeFonts.end()); - } - } - FT_Library CDocument::GetFreeTypeLibrary() - { - if (!m_pFreeTypeLibrary) - FT_Init_FreeType(&m_pFreeTypeLibrary); - - return m_pFreeTypeLibrary; - } - CJbig2Global* CDocument::GetJbig2Global() - { - if (m_pJbig2 && m_pJbig2->GetImagesCount() > 4) - { - // Удалять не надо, т.к. объект удалится в CXref - m_pJbig2->FlushStreams(); - m_pJbig2 = NULL; - } - - if (!m_pJbig2) - m_pJbig2 = new CJbig2Global(m_pXref); - - return m_pJbig2; - } - CShading* CDocument::CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) - { - pExtGrState = NULL; - - bool bNeedAlpha = false; - unsigned char* pA = new unsigned char[3 * nCount]; - if (!pA) - return NULL; - - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - pA[3 * nIndex + 0] = pAlphas[nIndex]; - pA[3 * nIndex + 1] = pAlphas[nIndex]; - pA[3 * nIndex + 2] = pAlphas[nIndex]; - - if (255 != pAlphas[nIndex]) - bNeedAlpha = true; - } - - if (!bNeedAlpha) - { - delete[] pA; - if (bAxial) - return CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount); - else - return CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount); - } - - // Создаем 2 shading-объекта, один цветной RGB, второй серый со значениями альфа-канала - CShading* pColorShading = NULL; - CShading* pAlphaShading = NULL; - - if (bAxial) - { - pColorShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount); - pAlphaShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pA, pPoints, nCount); - } - else - { - pColorShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount); - pAlphaShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pA, pPoints, nCount); - } - delete[] pA; - - if (!IsPDFA()) - { - if (!m_pTransparencyGroup) - { - m_pTransparencyGroup = new CDictObject(); - m_pTransparencyGroup->Add("Type", "Group"); - m_pTransparencyGroup->Add("S", "Transparency"); - m_pTransparencyGroup->Add("CS", "DeviceRGB"); - } - - pPage->Add("Group", m_pTransparencyGroup); - } - double dWidth = pPage->GetWidth(); - double dHeight = pPage->GetHeight(); - - // Создаем графический объект, который будет альфа-маской - CDictObject* pXObject = new CDictObject(m_pXref); - pXObject->Add("Type", "XObject"); - pXObject->Add("Subtype", "Form"); - pXObject->Add("BBox", CArrayObject::CreateBox(0, 0, dWidth, dHeight)); - if (m_pTransparencyGroup) - pXObject->Add("Group", m_pTransparencyGroup); - CDictObject* pResources = new CDictObject(); - pXObject->Add("Resources", pResources); - CDictObject* pResShadings = new CDictObject(); - pResources->Add("Shading", pResShadings); - pResShadings->Add("S1", pAlphaShading); - CStream* pStream = pXObject->GetStream(); - - pStream->WriteStr("0 0 "); - pStream->WriteReal(dWidth); - pStream->WriteChar(' '); - pStream->WriteReal(dHeight); - pStream->WriteStr(" re\012W\012\n\012/S1 sh\012"); - - // Создаем обект-маску для графического состояние - CDictObject* pMask = new CDictObject(); - m_pXref->Add(pMask); - pMask->Add("Type", "Mask"); - pMask->Add("S", "Luminosity"); - pMask->Add("G", pXObject); - - if (!IsPDFA()) - { - // Создаем ExtGState объект, в который мы запишем альфа-маску - pExtGrState = new CExtGrState(m_pXref); - pExtGrState->Add("BM", "Normal"); - pExtGrState->Add("ca", 1); - pExtGrState->Add("SMask", pMask); - } - - return pColorShading; - } - CShading* CDocument::CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount) - { - for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++) - { - CShading* pShading = m_vShadings.at(nIndex); - if (shadingtype_Axial == pShading->GetShadingType() - && ((CAxialShading*)pShading)->Compare(dX0, dY0, dX1, dY1) - && pShading->CompareColors(pColors, pPoints, nCount, true) - && pShading->CompareExtend(true, true)) - return pShading; - } - - CAxialShading* pShading = new CAxialShading(m_pXref, dX0, dY0, dX1, dY1); - if (!pShading) - return NULL; - - pShading->SetRgbColors(pColors, pPoints, nCount); - pShading->SetExtend(true, true); - - m_vShadings.push_back(pShading); - - return pShading; - } - CShading* CDocument::CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount) - { - for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++) - { - CShading* pShading = m_vShadings.at(nIndex); - if (shadingtype_Radial == pShading->GetShadingType() - && ((CRadialShading*)pShading)->Compare(dX0, dY0, dR0, dX1, dY1, dR1) - && pShading->CompareColors(pColors, pPoints, nCount, true) - && pShading->CompareExtend(true, true)) - return pShading; - } - - CRadialShading* pShading = new CRadialShading(m_pXref, dX0, dY0, dR0, dX1, dY1, dR1); - if (!pShading) - return NULL; - - pShading->SetRgbColors(pColors, pPoints, nCount); - pShading->SetExtend(true, true); - - m_vShadings.push_back(pShading); - - return pShading; - } - CImageTilePattern*CDocument::CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType, double dXStepSpacing, double dYStepSpacing) - { - return new CImageTilePattern(m_pXref, dW, dH, pImageDict, pMatrix, eType, dXStepSpacing, dYStepSpacing); - } - CImageTilePattern*CDocument::CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch) - { - // TODO: Надо бы сделать мап, чтобы не создавать одинаковых паттернов - - CImageDict* pImage = CreateImage(); - BYTE* pBuffer = new BYTE[3 * HATCH_TX_SIZE * HATCH_TX_SIZE]; - if (!pBuffer) - return NULL; - - TColor oColor1(nR1, nG1, nB1); - TColor oColor2(nR2, nG2, nB2); - agg::GetHatchPattern(wsHatch, (TColor*)pBuffer, oColor1, oColor2); - pImage->LoadRaw(pBuffer, 3 * HATCH_TX_SIZE * HATCH_TX_SIZE, HATCH_TX_SIZE, HATCH_TX_SIZE); - delete[] pBuffer; - - if (255 != nAlpha1 || 255 != nAlpha2) - { - BYTE* pSMask = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE]; - if (pSMask) - { - agg::GetHatchPattern(wsHatch, pSMask, nAlpha1, nAlpha2); - pImage->LoadSMask(pSMask, (unsigned int)HATCH_TX_SIZE * HATCH_TX_SIZE, (unsigned int)HATCH_TX_SIZE, (unsigned int)HATCH_TX_SIZE); - delete[] pSMask; - } - } - - return CreateImageTilePattern(dW, dH, pImage, NULL, imagetilepatterntype_Default); - } - CShading* CDocument::CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) - { - double pPattern[] ={ dX0, dY0, dX1, dY1 }; - return CreateShading(pPage, pPattern, true, pColors, pAlphas, pPoints, nCount, pExtGrState); - } - CShading* CDocument::CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) - { - double pPattern[] ={ dX0, dY0, dR0, dX1, dY1, dR1 }; - return CreateShading(pPage, pPattern, false, pColors, pAlphas, pPoints, nCount, pExtGrState); - } - CResourcesDict* CDocument::GetFieldsResources() - { - if (!m_pFieldsResources) - { - if (!CheckAcroForm()) - return NULL; - - m_pFieldsResources = new CResourcesDict(m_pXref, false, true); - m_pAcroForm->Add("DR", m_pFieldsResources); - } - - return m_pFieldsResources; - } - CTextField* CDocument::CreateTextField() - { - if (!CheckAcroForm()) - return NULL; - - CTextField* pField = new CTextField(m_pXref, this); - if (!pField) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - - return pField; - } - CChoiceField* CDocument::CreateChoiceField() - { - if (!CheckAcroForm()) - return NULL; - - CChoiceField* pField = new CChoiceField(m_pXref, this); - if (!pField) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - - return pField; - } - CSignatureField* CDocument::CreateSignatureField() - { - if (!CheckAcroForm()) - return NULL; - - CSignatureField* pField = new CSignatureField(m_pXref, this); - if (!pField) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - - return pField; - } - CCheckBoxField* CDocument::CreateCheckBoxField() - { - if (!CheckAcroForm()) - return NULL; - - CCheckBoxField* pField = new CCheckBoxField(m_pXref, this); - if (!pField) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - - return pField; - } - CRadioGroupField* CDocument::GetRadioGroupField(const std::wstring& wsGroupName) - { - CRadioGroupField* pField = FindRadioGroupField(wsGroupName); - if (!pField) - { - if (!CheckAcroForm()) - return NULL; - - pField = new CRadioGroupField(m_pXref, this); - if (!pField) - return NULL; - - m_vRadioGroups.push_back(pField); - - pField->SetFieldName(wsGroupName); - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - } - - return pField; - } - CRadioGroupField* CDocument::FindRadioGroupField(const std::wstring& wsGroupName) - { - CRadioGroupField* pField = NULL; - for (unsigned int unIndex = 0, unCount = m_vRadioGroups.size(); unIndex < unCount; ++unIndex) - { - pField = m_vRadioGroups.at(unIndex); - - if (pField->GetFieldName() == wsGroupName) - return pField; - } - - return NULL; - } - CPictureField* CDocument::CreatePictureField() - { - if (!CheckAcroForm()) - return NULL; - - CPictureField* pField = new CPictureField(m_pXref, this); - if (!pField) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pField); - - return pField; - } - bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) - { - CFieldBase* pBase = m_mFields[sName]; - if (pBase) - { - if (!pBase->GetKidsCount()) - { - CFieldBase* pParent = new CFieldBase(m_pXref, this); - pParent->SetFieldName(sName, true); - pParent->Add("Ff", pBase->GetFieldFlag()); - pParent->Add("FT", pBase->GetFieldType()); - - - pBase->SetParent(pParent); - pBase->ClearKidRecords(); - pParent->AddKid(pBase); - - m_mFields[sName] = pParent; - pField->ClearKidRecords(); - pField->SetParent(pParent); - pParent->AddKid(pField); - - CChoiceField* pChoice = dynamic_cast(pBase); - if (pChoice) - pChoice->UpdateSelectedIndexToParent(); - - CTextField* pTextField = dynamic_cast(pBase); - int nMaxLen = 0; - if (pTextField && 0 != (nMaxLen = pTextField->GetMaxLen())) - { - pBase->Remove("MaxLen"); - pParent->Add("MaxLen", nMaxLen); - } - - pParent->UpdateKidsPlaceHolder(); - } - else - { - pField->ClearKidRecords(); - pField->SetParent(pBase); - pBase->AddKid(pField); - - CChoiceField* pChoice = dynamic_cast(pBase); - if (pChoice) - pChoice->UpdateSelectedIndexToParent(); - - pBase->UpdateKidsPlaceHolder(); - } - - return true; - } - else - { - m_mFields[sName] = pField; - return false; - } - } - bool CDocument::CheckAcroForm() - { - if (!m_pXref || !m_pCatalog) - return false; - - if (!m_pAcroForm) - { - m_pAcroForm = new CDictObject(); - if (!m_pAcroForm) - return false; - - m_pCatalog->Add("AcroForm", m_pAcroForm); - m_pAcroForm->Add("Fields", new CArrayObject()); - } - - return (!!m_pAcroForm); - } - bool CDocument::CreatePageTree(CXref* pXref, CPageTree* pPageTree) - { - if (!pXref || !pPageTree) - return false; - - if (!m_pPageTree) - m_pPageTree = pPageTree; - else - m_pPageTree->Join(pPageTree); - pXref->SetPrev(m_pLastXref); - m_pLastXref = pXref; - - return true; - } - bool CDocument::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) - { - if (!pXref || !pCatalog) - return false; - Close(); - - m_pXref = new CXref(this, nSizeXRef); - if (!m_pXref) - return false; - m_pXref->SetPrevAddr(nPosLastXRef); - m_pLastXref = m_pXref; - - m_pTrailer = m_pXref->GetTrailer(); - if (!m_pTrailer) - return false; - - SetCompressionMode(COMP_ALL); - - m_pCatalog = pCatalog; - pXref->SetPrev(m_pLastXref); - m_pLastXref = pXref; - - CObjectBase* pAcroForm = m_pCatalog->Get("AcroForm"); - if (pAcroForm && pAcroForm->GetType() == object_type_DICT) - m_pAcroForm = (CDictObject*)pAcroForm; - - if (m_pAcroForm) - { - CObjectBase* pFieldsResources = m_pAcroForm->Get("DR"); - if (pFieldsResources && pFieldsResources->GetType() == object_type_DICT) - m_pFieldsResources = (CResourcesDict*)pFieldsResources; - - // TODO заполнить поля m_pFieldsResources - } - - if (pEncrypt) - { - m_pEncryptDict = pEncrypt; - m_bEncrypt = true; - } - - m_unFormFields = nFormField; - m_wsFilePath = wsPath; - return true; - } - std::pair CDocument::GetPageRef(int nPageIndex) - { - std::pair pRes = std::make_pair(0, 0); - if (!m_pPageTree) - return pRes; - - CObjectBase* pObj = m_pPageTree->GetObj(nPageIndex); - if (pObj) - { - pRes.first = pObj->GetObjId(); - pRes.second = pObj->GetGenNo(); - } - - return pRes; - } - bool CDocument::EditPage(CXref* pXref, CPage* pPage) - { - if (!pXref || !pPage) - return false; - - pPage->AddContents(m_pXref); -#ifndef FILTER_FLATE_DECODE_DISABLED - if (m_unCompressMode & COMP_TEXT) - pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - - pXref->SetPrev(m_pLastXref); - m_pLastXref = pXref; - m_pCurPage = pPage; - - return true; - } - CPage* CDocument::AddPage(int nPageIndex) - { - if (!m_pPageTree) - return NULL; - - CPage* pNewPage = new CPage(m_pXref, NULL, this); - if (!pNewPage) - return NULL; - bool bRes = m_pPageTree->InsertPage(nPageIndex, pNewPage); - if (!bRes) - return NULL; - -#ifndef FILTER_FLATE_DECODE_DISABLED - if (m_unCompressMode & COMP_TEXT) - pNewPage->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - m_pCurPage = pNewPage; - return pNewPage; - } - bool CDocument::DeletePage(int nPageIndex) - { - if (!m_pPageTree) - return false; - - CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); - if (pObj) - { - CXref* pXref = new CXref(this, pObj->GetObjId(), pObj->GetGenNo()); - delete pObj; - if (!pXref) - return false; - - pXref->SetPrev(m_pLastXref); - m_pLastXref = pXref; - return true; - } - return false; - } - bool CDocument::AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) - { - if (!pTrailer || !pInfoXref || !pInfo || m_wsFilePath.empty()) - return false; - - CFileStream* pStream = new CFileStream(); - if (!pStream) - return false; - - if (!pStream->OpenFile(m_wsFilePath, false)) - { - RELEASEOBJECT(pStream); - return false; - } - - m_pTrailer = pTrailer; - m_pInfo = pInfo; - - std::wstring sCreator = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); - if (sCreator.empty()) - sCreator = NSSystemUtils::gc_EnvApplicationNameDefault; - std::string sCreatorA = U_TO_UTF8(sCreator); - -#if defined(INTVER) - sCreatorA += "/"; - sCreatorA += VALUE2STR(INTVER); -#endif - - const char* cCreator = m_pInfo->GetInfo(InfoProducer); - m_pInfo->SetInfo(InfoCreator, cCreator ? cCreator : sCreatorA.c_str()); - m_pInfo->SetInfo(InfoProducer, sCreatorA.c_str()); - - pInfoXref->SetPrev(m_pLastXref); - pXref->SetPrev(pInfoXref); - m_pLastXref = pXref; - - // Вторая часть идентификатора должна обновляться - CObjectBase* pID = m_pTrailer->Get("ID"); - if (pID && pID->GetType() == object_type_ARRAY) - { - BYTE arrId[16]; - CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); - - CObjectBase* pObject = ((CArrayObject*)pID)->Get(1, false); - ((CArrayObject*)pID)->Insert(pObject, new CBinaryObject(arrId, 16), true); - } - - CEncrypt* pEncrypt = NULL; - if (m_bEncrypt) - pEncrypt = m_pEncryptDict->GetEncrypt(); - - // Если m_pTrailer поток перекрестных ссылок, то при дозаписи тоже должен быть поток - m_pTrailer->Remove("XRefStm"); - bool bNeedStreamXRef = false; - pStream->WriteChar('\n'); - if (m_pTrailer->Get("Type")) - { - m_pTrailer->Remove("Length"); - m_pTrailer->Remove("Filter"); - m_pTrailer->Remove("DecodeParms"); - m_pTrailer->Remove("F"); - m_pTrailer->Remove("FFilter"); - m_pTrailer->Remove("FDecodeParms"); - m_pTrailer->Remove("DL"); - m_pTrailer->Remove("Type"); - m_pTrailer->Remove("Index"); - m_pTrailer->Remove("W"); - bNeedStreamXRef = true; - - m_pLastXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef); - } - else - m_pLastXref->WriteToStream(pStream, pEncrypt); - - RELEASEOBJECT(pStream); - unsigned int nSizeXRef = m_pXref->GetSizeXRef(); - m_pXref = m_pLastXref; - Sign(m_wsFilePath, nSizeXRef, bNeedStreamXRef); - RELEASEOBJECT(m_pEncryptDict); - - return true; - } - void CDocument::Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCertificate) - { - m_vSignatures.push_back({ oRect, m_pCurPage ? m_pCurPage : m_pPageTree->GetPage(0), pImage, pCertificate }); - } - void CDocument::Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef) - { - unsigned int nPrevAddr = m_pXref->GetPrevAddr(); - std::vector vXRefForWrite; - for (unsigned int i = 0; i < m_vSignatures.size(); i++) - { - CXref* pXrefBefore = m_pXref; - m_pXref = new CXref(this, nSizeXRef); - if (!m_pXref) - { - m_pXref = pXrefBefore; - continue; - } - m_pXref->SetPrevAddr(nPrevAddr); - - CSignatureField* pField = CreateSignatureField(); - if (!pField) - { - RELEASEOBJECT(m_pXref); - m_pXref = pXrefBefore; - continue; - } - - m_pAcroForm->Add("SigFlags", 3); - pField->GetSignatureDict()->SetCert(m_vSignatures[i].pCertificate); - pField->GetSignatureDict()->SetDate(); - pField->AddPageRect(m_vSignatures[i].pPage, m_vSignatures[i].oRect); - pField->Add("F", 132); - pField->SetFieldName("Sig" + std::to_string(i + m_unFormFields + 1)); - if (m_vSignatures[i].pImage) - pField->SetAppearance(m_vSignatures[i].pImage); - - CFileStream* pStream = new CFileStream(); - if (!pStream || !pStream->OpenFile(wsPath, false)) - { - RELEASEOBJECT(m_pXref); - m_pXref = pXrefBefore; - continue; - } - - CXref* pXrefCatalog = new CXref(this, m_pCatalog->GetObjId()); - if (pXrefCatalog) - { - pXrefCatalog->Add(m_pCatalog->Copy()); - pXrefCatalog->SetPrev(m_pXref); - } - - CXref* pXrefPage = new CXref(this, m_vSignatures[i].pPage->GetObjId()); - if (pXrefPage) - { - pXrefPage->Add(m_vSignatures[i].pPage->Copy()); - pXrefPage->SetPrev(pXrefCatalog); - } - - CXref* pXref = new CXref(this, 0, 65535); - if (pXref) - { - pXref->SetPrev(pXrefPage); - CDictObject* pTrailer = pXref->GetTrailer(); - m_pTrailer->Copy(pTrailer); - - CEncrypt* pEncrypt = NULL; - if (m_bEncrypt && m_pEncryptDict) - pEncrypt = m_pEncryptDict->GetEncrypt(); - - pXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef); - nPrevAddr = pXref->GetPrevAddr(); - nSizeXRef = m_pXref->GetSizeXRef(); - vXRefForWrite.push_back(pXref); - } - - RELEASEOBJECT(pStream); - pStream = new CFileStream(); - if (pStream && pStream->OpenFile(wsPath, false)) - pField->GetSignatureDict()->WriteToStream(pStream, pStream->Size()); - - m_pXref = pXrefBefore; - RELEASEOBJECT(pStream); - } - for (CXref* XRef : vXRefForWrite) - RELEASEOBJECT(XRef); - vXRefForWrite.clear(); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Document.h" +#include "Info.h" +#include "Catalog.h" +#include "Streams.h" +#include "EncryptDictionary.h" +#include "Encrypt.h" +#include "Pages.h" +#include "Outline.h" +#include "Destination.h" +#include "GState.h" +#include "Annotation.h" +#include "Image.h" +#include "Font14.h" +#include "FontCidTT.h" +#include "FontTT.h" +#include "Shading.h" +#include "Pattern.h" +#include "AcroForm.h" +#include "Field.h" +#include "ResourcesDictionary.h" + +#include "../../DesktopEditor/agg-2.4/include/agg_span_hatch.h" +#include "../../DesktopEditor/common/SystemUtils.h" + +#ifdef CreateFont +#undef CreateFont +#endif + +#ifndef VALUE2STR +#define VALUE_TO_STRING(x) #x +#define VALUE2STR(x) VALUE_TO_STRING(x) +#endif + +namespace PdfWriter +{ + const char* c_sPdfHeader = "%PDF-1.7\015%\315\312\322\251\015"; + const char* c_sPdfAHeader = "%PDF-1.4\015%\315\312\322\251\015"; + //---------------------------------------------------------------------------------------- + // CDocument + //---------------------------------------------------------------------------------------- + CDocument::CDocument() + { + m_pCatalog = NULL; + m_pOutlines = NULL; + m_pXref = NULL; + m_pLastXref = NULL; + m_pPageTree = NULL; + m_pCurPage = NULL; + m_nCurPageNum = -1; + m_unFormFields = 0; + m_pInfo = NULL; + m_pTrailer = NULL; + m_pResources = NULL; + m_bEncrypt = false; + m_pEncryptDict = NULL; + m_unCompressMode = COMP_NONE; + m_pJbig2 = NULL; + memset((void*)m_sTTFontTag, 0x00, 8); + m_pTransparencyGroup = NULL; + m_pFreeTypeLibrary = NULL; + m_pAcroForm = NULL; + m_pFieldsResources = NULL; + m_pDefaultCheckBoxFont = NULL; + m_wsDocumentID = L""; + m_wsFilePath = L""; + + m_bPDFAConformance = false; + } + CDocument::~CDocument() + { + Close(); + } + bool CDocument::CreateNew() + { + Close(); + + m_pXref = new CXref(this, 0); + if (!m_pXref) + return false; + + m_pTrailer = m_pXref->GetTrailer(); + if (!m_pTrailer) + return false; + + m_pCatalog = new CCatalog(m_pXref); + if (!m_pCatalog) + return false; + + m_pCatalog->SetPageMode(pagemode_UseNone); + m_pCatalog->SetPageLayout(pagelayout_OneColumn); + + m_pPageTree = m_pCatalog->GetRoot(); + if (!m_pPageTree) + return false; + + m_pInfo = new CInfoDict(m_pXref); + if (!m_pInfo) + return false; + + m_pInfo->SetTime(InfoCreationDate); + m_pInfo->SetTime(InfoModaDate); + + std::wstring sCreator = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (sCreator.empty()) + sCreator = NSSystemUtils::gc_EnvApplicationNameDefault; + std::string sCreatorA = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sCreator); + +#if defined(INTVER) + std::string sVersion = VALUE2STR(INTVER); + sCreatorA += ("/" + sVersion); +#endif + + m_pInfo->SetInfo(InfoProducer, sCreatorA.c_str()); + m_pInfo->SetInfo(InfoCreator, sCreatorA.c_str()); + + CMetadata* pMetadata = m_pCatalog->AddMetadata(m_pXref, m_pInfo); + if (IsPDFA()) + { + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + + pID->Add(new CBinaryObject(arrId, 16)); + pID->Add(new CBinaryObject(arrId, 16)); + } + } + + m_nCurPageNum = -1; + + m_vExtGrStates.clear(); + m_vFillAlpha.clear(); + m_vStrokeAlpha.clear(); + m_vRadioGroups.clear(); + + m_pTransparencyGroup = NULL; + + return true; + } + void CDocument::Close() + { + // Все объекты удаляются внутри CXref + RELEASEOBJECT(m_pXref); + + m_pLastXref = NULL; + m_pTrailer = NULL; + m_pResources = NULL; + m_pCatalog = NULL; + m_pOutlines = NULL; + m_pPageTree = NULL; + m_pCurPage = NULL; + m_nCurPageNum = 0; + m_unFormFields = 0; + m_bEncrypt = false; + m_pEncryptDict = NULL; + m_pInfo = NULL; + m_unCompressMode = COMP_NONE; + m_pJbig2 = NULL; + m_pTransparencyGroup= NULL; + m_pAcroForm = NULL; + m_pFieldsResources = NULL; + memset((void*)m_sTTFontTag, 0x00, 8); + m_pDefaultCheckBoxFont = NULL; + m_wsDocumentID = L""; + m_wsFilePath = L""; + + m_vExtGrStates.clear(); + m_vStrokeAlpha.clear(); + m_vFillAlpha.clear(); + m_vShadings.clear(); + m_vCidTTFonts.clear(); + m_vTTFonts.clear(); + m_vFreeTypeFonts.clear(); + m_vSignatures.clear(); + if (m_pFreeTypeLibrary) + { + FT_Done_FreeType(m_pFreeTypeLibrary); + m_pFreeTypeLibrary = NULL; + } + } + bool CDocument::SaveToFile(const std::wstring& wsPath, bool bAdd) + { + CFileStream* pStream = new CFileStream(); + if (!pStream || !pStream->OpenFile(wsPath, bAdd)) + return false; + + if (m_pJbig2) + m_pJbig2->FlushStreams(); + + SaveToStream((CStream*)pStream); + delete pStream; + + Sign(wsPath, m_pXref->GetSizeXRef()); + + return true; + } + void CDocument::SaveToStream(CStream* pStream) + { + unsigned long nRet = OK; + + // Пишем заголовок + if (IsPDFA()) + pStream->WriteStr(c_sPdfAHeader); + else + pStream->WriteStr(c_sPdfHeader); + + if (false == m_wsDocumentID.empty()) + { + std::string sDocumentID = "%DocumentID " + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(m_wsDocumentID); + pStream->WriteStr(sDocumentID.c_str()); + } + + // Добавляем в Trailer необходимые элементы + m_pTrailer->Add("Root", m_pCatalog); + m_pTrailer->Add("Info", m_pInfo); + + // Шифруем документ, если это необходимо + CEncrypt* pEncrypt = NULL; + if (m_bEncrypt) + { + pEncrypt = m_pEncryptDict->GetEncrypt(); + PrepareEncryption(); + } + + m_pXref->WriteToStream(pStream, pEncrypt); + } + void CDocument::PrepareEncryption() + { + CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt(); + if (!pEncrypt) + return; + + m_pEncryptDict->Prepare(m_pInfo, m_pXref); + + CArrayObject* pID = (CArrayObject*)m_pTrailer->Get("ID"); + if (!pID) + { + pID = new CArrayObject(); + m_pTrailer->Add("ID", pID); + } + else + pID->Clear(); + + pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + pID->Add(new CBinaryObject(pEncrypt->m_anEncryptID, 16)); + } + void CDocument::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) + { + if (IsPDFA()) + return; + + if (!m_pEncryptDict) + m_pEncryptDict = new CEncryptDict(m_pXref); + + if (!m_pEncryptDict) + return; + + m_pEncryptDict->SetPasswords(wsOwnerPassword, wsUserPassword); + + m_pTrailer->Add("Encrypt", m_pEncryptDict); + m_bEncrypt = true; + } + CPage* CDocument::AddPage() + { + CPage* pPage = new CPage(m_pXref, m_pPageTree, this); + m_pPageTree->AddPage(pPage); + m_pCurPage = pPage; + +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_unCompressMode & COMP_TEXT) + pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + + m_nCurPageNum++; + return pPage; + } + CPage* CDocument::GetPage(const unsigned int &unPage) + { + if (unPage >= m_pPageTree->GetCount()) + return NULL; + + return m_pPageTree->GetPage(unPage); + } + unsigned int CDocument::GetPagesCount() const + { + return m_pPageTree->GetCount(); + } + void CDocument::SetDocumentID(const std::wstring& documentID) + { + m_wsDocumentID = documentID; + } + void CDocument::SetTitle(const std::string& sTitle) + { + if (!m_pInfo) + return; + m_pInfo->SetInfo(InfoTitle, sTitle.c_str()); + } + void CDocument::SetAuthor(const std::string& sAuthor) + { + if (!m_pInfo) + return; + m_pInfo->SetInfo(InfoAuthor, sAuthor.c_str()); + } + void CDocument::SetSubject(const std::string& sSubject) + { + if (!m_pInfo) + return; + m_pInfo->SetInfo(InfoSubject, sSubject.c_str()); + } + void CDocument::SetKeywords(const std::string& sKeywords) + { + if (!m_pInfo) + return; + m_pInfo->SetInfo(InfoKeyWords, sKeywords.c_str()); + } + + void CDocument::SetPermission(unsigned int unPermission) + { + if (!m_bEncrypt) + return; + + CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt(); + pEncrypt->SetPermission(unPermission); + } + void CDocument::SetCompressionMode(unsigned int unMode) + { + m_unCompressMode = unMode; + } + unsigned int CDocument::GetCompressionMode() const + { + return m_unCompressMode; + } + void CDocument::SetPDFAConformanceMode(bool isPDFA) + { + m_bPDFAConformance = isPDFA; + } + bool CDocument::IsPDFA() const + { + return m_bPDFAConformance; + } + void CDocument::AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) + { + CDictObject* pPageLabel = CreatePageLabel(eStyle, unFirstPage, sPrefix); + if (!pPageLabel) + return; + + m_pCatalog->AddPageLabel(m_nCurPageNum, pPageLabel); + } + void CDocument::AddPageLabel(unsigned int unPageNum, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) + { + CDictObject* pPageLabel = CreatePageLabel(eStyle, unFirstPage, sPrefix); + if (!pPageLabel) + return; + + m_pCatalog->AddPageLabel(unPageNum, pPageLabel); + } + CDictObject* CDocument::CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix) + { + CDictObject* pLabel = new CDictObject(); + if (!pLabel) + return NULL; + + eStyle = std::min(std::max(eStyle, pagenumstyle_Min), pagenumstyle_Max); + switch (eStyle) + { + case pagenumstyle_UpperRoman: pLabel->Add("S", "R"); break; + case pagenumstyle_LowerRoman: pLabel->Add("S", "r"); break; + case pagenumstyle_UpperLetters: pLabel->Add("S", "A"); break; + case pagenumstyle_LowerLetters: pLabel->Add("S", "a"); break; + case pagenumstyle_Decimal: pLabel->Add("S", "D"); break; + } + + if (sPrefix && 0 != sPrefix[0]) + pLabel->Add("P", new CStringObject(sPrefix)); + + if (0 != unFirstPage) + pLabel->Add("St", unFirstPage); + + return pLabel; + } + COutline* CDocument::CreateOutline(COutline* pParent, const char* sTitle) + { + if (!pParent) + { + if (!m_pOutlines) + { + m_pOutlines = new COutline(m_pXref); + if (m_pOutlines) + m_pCatalog->Add("Outlines", m_pOutlines); + else + return NULL; + } + + pParent = m_pOutlines; + } + + return new COutline(pParent, sTitle, m_pXref); + } + CDestination* CDocument::CreateDestination(unsigned int unPageIndex) + { + if (unPageIndex >= m_pPageTree->GetCount()) + return NULL; + + CPage* pPage = m_pPageTree->GetPage(unPageIndex); + if (pPage) + return new CDestination(pPage, m_pXref); + return NULL; + } + CExtGrState* CDocument::FindExtGrState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) + { + CExtGrState* pExtGrState = NULL; + for (unsigned int unIndex = 0, unCount = m_vExtGrStates.size(); unIndex < unCount; unIndex++) + { + pExtGrState = m_vExtGrStates.at(unIndex); + + if (dAlphaStroke != pExtGrState->GetAlphaStroke()) + continue; + + if (dAlphaFill != pExtGrState->GetAlphaFill()) + continue; + + if (eMode != pExtGrState->GetBlendMode()) + continue; + + if ((0 == nStrokeAdjustment ? false : true) != pExtGrState->GetStrokeAdjustment()) + continue; + + return pExtGrState; + } + + return NULL; + } + CExtGrState* CDocument::GetExtGState(double dAlphaStroke, double dAlphaFill, EBlendMode eMode, int nStrokeAdjustment) + { + if (IsPDFA()) + return NULL; + + CExtGrState* pExtGrState = FindExtGrState(dAlphaStroke, dAlphaFill, eMode, nStrokeAdjustment); + + if (!pExtGrState) + { + pExtGrState = new CExtGrState(m_pXref); + if (!pExtGrState) + return NULL; + + if (-1 != dAlphaStroke) + pExtGrState->SetAlphaStroke(dAlphaStroke); + + if (-1 != dAlphaFill) + pExtGrState->SetAlphaFill(dAlphaFill); + + if (blendmode_Unknown != eMode) + pExtGrState->SetBlendMode(eMode); + + if (-1 != nStrokeAdjustment) + pExtGrState->SetStrokeAdjustment(0 == nStrokeAdjustment ? false : true); + + m_vExtGrStates.push_back(pExtGrState); + } + + return pExtGrState; + } + CExtGrState* CDocument::GetStrokeAlpha(double dAlpha) + { + if (IsPDFA()) + return NULL; + + CExtGrState* pExtGrState = NULL; + for (unsigned int unIndex = 0, unCount = m_vStrokeAlpha.size(); unIndex < unCount; unIndex++) + { + pExtGrState = m_vStrokeAlpha.at(unIndex); + + if (fabs(dAlpha - pExtGrState->GetAlphaStroke()) < 0.001) + return pExtGrState; + } + + pExtGrState = new CExtGrState(m_pXref); + if (!pExtGrState) + return NULL; + + pExtGrState->SetAlphaStroke(dAlpha); + + m_vStrokeAlpha.push_back(pExtGrState); + return pExtGrState; + } + CExtGrState* CDocument::GetFillAlpha(double dAlpha) + { + if (IsPDFA()) + return NULL; + + CExtGrState* pExtGrState = NULL; + for (unsigned int unIndex = 0, unCount = m_vFillAlpha.size(); unIndex < unCount; unIndex++) + { + pExtGrState = m_vFillAlpha.at(unIndex); + + if (fabs(dAlpha - pExtGrState->GetAlphaFill()) < 0.001) + return pExtGrState; + } + + pExtGrState = new CExtGrState(m_pXref); + if (!pExtGrState) + return NULL; + + pExtGrState->SetAlphaFill(dAlpha); + + m_vFillAlpha.push_back(pExtGrState); + return pExtGrState; + } + CAnnotation* CDocument::CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText) + { + CAnnotation* pAnnot = new CTextAnnotation(m_pXref, oRect, sText); + if (pAnnot) + { + CPage* pPage = m_pPageTree->GetPage(unPageNum); + if (pPage) + pPage->AddAnnotation(pAnnot); + } + + return pAnnot; + } + CAnnotation* CDocument::CreateLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, CDestination* pDest) + { + CAnnotation* pAnnot = new CLinkAnnotation(m_pXref, oRect, pDest); + + if (pAnnot) + { + CPage* pPage = m_pPageTree->GetPage(unPageNum); + if (pPage) + pPage->AddAnnotation(pAnnot); + } + + return pAnnot; + } + CAnnotation* CDocument::CreateLinkAnnot(CPage* pPage, const TRect& oRect, CDestination* pDest) + { + CAnnotation* pAnnot = new CLinkAnnotation(m_pXref, oRect, pDest); + + if (pAnnot) + pPage->AddAnnotation(pAnnot); + + return pAnnot; + } + CAnnotation* CDocument::CreateUriLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, const char* sUri) + { + CAnnotation* pAnnot = new CUriLinkAnnotation(m_pXref, oRect, sUri); + + if (pAnnot) + { + CPage* pPage = m_pPageTree->GetPage(unPageNum); + if (pPage) + pPage->AddAnnotation(pAnnot); + } + + return pAnnot; + } + CAnnotation* CDocument::CreateUriLinkAnnot(CPage* pPage, const TRect& oRect, const char* sUrl) + { + CAnnotation* pAnnot = new CUriLinkAnnotation(m_pXref, oRect, sUrl); + + if (pAnnot) + pPage->AddAnnotation(pAnnot); + + return pAnnot; + } + CImageDict* CDocument::CreateImage() + { + return new CImageDict(m_pXref, this); + } + CFont14* CDocument::CreateFont14(EStandard14Fonts eType) + { + return new CFont14(m_pXref, this, eType); + } + CFontCidTrueType* CDocument::CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) + { + CFontCidTrueType* pFont = FindCidTrueTypeFont(wsFontPath, unIndex); + if (pFont) + return pFont; + + pFont = new CFontCidTrueType(m_pXref, this, wsFontPath, unIndex); + if (!pFont) + return NULL; + + // 0 GID всегда используется для .notdef символа, не используем данный код для настоящих символов + unsigned int unUnicode = 0; + pFont->EncodeGID(0, &unUnicode, 1); + + m_vCidTTFonts.push_back(TFontInfo(wsFontPath, unIndex, pFont)); + return pFont; + } + CFontCidTrueType* CDocument::FindCidTrueTypeFont(const std::wstring &wsFontPath, unsigned int unIndex) + { + for (int nIndex = 0, nCount = m_vCidTTFonts.size(); nIndex < nCount; nIndex++) + { + TFontInfo& oInfo = m_vCidTTFonts.at(nIndex); + if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) + return (CFontCidTrueType*)oInfo.pFont; + } + + return NULL; + } + CFontTrueType* CDocument::CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex) + { + for (int nIndex = 0, nCount = m_vTTFonts.size(); nIndex < nCount; nIndex++) + { + TFontInfo& oInfo = m_vTTFonts.at(nIndex); + if (wsFontPath == oInfo.wsPath && unIndex == oInfo.unIndex) + return (CFontTrueType*)oInfo.pFont; + } + + CFontTrueType* pFont = new CFontTrueType(m_pXref, this, wsFontPath, unIndex); + if (!pFont) + return NULL; + + m_vTTFonts.push_back(TFontInfo(wsFontPath, unIndex, pFont)); + return pFont; + } + CFontTrueType* CDocument::CreateTrueTypeFont(CFontCidTrueType* pCidFont) + { + for (int nIndex = 0, nCount = m_vCidTTFonts.size(); nIndex < nCount; nIndex++) + { + TFontInfo& oInfo = m_vCidTTFonts.at(nIndex); + if (pCidFont == (CFontCidTrueType*)oInfo.pFont) + { + return CreateTrueTypeFont(oInfo.wsPath, oInfo.unIndex); + } + } + + return NULL; + } + CFont14* CDocument::GetDefaultCheckboxFont() + { + if (!m_pDefaultCheckBoxFont) + m_pDefaultCheckBoxFont = new CFont14(m_pXref, this, EStandard14Fonts::standard14fonts_ZapfDingbats); + + return m_pDefaultCheckBoxFont; + } + char* CDocument::GetTTFontTag() + { + if (0 == m_sTTFontTag[0]) + { + MemCpy((BYTE*)m_sTTFontTag, (BYTE*)"BAAAAA+", 7); + } + else + { + for (unsigned int nIndex = 0; nIndex <= 5; nIndex++) + { + m_sTTFontTag[nIndex] += 1; + if (m_sTTFontTag[nIndex] > 'Z') + m_sTTFontTag[nIndex] = 'A'; + else + break; + } + } + + return m_sTTFontTag; + } + void CDocument::AddFreeTypeFont(CFontCidTrueType* pFont) + { + for (int nIndex = 0, nCount = m_vFreeTypeFonts.size(); nIndex < nCount; nIndex++) + { + if (pFont == m_vFreeTypeFonts.at(nIndex)) + { + if (nIndex >= 10) + { + m_vFreeTypeFonts.erase(m_vFreeTypeFonts.begin() + nIndex); + m_vFreeTypeFonts.insert(m_vFreeTypeFonts.begin(), pFont); + } + return; + } + } + + m_vFreeTypeFonts.insert(m_vFreeTypeFonts.begin(), pFont); + + int nFontsCount = m_vFreeTypeFonts.size(); + if (nFontsCount > MAX_OPENED_FT_FACES) + { + for (int nFontIndex = MAX_OPENED_FT_FACES; nFontIndex < nFontsCount; nFontIndex++) + { + CFontCidTrueType* pFont = m_vFreeTypeFonts.at(nFontIndex); + pFont->CloseFontFace(); + } + m_vFreeTypeFonts.erase(m_vFreeTypeFonts.begin() + MAX_OPENED_FT_FACES, m_vFreeTypeFonts.end()); + } + } + FT_Library CDocument::GetFreeTypeLibrary() + { + if (!m_pFreeTypeLibrary) + FT_Init_FreeType(&m_pFreeTypeLibrary); + + return m_pFreeTypeLibrary; + } + CJbig2Global* CDocument::GetJbig2Global() + { + if (m_pJbig2 && m_pJbig2->GetImagesCount() > 4) + { + // Удалять не надо, т.к. объект удалится в CXref + m_pJbig2->FlushStreams(); + m_pJbig2 = NULL; + } + + if (!m_pJbig2) + m_pJbig2 = new CJbig2Global(m_pXref); + + return m_pJbig2; + } + CShading* CDocument::CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) + { + pExtGrState = NULL; + + bool bNeedAlpha = false; + unsigned char* pA = new unsigned char[3 * nCount]; + if (!pA) + return NULL; + + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + pA[3 * nIndex + 0] = pAlphas[nIndex]; + pA[3 * nIndex + 1] = pAlphas[nIndex]; + pA[3 * nIndex + 2] = pAlphas[nIndex]; + + if (255 != pAlphas[nIndex]) + bNeedAlpha = true; + } + + if (!bNeedAlpha) + { + delete[] pA; + if (bAxial) + return CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount); + else + return CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount); + } + + // Создаем 2 shading-объекта, один цветной RGB, второй серый со значениями альфа-канала + CShading* pColorShading = NULL; + CShading* pAlphaShading = NULL; + + if (bAxial) + { + pColorShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount); + pAlphaShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pA, pPoints, nCount); + } + else + { + pColorShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount); + pAlphaShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pA, pPoints, nCount); + } + delete[] pA; + + if (!IsPDFA()) + { + if (!m_pTransparencyGroup) + { + m_pTransparencyGroup = new CDictObject(); + m_pTransparencyGroup->Add("Type", "Group"); + m_pTransparencyGroup->Add("S", "Transparency"); + m_pTransparencyGroup->Add("CS", "DeviceRGB"); + } + + pPage->Add("Group", m_pTransparencyGroup); + } + double dWidth = pPage->GetWidth(); + double dHeight = pPage->GetHeight(); + + // Создаем графический объект, который будет альфа-маской + CDictObject* pXObject = new CDictObject(m_pXref); + pXObject->Add("Type", "XObject"); + pXObject->Add("Subtype", "Form"); + pXObject->Add("BBox", CArrayObject::CreateBox(0, 0, dWidth, dHeight)); + if (m_pTransparencyGroup) + pXObject->Add("Group", m_pTransparencyGroup); + CDictObject* pResources = new CDictObject(); + pXObject->Add("Resources", pResources); + CDictObject* pResShadings = new CDictObject(); + pResources->Add("Shading", pResShadings); + pResShadings->Add("S1", pAlphaShading); + CStream* pStream = pXObject->GetStream(); + + pStream->WriteStr("0 0 "); + pStream->WriteReal(dWidth); + pStream->WriteChar(' '); + pStream->WriteReal(dHeight); + pStream->WriteStr(" re\012W\012\n\012/S1 sh\012"); + + // Создаем обект-маску для графического состояние + CDictObject* pMask = new CDictObject(); + m_pXref->Add(pMask); + pMask->Add("Type", "Mask"); + pMask->Add("S", "Luminosity"); + pMask->Add("G", pXObject); + + if (!IsPDFA()) + { + // Создаем ExtGState объект, в который мы запишем альфа-маску + pExtGrState = new CExtGrState(m_pXref); + pExtGrState->Add("BM", "Normal"); + pExtGrState->Add("ca", 1); + pExtGrState->Add("SMask", pMask); + } + + return pColorShading; + } + CShading* CDocument::CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount) + { + for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++) + { + CShading* pShading = m_vShadings.at(nIndex); + if (shadingtype_Axial == pShading->GetShadingType() + && ((CAxialShading*)pShading)->Compare(dX0, dY0, dX1, dY1) + && pShading->CompareColors(pColors, pPoints, nCount, true) + && pShading->CompareExtend(true, true)) + return pShading; + } + + CAxialShading* pShading = new CAxialShading(m_pXref, dX0, dY0, dX1, dY1); + if (!pShading) + return NULL; + + pShading->SetRgbColors(pColors, pPoints, nCount); + pShading->SetExtend(true, true); + + m_vShadings.push_back(pShading); + + return pShading; + } + CShading* CDocument::CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount) + { + for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++) + { + CShading* pShading = m_vShadings.at(nIndex); + if (shadingtype_Radial == pShading->GetShadingType() + && ((CRadialShading*)pShading)->Compare(dX0, dY0, dR0, dX1, dY1, dR1) + && pShading->CompareColors(pColors, pPoints, nCount, true) + && pShading->CompareExtend(true, true)) + return pShading; + } + + CRadialShading* pShading = new CRadialShading(m_pXref, dX0, dY0, dR0, dX1, dY1, dR1); + if (!pShading) + return NULL; + + pShading->SetRgbColors(pColors, pPoints, nCount); + pShading->SetExtend(true, true); + + m_vShadings.push_back(pShading); + + return pShading; + } + CImageTilePattern*CDocument::CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType, double dXStepSpacing, double dYStepSpacing) + { + return new CImageTilePattern(m_pXref, dW, dH, pImageDict, pMatrix, eType, dXStepSpacing, dYStepSpacing); + } + CImageTilePattern*CDocument::CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch) + { + // TODO: Надо бы сделать мап, чтобы не создавать одинаковых паттернов + + CImageDict* pImage = CreateImage(); + BYTE* pBuffer = new BYTE[3 * HATCH_TX_SIZE * HATCH_TX_SIZE]; + if (!pBuffer) + return NULL; + + TColor oColor1(nR1, nG1, nB1); + TColor oColor2(nR2, nG2, nB2); + agg::GetHatchPattern(wsHatch, (TColor*)pBuffer, oColor1, oColor2); + pImage->LoadRaw(pBuffer, 3 * HATCH_TX_SIZE * HATCH_TX_SIZE, HATCH_TX_SIZE, HATCH_TX_SIZE); + delete[] pBuffer; + + if (255 != nAlpha1 || 255 != nAlpha2) + { + BYTE* pSMask = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE]; + if (pSMask) + { + agg::GetHatchPattern(wsHatch, pSMask, nAlpha1, nAlpha2); + pImage->LoadSMask(pSMask, (unsigned int)HATCH_TX_SIZE * HATCH_TX_SIZE, (unsigned int)HATCH_TX_SIZE, (unsigned int)HATCH_TX_SIZE); + delete[] pSMask; + } + } + + return CreateImageTilePattern(dW, dH, pImage, NULL, imagetilepatterntype_Default); + } + CShading* CDocument::CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) + { + double pPattern[] ={ dX0, dY0, dX1, dY1 }; + return CreateShading(pPage, pPattern, true, pColors, pAlphas, pPoints, nCount, pExtGrState); + } + CShading* CDocument::CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState) + { + double pPattern[] ={ dX0, dY0, dR0, dX1, dY1, dR1 }; + return CreateShading(pPage, pPattern, false, pColors, pAlphas, pPoints, nCount, pExtGrState); + } + CResourcesDict* CDocument::GetFieldsResources() + { + if (!m_pFieldsResources) + { + if (!CheckAcroForm()) + return NULL; + + m_pFieldsResources = new CResourcesDict(m_pXref, false, true); + m_pAcroForm->Add("DR", m_pFieldsResources); + } + + return m_pFieldsResources; + } + CTextField* CDocument::CreateTextField() + { + if (!CheckAcroForm()) + return NULL; + + CTextField* pField = new CTextField(m_pXref, this); + if (!pField) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + + return pField; + } + CChoiceField* CDocument::CreateChoiceField() + { + if (!CheckAcroForm()) + return NULL; + + CChoiceField* pField = new CChoiceField(m_pXref, this); + if (!pField) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + + return pField; + } + CSignatureField* CDocument::CreateSignatureField() + { + if (!CheckAcroForm()) + return NULL; + + CSignatureField* pField = new CSignatureField(m_pXref, this); + if (!pField) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + + return pField; + } + CCheckBoxField* CDocument::CreateCheckBoxField() + { + if (!CheckAcroForm()) + return NULL; + + CCheckBoxField* pField = new CCheckBoxField(m_pXref, this); + if (!pField) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + + return pField; + } + CRadioGroupField* CDocument::GetRadioGroupField(const std::wstring& wsGroupName) + { + CRadioGroupField* pField = FindRadioGroupField(wsGroupName); + if (!pField) + { + if (!CheckAcroForm()) + return NULL; + + pField = new CRadioGroupField(m_pXref, this); + if (!pField) + return NULL; + + m_vRadioGroups.push_back(pField); + + pField->SetFieldName(wsGroupName); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + } + + return pField; + } + CRadioGroupField* CDocument::FindRadioGroupField(const std::wstring& wsGroupName) + { + CRadioGroupField* pField = NULL; + for (unsigned int unIndex = 0, unCount = m_vRadioGroups.size(); unIndex < unCount; ++unIndex) + { + pField = m_vRadioGroups.at(unIndex); + + if (pField->GetFieldName() == wsGroupName) + return pField; + } + + return NULL; + } + CPictureField* CDocument::CreatePictureField() + { + if (!CheckAcroForm()) + return NULL; + + CPictureField* pField = new CPictureField(m_pXref, this); + if (!pField) + return NULL; + + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pField); + + return pField; + } + bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) + { + CFieldBase* pBase = m_mFields[sName]; + if (pBase) + { + if (!pBase->GetKidsCount()) + { + CFieldBase* pParent = new CFieldBase(m_pXref, this); + pParent->SetFieldName(sName, true); + pParent->Add("Ff", pBase->GetFieldFlag()); + pParent->Add("FT", pBase->GetFieldType()); + + + pBase->SetParent(pParent); + pBase->ClearKidRecords(); + pParent->AddKid(pBase); + + m_mFields[sName] = pParent; + pField->ClearKidRecords(); + pField->SetParent(pParent); + pParent->AddKid(pField); + + CChoiceField* pChoice = dynamic_cast(pBase); + if (pChoice) + pChoice->UpdateSelectedIndexToParent(); + + CTextField* pTextField = dynamic_cast(pBase); + int nMaxLen = 0; + if (pTextField && 0 != (nMaxLen = pTextField->GetMaxLen())) + { + pBase->Remove("MaxLen"); + pParent->Add("MaxLen", nMaxLen); + } + + pParent->UpdateKidsPlaceHolder(); + } + else + { + pField->ClearKidRecords(); + pField->SetParent(pBase); + pBase->AddKid(pField); + + CChoiceField* pChoice = dynamic_cast(pBase); + if (pChoice) + pChoice->UpdateSelectedIndexToParent(); + + pBase->UpdateKidsPlaceHolder(); + } + + return true; + } + else + { + m_mFields[sName] = pField; + return false; + } + } + bool CDocument::CheckAcroForm() + { + if (!m_pXref || !m_pCatalog) + return false; + + if (!m_pAcroForm) + { + m_pAcroForm = new CDictObject(); + if (!m_pAcroForm) + return false; + + m_pCatalog->Add("AcroForm", m_pAcroForm); + m_pAcroForm->Add("Fields", new CArrayObject()); + } + + return (!!m_pAcroForm); + } + bool CDocument::CreatePageTree(CXref* pXref, CPageTree* pPageTree) + { + if (!pXref || !pPageTree) + return false; + + if (!m_pPageTree) + m_pPageTree = pPageTree; + else + m_pPageTree->Join(pPageTree); + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + + return true; + } + bool CDocument::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) + { + if (!pXref || !pCatalog) + return false; + Close(); + + m_pXref = new CXref(this, nSizeXRef); + if (!m_pXref) + return false; + m_pXref->SetPrevAddr(nPosLastXRef); + m_pLastXref = m_pXref; + + m_pTrailer = m_pXref->GetTrailer(); + if (!m_pTrailer) + return false; + + SetCompressionMode(COMP_ALL); + + m_pCatalog = pCatalog; + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + + CObjectBase* pAcroForm = m_pCatalog->Get("AcroForm"); + if (pAcroForm && pAcroForm->GetType() == object_type_DICT) + m_pAcroForm = (CDictObject*)pAcroForm; + + if (m_pAcroForm) + { + CObjectBase* pFieldsResources = m_pAcroForm->Get("DR"); + if (pFieldsResources && pFieldsResources->GetType() == object_type_DICT) + m_pFieldsResources = (CResourcesDict*)pFieldsResources; + + // TODO заполнить поля m_pFieldsResources + } + + if (pEncrypt) + { + m_pEncryptDict = pEncrypt; + m_bEncrypt = true; + } + + m_unFormFields = nFormField; + m_wsFilePath = wsPath; + return true; + } + std::pair CDocument::GetPageRef(int nPageIndex) + { + std::pair pRes = std::make_pair(0, 0); + if (!m_pPageTree) + return pRes; + + CObjectBase* pObj = m_pPageTree->GetObj(nPageIndex); + if (pObj) + { + pRes.first = pObj->GetObjId(); + pRes.second = pObj->GetGenNo(); + } + + return pRes; + } + bool CDocument::EditPage(CXref* pXref, CPage* pPage) + { + if (!pXref || !pPage) + return false; + + pPage->AddContents(m_pXref); +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_unCompressMode & COMP_TEXT) + pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + m_pCurPage = pPage; + + return true; + } + CPage* CDocument::AddPage(int nPageIndex) + { + if (!m_pPageTree) + return NULL; + + CPage* pNewPage = new CPage(m_pXref, NULL, this); + if (!pNewPage) + return NULL; + bool bRes = m_pPageTree->InsertPage(nPageIndex, pNewPage); + if (!bRes) + return NULL; + +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_unCompressMode & COMP_TEXT) + pNewPage->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + m_pCurPage = pNewPage; + return pNewPage; + } + bool CDocument::DeletePage(int nPageIndex) + { + if (!m_pPageTree) + return false; + + CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); + if (pObj) + { + CXref* pXref = new CXref(this, pObj->GetObjId(), pObj->GetGenNo()); + delete pObj; + if (!pXref) + return false; + + pXref->SetPrev(m_pLastXref); + m_pLastXref = pXref; + return true; + } + return false; + } + bool CDocument::AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) + { + if (!pTrailer || !pInfoXref || !pInfo || m_wsFilePath.empty()) + return false; + + CFileStream* pStream = new CFileStream(); + if (!pStream) + return false; + + if (!pStream->OpenFile(m_wsFilePath, false)) + { + RELEASEOBJECT(pStream); + return false; + } + + m_pTrailer = pTrailer; + m_pInfo = pInfo; + + std::wstring sCreator = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName); + if (sCreator.empty()) + sCreator = NSSystemUtils::gc_EnvApplicationNameDefault; + std::string sCreatorA = U_TO_UTF8(sCreator); + +#if defined(INTVER) + sCreatorA += "/"; + sCreatorA += VALUE2STR(INTVER); +#endif + + const char* cCreator = m_pInfo->GetInfo(InfoProducer); + m_pInfo->SetInfo(InfoCreator, cCreator ? cCreator : sCreatorA.c_str()); + m_pInfo->SetInfo(InfoProducer, sCreatorA.c_str()); + + pInfoXref->SetPrev(m_pLastXref); + pXref->SetPrev(pInfoXref); + m_pLastXref = pXref; + + // Вторая часть идентификатора должна обновляться + CObjectBase* pID = m_pTrailer->Get("ID"); + if (pID && pID->GetType() == object_type_ARRAY) + { + BYTE arrId[16]; + CEncryptDict::CreateId(m_pInfo, m_pXref, (BYTE*)arrId); + + CObjectBase* pObject = ((CArrayObject*)pID)->Get(1, false); + ((CArrayObject*)pID)->Insert(pObject, new CBinaryObject(arrId, 16), true); + } + + CEncrypt* pEncrypt = NULL; + if (m_bEncrypt) + pEncrypt = m_pEncryptDict->GetEncrypt(); + + // Если m_pTrailer поток перекрестных ссылок, то при дозаписи тоже должен быть поток + m_pTrailer->Remove("XRefStm"); + bool bNeedStreamXRef = false; + pStream->WriteChar('\n'); + if (m_pTrailer->Get("Type")) + { + m_pTrailer->Remove("Length"); + m_pTrailer->Remove("Filter"); + m_pTrailer->Remove("DecodeParms"); + m_pTrailer->Remove("F"); + m_pTrailer->Remove("FFilter"); + m_pTrailer->Remove("FDecodeParms"); + m_pTrailer->Remove("DL"); + m_pTrailer->Remove("Type"); + m_pTrailer->Remove("Index"); + m_pTrailer->Remove("W"); + bNeedStreamXRef = true; + + m_pLastXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef); + } + else + m_pLastXref->WriteToStream(pStream, pEncrypt); + + RELEASEOBJECT(pStream); + unsigned int nSizeXRef = m_pXref->GetSizeXRef(); + m_pXref = m_pLastXref; + Sign(m_wsFilePath, nSizeXRef, bNeedStreamXRef); + RELEASEOBJECT(m_pEncryptDict); + + return true; + } + void CDocument::Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCertificate) + { + m_vSignatures.push_back({ oRect, m_pCurPage ? m_pCurPage : m_pPageTree->GetPage(0), pImage, pCertificate }); + } + void CDocument::Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef) + { + unsigned int nPrevAddr = m_pXref->GetPrevAddr(); + std::vector vXRefForWrite; + for (unsigned int i = 0; i < m_vSignatures.size(); i++) + { + CXref* pXrefBefore = m_pXref; + m_pXref = new CXref(this, nSizeXRef); + if (!m_pXref) + { + m_pXref = pXrefBefore; + continue; + } + m_pXref->SetPrevAddr(nPrevAddr); + + CSignatureField* pField = CreateSignatureField(); + if (!pField) + { + RELEASEOBJECT(m_pXref); + m_pXref = pXrefBefore; + continue; + } + + m_pAcroForm->Add("SigFlags", 3); + pField->GetSignatureDict()->SetCert(m_vSignatures[i].pCertificate); + pField->GetSignatureDict()->SetDate(); + pField->AddPageRect(m_vSignatures[i].pPage, m_vSignatures[i].oRect); + pField->Add("F", 132); + pField->SetFieldName("Sig" + std::to_string(i + m_unFormFields + 1)); + if (m_vSignatures[i].pImage) + pField->SetAppearance(m_vSignatures[i].pImage); + + CFileStream* pStream = new CFileStream(); + if (!pStream || !pStream->OpenFile(wsPath, false)) + { + RELEASEOBJECT(m_pXref); + m_pXref = pXrefBefore; + continue; + } + + CXref* pXrefCatalog = new CXref(this, m_pCatalog->GetObjId()); + if (pXrefCatalog) + { + pXrefCatalog->Add(m_pCatalog->Copy()); + pXrefCatalog->SetPrev(m_pXref); + } + + CXref* pXrefPage = new CXref(this, m_vSignatures[i].pPage->GetObjId()); + if (pXrefPage) + { + pXrefPage->Add(m_vSignatures[i].pPage->Copy()); + pXrefPage->SetPrev(pXrefCatalog); + } + + CXref* pXref = new CXref(this, 0, 65535); + if (pXref) + { + pXref->SetPrev(pXrefPage); + CDictObject* pTrailer = pXref->GetTrailer(); + m_pTrailer->Copy(pTrailer); + + CEncrypt* pEncrypt = NULL; + if (m_bEncrypt && m_pEncryptDict) + pEncrypt = m_pEncryptDict->GetEncrypt(); + + pXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef); + nPrevAddr = pXref->GetPrevAddr(); + nSizeXRef = m_pXref->GetSizeXRef(); + vXRefForWrite.push_back(pXref); + } + + RELEASEOBJECT(pStream); + pStream = new CFileStream(); + if (pStream && pStream->OpenFile(wsPath, false)) + pField->GetSignatureDict()->WriteToStream(pStream, pStream->Size()); + + m_pXref = pXrefBefore; + RELEASEOBJECT(pStream); + } + for (CXref* XRef : vXRefForWrite) + RELEASEOBJECT(XRef); + vXRefForWrite.clear(); + } +} diff --git a/PdfWriter/Src/Document.h b/PdfFile/SrcWriter/Document.h similarity index 97% rename from PdfWriter/Src/Document.h rename to PdfFile/SrcWriter/Document.h index bed7475a41..52df3f0245 100644 --- a/PdfWriter/Src/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -1,256 +1,256 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_DOCUMENT_H -#define _PDF_WRITER_SRC_DOCUMENT_H - -#include -#include -#include "Types.h" - -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" - -#include -#include FT_OUTLINE_H -#include FT_SIZES_H -#include FT_GLYPH_H -#include FT_TRUETYPE_IDS_H -#include FT_TRUETYPE_TABLES_H -#include FT_XFREE86_H -#include FT_ADVANCES_H - -#ifdef CreateFont -#undef CreateFont -#endif - -class CFontManager; - -namespace PdfWriter -{ - class CCatalog; - class COutline; - class CXref; - class CPageTree; - class CPage; - class CInfoDict; - class CDictObject; - class CEncryptDict; - class CSignatureDict; - class CStream; - class CDestination; - class CExtGrState; - class CAnnotation; - class CImageDict; - class CFontDict; - class CFont14; - class CFontCidTrueType; - class CFontTrueType; - class CJbig2Global; - class CShading; - class CImageTilePattern; - class CPattern; - class CAcroForm; - class CTextField; - class CResourcesDict; - class CChoiceField; - class CCheckBoxField; - class CRadioGroupField; - class CPictureField; - class CSignatureField; - class CFieldBase; - //---------------------------------------------------------------------------------------- - // CDocument - //---------------------------------------------------------------------------------------- - class CDocument - { - public: - - CDocument(); - ~CDocument(); - - bool CreateNew(); - void Close(); - bool SaveToFile(const std::wstring& wsPath, bool bAdd = true); - - void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); - void SetPermission(unsigned int unPermission); - void SetCompressionMode(unsigned int unMode); - unsigned int GetCompressionMode() const; - void SetDocumentID(const std::wstring & wsDocumentID); - void SetTitle (const std::string& sTitle); - void SetAuthor (const std::string& sAuthor); - void SetSubject (const std::string& sSubject); - void SetKeywords(const std::string& sKeywords); - - void SetPDFAConformanceMode(bool isPDFA); - bool IsPDFA() const; - - CPage* AddPage(); - CPage* GetPage(const unsigned int& unPage); - unsigned int GetPagesCount() const; - void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); - void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); - COutline* CreateOutline(COutline* pParent, const char* sTitle); - CDestination* CreateDestination(unsigned int unPageIndex); - - CExtGrState* GetExtGState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); - CExtGrState* GetStrokeAlpha(double dAlpha); - CExtGrState* GetFillAlpha(double dAlpha); - CJbig2Global* GetJbig2Global(); - - CAnnotation* CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText); - CAnnotation* CreateLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, CDestination* pDest); - CAnnotation* CreateLinkAnnot(CPage* pPage, const TRect& oRect, CDestination* pDest); - CAnnotation* CreateUriLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, const char* sUri); - CAnnotation* CreateUriLinkAnnot(CPage* pPage, const TRect& oRect, const char* sUrl); - - CImageDict* CreateImage(); - CFont14* CreateFont14(EStandard14Fonts eType); - CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); - CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); - CFontTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); - CFontTrueType* CreateTrueTypeFont(CFontCidTrueType* pCidFont); - CFont14* GetDefaultCheckboxFont(); - - CImageTilePattern*CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default, double dXStepSpacing = 0, double dYStepSpacing = 0); - CImageTilePattern*CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch); - CShading* CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); - CShading* CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); - - CResourcesDict* GetFieldsResources(); - CTextField* CreateTextField(); - CChoiceField* CreateChoiceField(); - CCheckBoxField* CreateCheckBoxField(); - CRadioGroupField* GetRadioGroupField(const std::wstring& wsGroupName); - CPictureField* CreatePictureField(); - CSignatureField* CreateSignatureField(); - bool CheckFieldName(CFieldBase* pField, const std::string& sName); - - bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); - bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); - std::pair GetPageRef(int nPageIndex); - bool EditPage(CXref* pXref, CPage* pPage); - CPage* AddPage(int nPageIndex); - bool DeletePage(int nPageIndex); - bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); - void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); - std::wstring GetEditPdfPath() { return m_wsFilePath; } - private: - - char* GetTTFontTag(); - void AddFreeTypeFont(CFontCidTrueType* pFont); - FT_Library GetFreeTypeLibrary(); - CExtGrState* FindExtGrState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); - void SaveToStream(CStream* pStream); - void PrepareEncryption(); - CDictObject* CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); - CShading* CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); - CShading* CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount); - CShading* CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount); - bool CheckAcroForm(); - CRadioGroupField* FindRadioGroupField(const std::wstring& wsGroupName); - void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false); - - private: - - struct TFontInfo - { - TFontInfo(const std::wstring& path, const unsigned int& index, CFontDict* font) - { - wsPath = path; - unIndex = index; - pFont = font; - } - - std::wstring wsPath; - unsigned int unIndex; - CFontDict* pFont; - }; - struct TSignatureInfo - { - TSignatureInfo(const TRect& _oRect, CPage* _pPage, CImageDict* _pImage, ICertificate* _pCertificate) - { - oRect = _oRect; - pPage = _pPage; - pImage = _pImage; - pCertificate = _pCertificate; - } - - TRect oRect; - CPage* pPage; - CImageDict* pImage; - ICertificate* pCertificate; - }; - - CCatalog* m_pCatalog; - COutline* m_pOutlines; - CXref* m_pXref; - CXref* m_pLastXref; - CPageTree* m_pPageTree; - CPage* m_pCurPage; - int m_nCurPageNum; - CInfoDict* m_pInfo; - CDictObject* m_pTrailer; - CDictObject* m_pResources; - bool m_bEncrypt; - CEncryptDict* m_pEncryptDict; - std::vector m_vSignatures; - unsigned int m_unFormFields; - unsigned int m_unCompressMode; - std::vector m_vExtGrStates; - std::vector m_vStrokeAlpha; - std::vector m_vFillAlpha; - char m_sTTFontTag[8]; // 6 символов + '+' + 0x00 ("BAAAAA+/0") - CJbig2Global* m_pJbig2; - std::vector m_vShadings; - std::vector m_vCidTTFonts; - std::vector m_vTTFonts; - CFont14* m_pDefaultCheckBoxFont; - CDictObject* m_pTransparencyGroup; - std::vector m_vFreeTypeFonts; - FT_Library m_pFreeTypeLibrary; - bool m_bPDFAConformance; - std::wstring m_wsDocumentID; - std::wstring m_wsFilePath; - CDictObject* m_pAcroForm; - CResourcesDict* m_pFieldsResources; - std::vector m_vRadioGroups; - std::map m_mFields; - - friend class CFontCidTrueType; - friend class CFontTrueType; - }; -} - -#endif // _PDF_WRITER_SRC_DOCUMENT_H - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_DOCUMENT_H +#define _PDF_WRITER_SRC_DOCUMENT_H + +#include +#include +#include "Types.h" + +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" + +#include +#include FT_OUTLINE_H +#include FT_SIZES_H +#include FT_GLYPH_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TABLES_H +#include FT_XFREE86_H +#include FT_ADVANCES_H + +#ifdef CreateFont +#undef CreateFont +#endif + +class CFontManager; + +namespace PdfWriter +{ + class CCatalog; + class COutline; + class CXref; + class CPageTree; + class CPage; + class CInfoDict; + class CDictObject; + class CEncryptDict; + class CSignatureDict; + class CStream; + class CDestination; + class CExtGrState; + class CAnnotation; + class CImageDict; + class CFontDict; + class CFont14; + class CFontCidTrueType; + class CFontTrueType; + class CJbig2Global; + class CShading; + class CImageTilePattern; + class CPattern; + class CAcroForm; + class CTextField; + class CResourcesDict; + class CChoiceField; + class CCheckBoxField; + class CRadioGroupField; + class CPictureField; + class CSignatureField; + class CFieldBase; + //---------------------------------------------------------------------------------------- + // CDocument + //---------------------------------------------------------------------------------------- + class CDocument + { + public: + + CDocument(); + ~CDocument(); + + bool CreateNew(); + void Close(); + bool SaveToFile(const std::wstring& wsPath, bool bAdd = true); + + void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); + void SetPermission(unsigned int unPermission); + void SetCompressionMode(unsigned int unMode); + unsigned int GetCompressionMode() const; + void SetDocumentID(const std::wstring & wsDocumentID); + void SetTitle (const std::string& sTitle); + void SetAuthor (const std::string& sAuthor); + void SetSubject (const std::string& sSubject); + void SetKeywords(const std::string& sKeywords); + + void SetPDFAConformanceMode(bool isPDFA); + bool IsPDFA() const; + + CPage* AddPage(); + CPage* GetPage(const unsigned int& unPage); + unsigned int GetPagesCount() const; + void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); + void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); + COutline* CreateOutline(COutline* pParent, const char* sTitle); + CDestination* CreateDestination(unsigned int unPageIndex); + + CExtGrState* GetExtGState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); + CExtGrState* GetStrokeAlpha(double dAlpha); + CExtGrState* GetFillAlpha(double dAlpha); + CJbig2Global* GetJbig2Global(); + + CAnnotation* CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText); + CAnnotation* CreateLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, CDestination* pDest); + CAnnotation* CreateLinkAnnot(CPage* pPage, const TRect& oRect, CDestination* pDest); + CAnnotation* CreateUriLinkAnnot(const unsigned int& unPageNum, const TRect& oRect, const char* sUri); + CAnnotation* CreateUriLinkAnnot(CPage* pPage, const TRect& oRect, const char* sUrl); + + CImageDict* CreateImage(); + CFont14* CreateFont14(EStandard14Fonts eType); + CFontCidTrueType* CreateCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); + CFontCidTrueType* FindCidTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); + CFontTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex); + CFontTrueType* CreateTrueTypeFont(CFontCidTrueType* pCidFont); + CFont14* GetDefaultCheckboxFont(); + + CImageTilePattern*CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default, double dXStepSpacing = 0, double dYStepSpacing = 0); + CImageTilePattern*CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch); + CShading* CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); + CShading* CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); + + CResourcesDict* GetFieldsResources(); + CTextField* CreateTextField(); + CChoiceField* CreateChoiceField(); + CCheckBoxField* CreateCheckBoxField(); + CRadioGroupField* GetRadioGroupField(const std::wstring& wsGroupName); + CPictureField* CreatePictureField(); + CSignatureField* CreateSignatureField(); + bool CheckFieldName(CFieldBase* pField, const std::string& sName); + + bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); + bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); + std::pair GetPageRef(int nPageIndex); + bool EditPage(CXref* pXref, CPage* pPage); + CPage* AddPage(int nPageIndex); + bool DeletePage(int nPageIndex); + bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); + void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); + std::wstring GetEditPdfPath() { return m_wsFilePath; } + private: + + char* GetTTFontTag(); + void AddFreeTypeFont(CFontCidTrueType* pFont); + FT_Library GetFreeTypeLibrary(); + CExtGrState* FindExtGrState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); + void SaveToStream(CStream* pStream); + void PrepareEncryption(); + CDictObject* CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); + CShading* CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState); + CShading* CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount); + CShading* CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount); + bool CheckAcroForm(); + CRadioGroupField* FindRadioGroupField(const std::wstring& wsGroupName); + void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false); + + private: + + struct TFontInfo + { + TFontInfo(const std::wstring& path, const unsigned int& index, CFontDict* font) + { + wsPath = path; + unIndex = index; + pFont = font; + } + + std::wstring wsPath; + unsigned int unIndex; + CFontDict* pFont; + }; + struct TSignatureInfo + { + TSignatureInfo(const TRect& _oRect, CPage* _pPage, CImageDict* _pImage, ICertificate* _pCertificate) + { + oRect = _oRect; + pPage = _pPage; + pImage = _pImage; + pCertificate = _pCertificate; + } + + TRect oRect; + CPage* pPage; + CImageDict* pImage; + ICertificate* pCertificate; + }; + + CCatalog* m_pCatalog; + COutline* m_pOutlines; + CXref* m_pXref; + CXref* m_pLastXref; + CPageTree* m_pPageTree; + CPage* m_pCurPage; + int m_nCurPageNum; + CInfoDict* m_pInfo; + CDictObject* m_pTrailer; + CDictObject* m_pResources; + bool m_bEncrypt; + CEncryptDict* m_pEncryptDict; + std::vector m_vSignatures; + unsigned int m_unFormFields; + unsigned int m_unCompressMode; + std::vector m_vExtGrStates; + std::vector m_vStrokeAlpha; + std::vector m_vFillAlpha; + char m_sTTFontTag[8]; // 6 символов + '+' + 0x00 ("BAAAAA+/0") + CJbig2Global* m_pJbig2; + std::vector m_vShadings; + std::vector m_vCidTTFonts; + std::vector m_vTTFonts; + CFont14* m_pDefaultCheckBoxFont; + CDictObject* m_pTransparencyGroup; + std::vector m_vFreeTypeFonts; + FT_Library m_pFreeTypeLibrary; + bool m_bPDFAConformance; + std::wstring m_wsDocumentID; + std::wstring m_wsFilePath; + CDictObject* m_pAcroForm; + CResourcesDict* m_pFieldsResources; + std::vector m_vRadioGroups; + std::map m_mFields; + + friend class CFontCidTrueType; + friend class CFontTrueType; + }; +} + +#endif // _PDF_WRITER_SRC_DOCUMENT_H + diff --git a/PdfWriter/Src/Encodings.h b/PdfFile/SrcWriter/Encodings.h similarity index 100% rename from PdfWriter/Src/Encodings.h rename to PdfFile/SrcWriter/Encodings.h diff --git a/PdfWriter/Src/Encrypt.cpp b/PdfFile/SrcWriter/Encrypt.cpp similarity index 97% rename from PdfWriter/Src/Encrypt.cpp rename to PdfFile/SrcWriter/Encrypt.cpp index 9f2859ef09..ed60ece483 100644 --- a/PdfWriter/Src/Encrypt.cpp +++ b/PdfFile/SrcWriter/Encrypt.cpp @@ -1,657 +1,657 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Encrypt.h" -#include "Objects.h" - -#include "../../Common/3dParty/cryptopp/modes.h" -#include "../../Common/3dParty/cryptopp/aes.h" -#include "../../Common/3dParty/cryptopp/sha.h" -#include "../../Common/3dParty/cryptopp/md5.h" -#include "../../Common/3dParty/cryptopp/arc4.h" -#include "../../Common/3dParty/cryptopp/filters.h" -#include "../../Common/3dParty/cryptopp/osrng.h" - -namespace PdfWriter -{ - static void MD5(unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) - { - CryptoPP::MD5 hash; - - hash.Update( sMessage, nMessageLen); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.BytePtr(), buffer.size()); - return; - } - static int SHA(int type, unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) - { - int res = 0; - switch(type) - { - case 0: - case 256: - { - CryptoPP::SHA256 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.data(), buffer.size()); - }break; - case 1: - case 384: - { - CryptoPP::SHA384 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.data(), buffer.size()); - }break; - case 2: - case 512: - { - CryptoPP::SHA512 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.data(), buffer.size()); - }break; - } - return res; - } - static unsigned char passwordPad[32] = - { - 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, - 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, - 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, - 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a - }; - - class CEncrypt::Impl - { - public: - Impl() : m_nCryptAlgorithm(2), aesEncryption(NULL), rc4Encryption(NULL), streamEncryption(NULL) - { - m_unEncryptionKeyLength = 32; - MemSet(m_anEncryptionKey, 0, m_unEncryptionKeyLength); - } - virtual ~Impl() - { - if (streamEncryption) - delete streamEncryption; - if (aesEncryption) - delete aesEncryption; - if (rc4Encryption) - delete rc4Encryption; - } - void Reset() - { - if (streamEncryption) - delete streamEncryption; - if (aesEncryption) - delete aesEncryption; - if (rc4Encryption) - delete rc4Encryption; - - CryptoPP::RandomPool prng; - CryptoPP::SecByteBlock iv(16); - CryptoPP::OS_GenerateRandomBlock(false, iv, iv.size()); - prng.IncorporateEntropy(iv, iv.size()); - - memcpy(streamInitialization, iv, iv.size()); - - if (m_nCryptAlgorithm != 2) // cryptAES256 - { - memcpy(m_anObjectKey, m_anEncryptionKey, m_unEncryptionKeyLength); - - m_anObjectKey[m_unEncryptionKeyLength + 0] = m_nObjNum & 0xff; - m_anObjectKey[m_unEncryptionKeyLength + 1] = (m_nObjNum >> 8) & 0xff; - m_anObjectKey[m_unEncryptionKeyLength + 2] = (m_nObjNum >> 16) & 0xff; - m_anObjectKey[m_unEncryptionKeyLength + 3] = m_nObjGen & 0xff; - m_anObjectKey[m_unEncryptionKeyLength + 4] = (m_nObjGen >> 8) & 0xff; - - int nLen = 0; - if (m_nCryptAlgorithm == 1) // cryptAES - { - m_anObjectKey[m_unEncryptionKeyLength + 5] = 0x73; // 's' - m_anObjectKey[m_unEncryptionKeyLength + 6] = 0x41; // 'A' - m_anObjectKey[m_unEncryptionKeyLength + 7] = 0x6c; // 'l' - m_anObjectKey[m_unEncryptionKeyLength + 8] = 0x54; // 'T' - - nLen = m_unEncryptionKeyLength + 9; - } - else if (m_nCryptAlgorithm == 0) // cryptRC4 - nLen = m_unEncryptionKeyLength + 5; - MD5(m_anObjectKey, nLen, m_anObjectKey); - - if ((m_unObjectKeyLength = m_unEncryptionKeyLength + 5) > 16) - m_unObjectKeyLength = 16; - - if (m_nCryptAlgorithm == 0) // cryptRC4 - { - rc4Encryption = new CryptoPP::ARC4::Encryption(); - rc4Encryption->SetKey(m_anObjectKey, m_unObjectKeyLength); - } - else if (m_nCryptAlgorithm == 1) // cryptAES - { - aesEncryption = new CryptoPP::AES::Encryption(m_anObjectKey, m_unObjectKeyLength); - streamEncryption = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization); - } - - return; - } - - aesEncryption = new CryptoPP::AES::Encryption(m_anEncryptionKey, m_unEncryptionKeyLength); - streamEncryption = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization); - } - - std::string m_sOwnerPassword; - std::string m_sUserPassword; - BYTE m_anEncryptionKey[32]; - unsigned int m_unEncryptionKeyLength; - BYTE m_anObjectKey[32]; - unsigned int m_unObjectKeyLength; - int m_nCryptAlgorithm; - int m_nObjNum; - int m_nObjGen; - - unsigned char streamInitialization[16]; - CryptoPP::AES::Encryption *aesEncryption; - CryptoPP::ARC4::Encryption *rc4Encryption; - CryptoPP::StreamTransformation *streamEncryption; - }; - CEncrypt::CEncrypt() : m_unKeyLen(32), m_unVersion(5), m_unRevision(6) - { - impl = new Impl(); - - m_unPermission = ENABLE_PRINT | ENABLE_EDIT_ALL | ENABLE_COPY | ENABLE_EDIT | PERMISSION_PAD; - - MemSet(m_anEncryptID, 0, ID_LEN); - } - CEncrypt::~CEncrypt() - { - delete impl; - } - void CEncrypt::SetPasswords(const std::string &sUserPassword, const std::string &sOwnerPassword) - { - impl->m_sUserPassword = sUserPassword; - impl->m_sOwnerPassword = sOwnerPassword; - } - bool CEncrypt::MakeFileKey(int nCryptAlgorithm) - { - impl->m_nCryptAlgorithm = nCryptAlgorithm; - if (m_unRevision == 5 || m_unRevision == 6) - { - CryptoPP::SHA256 hash; - - hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); - hash.Update( m_anOwnerKey + 32, 8); - hash.Update( m_anUserKey, 48); - - CryptoPP::SecByteBlock pHashData(hash.DigestSize()); - hash.Final(pHashData); - - bool bValidate = true; - if (m_unRevision == 6) - bValidate = MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48); - - if (bValidate && 0 == memcmp(pHashData.data(), m_anOwnerKey, 32)) - { - hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); - hash.Update( m_anOwnerKey + 40, 8); - hash.Update( m_anUserKey, 48); - - CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); - hash.Final(pHashKeyData); - - if (m_unRevision == 6) - bValidate = MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48); - unsigned char empty[16] = {}; - - CryptoPP::AES::Decryption aesDecryption(pHashKeyData.data(), pHashKeyData.size()); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty); - - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( impl->m_anEncryptionKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfDecryptor.Put2(m_anOwnerEncryptKey, 32, 1, true); - stfDecryptor.MessageEnd(); - return true; - } - else - { - hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); - hash.Update( m_anUserKey + 32, 8); - - CryptoPP::SecByteBlock pHashData(hash.DigestSize()); - hash.Final(pHashData); - - if (m_unRevision == 6) - bValidate = MakeFileKey3(impl->m_sUserPassword, pHashData.data(), pHashData.size()); - - if (bValidate && 0 == memcmp(pHashData.data(), m_anUserKey, 32)) - { - hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); - hash.Update( m_anUserKey + 40, 8); - - CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); - hash.Final(pHashKeyData); - - if (m_unRevision == 6) - bValidate = MakeFileKey3(impl->m_sUserPassword, pHashKeyData.data(), pHashKeyData.size()); - unsigned char empty[16] = {}; - - CryptoPP::AES::Decryption aesDecryption(pHashKeyData.data(), pHashKeyData.size()); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty); - - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( impl->m_anEncryptionKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfDecryptor.Put2(m_anUserEncryptKey, 32, 1, true); - stfDecryptor.MessageEnd(); - return true; - } - } - } - else if (impl->m_sOwnerPassword.empty()) - return MakeFileKey2(impl->m_sUserPassword); - else - { - int nLen = impl->m_sOwnerPassword.length(); - unsigned char arrOwnerPass[32]; - if (nLen < 32) - { - memcpy(arrOwnerPass, impl->m_sOwnerPassword.c_str(), nLen); - memcpy(arrOwnerPass + nLen, passwordPad, 32 - nLen); - } - else - memcpy(arrOwnerPass, impl->m_sOwnerPassword.c_str(), 32); - MD5(arrOwnerPass, 32, arrOwnerPass); - - if (m_unRevision >= 3) - for (int nIndex = 0; nIndex < 50; ++nIndex) - MD5(arrOwnerPass, 16, arrOwnerPass); - - unsigned char arrOwnerKey[32]; - if (m_unRevision == 2) - { - CryptoPP::ARC4::Decryption rc4Decryption; - rc4Decryption.SetKey(arrOwnerPass, impl->m_unEncryptionKeyLength); - - rc4Decryption.ProcessData(arrOwnerKey, m_anOwnerKey, 32); - } - else - { - memcpy(arrOwnerKey, m_anOwnerKey, 32); - for (int nIndex = 19; nIndex >= 0; --nIndex) - { - unsigned char arrTempKey[16]; - for (unsigned int nJ = 0; nJ < impl->m_unEncryptionKeyLength; ++nJ) - arrTempKey[nJ] = arrOwnerPass[nJ] ^ nIndex; - CryptoPP::ARC4::Decryption rc4Decryption; - - rc4Decryption.SetKey(arrTempKey, impl->m_unEncryptionKeyLength); - rc4Decryption.ProcessData(arrOwnerKey, arrOwnerKey, 32); - } - } - std::string sUserPassword2((char *)arrOwnerKey, 32); - - return MakeFileKey2(sUserPassword2); - } - return false; - } - bool CEncrypt::MakeFileKey3(const std::string &sPassword, unsigned char *pHash, int nHashSize, unsigned char *pHash2, int nHashSize2) - { - if (!pHash) return false; - - int size = 64 * (sPassword.length() + 64 + nHashSize2); // max - - unsigned char K[64]; //max size sha - unsigned char *K1 = new unsigned char[size]; - unsigned char *E = new unsigned char[size]; - - int hash_size = nHashSize; - memcpy(K, pHash, nHashSize); - - int iteration = 0; - - while( (iteration < 64) || (iteration < E[size - 1] + 32)) - { - size = 0; - for (int i = 0; i < 64; i++) - { - memcpy(K1 + size, sPassword.c_str(), sPassword.length()); size += sPassword.length(); - memcpy(K1 + size, K, hash_size); size += hash_size; - if (pHash2) - { - memcpy(K1 + size, pHash2, nHashSize2); size += nHashSize2; - } - } - - CryptoPP::AES::Encryption aesEncryption(K, 16); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, K + 16); - - CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( E, size), CryptoPP::StreamTransformationFilter::NO_PADDING); - - stfEncryption.Put( K1, size); - stfEncryption.MessageEnd(); -//---------------------------------------------------------- - int E_mod_3 = 0; - for (unsigned int i = 0; i < 16; ++i) - { - E_mod_3 += E[i]; - } - E_mod_3 %= 3; - - hash_size = SHA(E_mod_3, E, size, K); - - iteration++; - } - - delete []K1; - delete []E; - - memcpy (pHash, K, 32); // pHash - from sha256 - return true; - } - bool CEncrypt::MakeFileKey2(const std::string &sUserPassword) - { - unsigned char sTest[32]; - unsigned char sTempKey[16]; - int nLen = 0; - bool bResult = true; - - unsigned char* pBuffer = new unsigned char[72 + 16]; - - if (false == sUserPassword.empty()) - { - nLen = sUserPassword.length(); - if (nLen < 32) - { - memcpy(pBuffer, sUserPassword.c_str(), nLen); - memcpy(pBuffer + nLen, passwordPad, 32 - nLen); - } - else - memcpy(pBuffer, sUserPassword.c_str(), 32); - } - else - memcpy(pBuffer, passwordPad, 32); - - memcpy(pBuffer + 32, m_anOwnerKey, 32); - - pBuffer[64] = m_unPermission & 0xff; - pBuffer[65] = (m_unPermission >> 8) & 0xff; - pBuffer[66] = (m_unPermission >> 16) & 0xff; - pBuffer[67] = (m_unPermission >> 24) & 0xff; - - memcpy(pBuffer + 68, m_anEncryptID, 16); - nLen = 68 + 16; - if (!true) - { - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - } - MD5(pBuffer, nLen, impl->m_anEncryptionKey); - if (m_unRevision >= 3) - for (int nIndex = 0; nIndex < 50; ++nIndex) - MD5(impl->m_anEncryptionKey, impl->m_unEncryptionKeyLength, impl->m_anEncryptionKey); - - if (m_unRevision == 2) - { - CryptoPP::ARC4::Decryption rc4Decryption; - rc4Decryption.SetKey(impl->m_anEncryptionKey, impl->m_unEncryptionKeyLength); - - rc4Decryption.ProcessData(sTest, m_anUserKey, 32); - - bResult = (memcmp(sTest, passwordPad, 32) == 0); - } - else if (m_unRevision >= 3) - { - memcpy(sTest, m_anUserKey, 32); - for (int nIndex = 19; nIndex >= 0; --nIndex) - { - for (unsigned int nJ = 0; nJ < impl->m_unEncryptionKeyLength; ++nJ) - sTempKey[nJ] = impl->m_anEncryptionKey[nJ] ^ nIndex; - CryptoPP::ARC4::Decryption rc4Decryption; - - rc4Decryption.SetKey(sTempKey, impl->m_unEncryptionKeyLength); - rc4Decryption.ProcessData(sTest, sTest, 32); - } - memcpy(pBuffer, passwordPad, 32); - memcpy(pBuffer + 32, m_anEncryptID, 16); - - MD5(pBuffer, 32 + 16, pBuffer); - - bResult = (memcmp(sTest, pBuffer, 16) == 0); - } - else - bResult = false; - - delete[] pBuffer; - return bResult; - } - - void CEncrypt::CreateUserKey() - { - CryptoPP::RandomPool prng; - - CryptoPP::SecByteBlock salt(16); - CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size()); - prng.IncorporateEntropy(salt, salt.size()); - - memcpy(m_anUserKey + 32, salt.data(), salt.size()); - - CryptoPP::SHA256 hash; - - hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); - hash.Update( m_anUserKey + 32, 8); - - CryptoPP::SecByteBlock pHashData(hash.DigestSize()); - hash.Final(pHashData); - - if (MakeFileKey3(impl->m_sUserPassword, pHashData.data(), pHashData.size())) - { - memcpy(m_anUserKey, pHashData.data(), pHashData.size()); - - hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); - hash.Update( m_anUserKey + 40, 8); - - CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); - hash.Final(pHashKeyData); - - MakeFileKey3(impl->m_sUserPassword, pHashKeyData.data(), pHashKeyData.size()); - unsigned char empty[16] = {}; - - CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size()); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty); - - CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anUserEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true); - stfEncryption.MessageEnd(); - } - } - void CEncrypt::CreateOwnerKey() - { - CryptoPP::RandomPool prng; - - CryptoPP::SecByteBlock salt(16); - CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size()); - prng.IncorporateEntropy(salt, salt.size()); - - memcpy(m_anOwnerKey + 32, salt.data(), salt.size()); - - CryptoPP::SHA256 hash; - - hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); - hash.Update( m_anOwnerKey + 32, 8); - hash.Update( m_anUserKey, 48); - - CryptoPP::SecByteBlock pHashData(hash.DigestSize()); - hash.Final(pHashData); - - if (MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48)) - { - memcpy(m_anOwnerKey, pHashData.data(), pHashData.size()); - - hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); - hash.Update( m_anOwnerKey + 40, 8); - hash.Update( m_anUserKey, 48); - - CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); - hash.Final(pHashKeyData); - - MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48); - unsigned char empty[16] = {}; - - CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size()); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty); - - CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anOwnerEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true); - stfEncryption.MessageEnd(); - } - } - void CEncrypt::CreateEncryptionKey() - { - CryptoPP::RandomPool prng; - - CryptoPP::SecByteBlock key(32); - CryptoPP::OS_GenerateRandomBlock(false, key, key.size()); - prng.IncorporateEntropy(key, key.size()); - - memcpy(impl->m_anEncryptionKey, key.data(), key.size()); -//------------------------------------------------------------------- - - unsigned long long extended_perms = 0xffffffff00000000LL | m_unPermission; - for (int i = 0; i < 8; ++i) - { - m_anPermEncrypt[i] = static_cast(extended_perms & 0xff); - extended_perms >>= 8; - } - m_anPermEncrypt[8] = /*m_bEncryptMetadata ? 'T' : */'F'; - m_anPermEncrypt[9] = 'a'; - m_anPermEncrypt[10] = 'd'; - m_anPermEncrypt[11] = 'b'; - - CryptoPP::SecByteBlock p(4); - CryptoPP::OS_GenerateRandomBlock(false, p, p.size()); - prng.IncorporateEntropy(p, p.size()); - - memcpy(m_anPermEncrypt + 12, p.data(), p.size()); - - unsigned char empty[16] = {}; - - CryptoPP::AES::Encryption aesEncryption(impl->m_anEncryptionKey, 32); - - CryptoPP::CipherModeFinalTemplate_ExternalCipher ecbEncryption(aesEncryption, empty ); - - CryptoPP::StreamTransformationFilter stfEncryption(ecbEncryption, new CryptoPP::ArraySink( m_anPermEncrypt, 16), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfEncryption.Put2(m_anPermEncrypt, 16, 1, true); - stfEncryption.MessageEnd(); - } - void CEncrypt::InitKey(unsigned int unObjectId, unsigned short unGenNo) - { - impl->m_nObjNum = unObjectId; - impl->m_nObjGen = unGenNo; - } - void CEncrypt::Reset() - { - impl->Reset(); - } - #define PADDING_SIZE 16 - unsigned int CEncrypt::CryptBuf(const BYTE* pSrc, BYTE* pDst, unsigned int unLen) - { - if (impl->m_nCryptAlgorithm == 0) // cryptRC4 - { - impl->rc4Encryption->ProcessData(pDst, pSrc, unLen); - // the algorithm does not change the length of the data - return unLen; - } - // cryptAES & cryptAES256 - - // Note that the pad is present when M is evenly divisible by 16 - unsigned int unLenOut = (unLen / PADDING_SIZE + 1) * PADDING_SIZE; - - memcpy(pDst, impl->streamInitialization, 16); - - CryptoPP::StreamTransformationFilter stfEncryption(*impl->streamEncryption, new CryptoPP::ArraySink( pDst + 16, unLenOut), CryptoPP::StreamTransformationFilter::NO_PADDING ); - - stfEncryption.Put2(pSrc, unLen, 0, true); - - if (unLenOut != unLen) - { - unsigned char empty[16] = {}; - // EXAMPLE A 9-byte message has a pad of 7 bytes, each with the value 0x07. - memset(empty, unLenOut - unLen, 16); - stfEncryption.Put2(empty, unLenOut - unLen, 0, true); - - } - stfEncryption.MessageEnd(); - - return unLenOut + 16; - } - //unsigned int CEncrypt::CryptBuf(const BYTE* pSrc, BYTE* pDst, unsigned int unLen, bool bFirst, bool bLast) - // { - // unsigned int unLenOut = unLen; - - // if (unLenOut % PADDING_SIZE != 0 && bLast) - // unLenOut = (unLen / PADDING_SIZE + 1) * PADDING_SIZE; - - // if(bFirst) - // memcpy(pDst, impl->streamInitialization, 16); - - // CryptoPP::StreamTransformationFilter stfEncryption(*impl->streamEncryption, new CryptoPP::ArraySink( pDst + (bFirst ? 16 : 0), unLenOut), CryptoPP::StreamTransformationFilter::NO_PADDING ); - - // stfEncryption.Put2(pSrc, unLen, 0, true); - // - //if (unLenOut != unLen && bLast) - // { - // unsigned char empty[16] = {}; - // stfEncryption.Put2(empty, unLenOut - unLen, 0, true); - - // } - // if (bLast) - // { - // stfEncryption.MessageEnd(); - // } - // return unLenOut + (bFirst ? 16 : 0); - // } - void CEncrypt::SetKeyLength(unsigned int unLen) - { - impl->m_unEncryptionKeyLength = unLen / 8; - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Encrypt.h" +#include "Objects.h" + +#include "../../Common/3dParty/cryptopp/modes.h" +#include "../../Common/3dParty/cryptopp/aes.h" +#include "../../Common/3dParty/cryptopp/sha.h" +#include "../../Common/3dParty/cryptopp/md5.h" +#include "../../Common/3dParty/cryptopp/arc4.h" +#include "../../Common/3dParty/cryptopp/filters.h" +#include "../../Common/3dParty/cryptopp/osrng.h" + +namespace PdfWriter +{ + static void MD5(unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) + { + CryptoPP::MD5 hash; + + hash.Update( sMessage, nMessageLen); + + CryptoPP::SecByteBlock buffer(hash.DigestSize()); + hash.Final(buffer); + + memcpy(sDigest, buffer.BytePtr(), buffer.size()); + return; + } + static int SHA(int type, unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) + { + int res = 0; + switch(type) + { + case 0: + case 256: + { + CryptoPP::SHA256 hash; + hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); + + CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); + hash.Final(buffer); + + memcpy(sDigest, buffer.data(), buffer.size()); + }break; + case 1: + case 384: + { + CryptoPP::SHA384 hash; + hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); + + CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); + hash.Final(buffer); + + memcpy(sDigest, buffer.data(), buffer.size()); + }break; + case 2: + case 512: + { + CryptoPP::SHA512 hash; + hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); + + CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); + hash.Final(buffer); + + memcpy(sDigest, buffer.data(), buffer.size()); + }break; + } + return res; + } + static unsigned char passwordPad[32] = + { + 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, + 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, + 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, + 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a + }; + + class CEncrypt::Impl + { + public: + Impl() : m_nCryptAlgorithm(2), aesEncryption(NULL), rc4Encryption(NULL), streamEncryption(NULL) + { + m_unEncryptionKeyLength = 32; + MemSet(m_anEncryptionKey, 0, m_unEncryptionKeyLength); + } + virtual ~Impl() + { + if (streamEncryption) + delete streamEncryption; + if (aesEncryption) + delete aesEncryption; + if (rc4Encryption) + delete rc4Encryption; + } + void Reset() + { + if (streamEncryption) + delete streamEncryption; + if (aesEncryption) + delete aesEncryption; + if (rc4Encryption) + delete rc4Encryption; + + CryptoPP::RandomPool prng; + CryptoPP::SecByteBlock iv(16); + CryptoPP::OS_GenerateRandomBlock(false, iv, iv.size()); + prng.IncorporateEntropy(iv, iv.size()); + + memcpy(streamInitialization, iv, iv.size()); + + if (m_nCryptAlgorithm != 2) // cryptAES256 + { + memcpy(m_anObjectKey, m_anEncryptionKey, m_unEncryptionKeyLength); + + m_anObjectKey[m_unEncryptionKeyLength + 0] = m_nObjNum & 0xff; + m_anObjectKey[m_unEncryptionKeyLength + 1] = (m_nObjNum >> 8) & 0xff; + m_anObjectKey[m_unEncryptionKeyLength + 2] = (m_nObjNum >> 16) & 0xff; + m_anObjectKey[m_unEncryptionKeyLength + 3] = m_nObjGen & 0xff; + m_anObjectKey[m_unEncryptionKeyLength + 4] = (m_nObjGen >> 8) & 0xff; + + int nLen = 0; + if (m_nCryptAlgorithm == 1) // cryptAES + { + m_anObjectKey[m_unEncryptionKeyLength + 5] = 0x73; // 's' + m_anObjectKey[m_unEncryptionKeyLength + 6] = 0x41; // 'A' + m_anObjectKey[m_unEncryptionKeyLength + 7] = 0x6c; // 'l' + m_anObjectKey[m_unEncryptionKeyLength + 8] = 0x54; // 'T' + + nLen = m_unEncryptionKeyLength + 9; + } + else if (m_nCryptAlgorithm == 0) // cryptRC4 + nLen = m_unEncryptionKeyLength + 5; + MD5(m_anObjectKey, nLen, m_anObjectKey); + + if ((m_unObjectKeyLength = m_unEncryptionKeyLength + 5) > 16) + m_unObjectKeyLength = 16; + + if (m_nCryptAlgorithm == 0) // cryptRC4 + { + rc4Encryption = new CryptoPP::ARC4::Encryption(); + rc4Encryption->SetKey(m_anObjectKey, m_unObjectKeyLength); + } + else if (m_nCryptAlgorithm == 1) // cryptAES + { + aesEncryption = new CryptoPP::AES::Encryption(m_anObjectKey, m_unObjectKeyLength); + streamEncryption = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization); + } + + return; + } + + aesEncryption = new CryptoPP::AES::Encryption(m_anEncryptionKey, m_unEncryptionKeyLength); + streamEncryption = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization); + } + + std::string m_sOwnerPassword; + std::string m_sUserPassword; + BYTE m_anEncryptionKey[32]; + unsigned int m_unEncryptionKeyLength; + BYTE m_anObjectKey[32]; + unsigned int m_unObjectKeyLength; + int m_nCryptAlgorithm; + int m_nObjNum; + int m_nObjGen; + + unsigned char streamInitialization[16]; + CryptoPP::AES::Encryption *aesEncryption; + CryptoPP::ARC4::Encryption *rc4Encryption; + CryptoPP::StreamTransformation *streamEncryption; + }; + CEncrypt::CEncrypt() : m_unKeyLen(32), m_unVersion(5), m_unRevision(6) + { + impl = new Impl(); + + m_unPermission = ENABLE_PRINT | ENABLE_EDIT_ALL | ENABLE_COPY | ENABLE_EDIT | PERMISSION_PAD; + + MemSet(m_anEncryptID, 0, ID_LEN); + } + CEncrypt::~CEncrypt() + { + delete impl; + } + void CEncrypt::SetPasswords(const std::string &sUserPassword, const std::string &sOwnerPassword) + { + impl->m_sUserPassword = sUserPassword; + impl->m_sOwnerPassword = sOwnerPassword; + } + bool CEncrypt::MakeFileKey(int nCryptAlgorithm) + { + impl->m_nCryptAlgorithm = nCryptAlgorithm; + if (m_unRevision == 5 || m_unRevision == 6) + { + CryptoPP::SHA256 hash; + + hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); + hash.Update( m_anOwnerKey + 32, 8); + hash.Update( m_anUserKey, 48); + + CryptoPP::SecByteBlock pHashData(hash.DigestSize()); + hash.Final(pHashData); + + bool bValidate = true; + if (m_unRevision == 6) + bValidate = MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48); + + if (bValidate && 0 == memcmp(pHashData.data(), m_anOwnerKey, 32)) + { + hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); + hash.Update( m_anOwnerKey + 40, 8); + hash.Update( m_anUserKey, 48); + + CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); + hash.Final(pHashKeyData); + + if (m_unRevision == 6) + bValidate = MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48); + unsigned char empty[16] = {}; + + CryptoPP::AES::Decryption aesDecryption(pHashKeyData.data(), pHashKeyData.size()); + CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty); + + CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( impl->m_anEncryptionKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfDecryptor.Put2(m_anOwnerEncryptKey, 32, 1, true); + stfDecryptor.MessageEnd(); + return true; + } + else + { + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 32, 8); + + CryptoPP::SecByteBlock pHashData(hash.DigestSize()); + hash.Final(pHashData); + + if (m_unRevision == 6) + bValidate = MakeFileKey3(impl->m_sUserPassword, pHashData.data(), pHashData.size()); + + if (bValidate && 0 == memcmp(pHashData.data(), m_anUserKey, 32)) + { + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 40, 8); + + CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); + hash.Final(pHashKeyData); + + if (m_unRevision == 6) + bValidate = MakeFileKey3(impl->m_sUserPassword, pHashKeyData.data(), pHashKeyData.size()); + unsigned char empty[16] = {}; + + CryptoPP::AES::Decryption aesDecryption(pHashKeyData.data(), pHashKeyData.size()); + CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty); + + CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( impl->m_anEncryptionKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfDecryptor.Put2(m_anUserEncryptKey, 32, 1, true); + stfDecryptor.MessageEnd(); + return true; + } + } + } + else if (impl->m_sOwnerPassword.empty()) + return MakeFileKey2(impl->m_sUserPassword); + else + { + int nLen = impl->m_sOwnerPassword.length(); + unsigned char arrOwnerPass[32]; + if (nLen < 32) + { + memcpy(arrOwnerPass, impl->m_sOwnerPassword.c_str(), nLen); + memcpy(arrOwnerPass + nLen, passwordPad, 32 - nLen); + } + else + memcpy(arrOwnerPass, impl->m_sOwnerPassword.c_str(), 32); + MD5(arrOwnerPass, 32, arrOwnerPass); + + if (m_unRevision >= 3) + for (int nIndex = 0; nIndex < 50; ++nIndex) + MD5(arrOwnerPass, 16, arrOwnerPass); + + unsigned char arrOwnerKey[32]; + if (m_unRevision == 2) + { + CryptoPP::ARC4::Decryption rc4Decryption; + rc4Decryption.SetKey(arrOwnerPass, impl->m_unEncryptionKeyLength); + + rc4Decryption.ProcessData(arrOwnerKey, m_anOwnerKey, 32); + } + else + { + memcpy(arrOwnerKey, m_anOwnerKey, 32); + for (int nIndex = 19; nIndex >= 0; --nIndex) + { + unsigned char arrTempKey[16]; + for (unsigned int nJ = 0; nJ < impl->m_unEncryptionKeyLength; ++nJ) + arrTempKey[nJ] = arrOwnerPass[nJ] ^ nIndex; + CryptoPP::ARC4::Decryption rc4Decryption; + + rc4Decryption.SetKey(arrTempKey, impl->m_unEncryptionKeyLength); + rc4Decryption.ProcessData(arrOwnerKey, arrOwnerKey, 32); + } + } + std::string sUserPassword2((char *)arrOwnerKey, 32); + + return MakeFileKey2(sUserPassword2); + } + return false; + } + bool CEncrypt::MakeFileKey3(const std::string &sPassword, unsigned char *pHash, int nHashSize, unsigned char *pHash2, int nHashSize2) + { + if (!pHash) return false; + + int size = 64 * (sPassword.length() + 64 + nHashSize2); // max + + unsigned char K[64]; //max size sha + unsigned char *K1 = new unsigned char[size]; + unsigned char *E = new unsigned char[size]; + + int hash_size = nHashSize; + memcpy(K, pHash, nHashSize); + + int iteration = 0; + + while( (iteration < 64) || (iteration < E[size - 1] + 32)) + { + size = 0; + for (int i = 0; i < 64; i++) + { + memcpy(K1 + size, sPassword.c_str(), sPassword.length()); size += sPassword.length(); + memcpy(K1 + size, K, hash_size); size += hash_size; + if (pHash2) + { + memcpy(K1 + size, pHash2, nHashSize2); size += nHashSize2; + } + } + + CryptoPP::AES::Encryption aesEncryption(K, 16); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, K + 16); + + CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( E, size), CryptoPP::StreamTransformationFilter::NO_PADDING); + + stfEncryption.Put( K1, size); + stfEncryption.MessageEnd(); +//---------------------------------------------------------- + int E_mod_3 = 0; + for (unsigned int i = 0; i < 16; ++i) + { + E_mod_3 += E[i]; + } + E_mod_3 %= 3; + + hash_size = SHA(E_mod_3, E, size, K); + + iteration++; + } + + delete []K1; + delete []E; + + memcpy (pHash, K, 32); // pHash - from sha256 + return true; + } + bool CEncrypt::MakeFileKey2(const std::string &sUserPassword) + { + unsigned char sTest[32]; + unsigned char sTempKey[16]; + int nLen = 0; + bool bResult = true; + + unsigned char* pBuffer = new unsigned char[72 + 16]; + + if (false == sUserPassword.empty()) + { + nLen = sUserPassword.length(); + if (nLen < 32) + { + memcpy(pBuffer, sUserPassword.c_str(), nLen); + memcpy(pBuffer + nLen, passwordPad, 32 - nLen); + } + else + memcpy(pBuffer, sUserPassword.c_str(), 32); + } + else + memcpy(pBuffer, passwordPad, 32); + + memcpy(pBuffer + 32, m_anOwnerKey, 32); + + pBuffer[64] = m_unPermission & 0xff; + pBuffer[65] = (m_unPermission >> 8) & 0xff; + pBuffer[66] = (m_unPermission >> 16) & 0xff; + pBuffer[67] = (m_unPermission >> 24) & 0xff; + + memcpy(pBuffer + 68, m_anEncryptID, 16); + nLen = 68 + 16; + if (!true) + { + pBuffer[nLen++] = 0xff; + pBuffer[nLen++] = 0xff; + pBuffer[nLen++] = 0xff; + pBuffer[nLen++] = 0xff; + } + MD5(pBuffer, nLen, impl->m_anEncryptionKey); + if (m_unRevision >= 3) + for (int nIndex = 0; nIndex < 50; ++nIndex) + MD5(impl->m_anEncryptionKey, impl->m_unEncryptionKeyLength, impl->m_anEncryptionKey); + + if (m_unRevision == 2) + { + CryptoPP::ARC4::Decryption rc4Decryption; + rc4Decryption.SetKey(impl->m_anEncryptionKey, impl->m_unEncryptionKeyLength); + + rc4Decryption.ProcessData(sTest, m_anUserKey, 32); + + bResult = (memcmp(sTest, passwordPad, 32) == 0); + } + else if (m_unRevision >= 3) + { + memcpy(sTest, m_anUserKey, 32); + for (int nIndex = 19; nIndex >= 0; --nIndex) + { + for (unsigned int nJ = 0; nJ < impl->m_unEncryptionKeyLength; ++nJ) + sTempKey[nJ] = impl->m_anEncryptionKey[nJ] ^ nIndex; + CryptoPP::ARC4::Decryption rc4Decryption; + + rc4Decryption.SetKey(sTempKey, impl->m_unEncryptionKeyLength); + rc4Decryption.ProcessData(sTest, sTest, 32); + } + memcpy(pBuffer, passwordPad, 32); + memcpy(pBuffer + 32, m_anEncryptID, 16); + + MD5(pBuffer, 32 + 16, pBuffer); + + bResult = (memcmp(sTest, pBuffer, 16) == 0); + } + else + bResult = false; + + delete[] pBuffer; + return bResult; + } + + void CEncrypt::CreateUserKey() + { + CryptoPP::RandomPool prng; + + CryptoPP::SecByteBlock salt(16); + CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size()); + prng.IncorporateEntropy(salt, salt.size()); + + memcpy(m_anUserKey + 32, salt.data(), salt.size()); + + CryptoPP::SHA256 hash; + + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 32, 8); + + CryptoPP::SecByteBlock pHashData(hash.DigestSize()); + hash.Final(pHashData); + + if (MakeFileKey3(impl->m_sUserPassword, pHashData.data(), pHashData.size())) + { + memcpy(m_anUserKey, pHashData.data(), pHashData.size()); + + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 40, 8); + + CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); + hash.Final(pHashKeyData); + + MakeFileKey3(impl->m_sUserPassword, pHashKeyData.data(), pHashKeyData.size()); + unsigned char empty[16] = {}; + + CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size()); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty); + + CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anUserEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true); + stfEncryption.MessageEnd(); + } + } + void CEncrypt::CreateOwnerKey() + { + CryptoPP::RandomPool prng; + + CryptoPP::SecByteBlock salt(16); + CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size()); + prng.IncorporateEntropy(salt, salt.size()); + + memcpy(m_anOwnerKey + 32, salt.data(), salt.size()); + + CryptoPP::SHA256 hash; + + hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); + hash.Update( m_anOwnerKey + 32, 8); + hash.Update( m_anUserKey, 48); + + CryptoPP::SecByteBlock pHashData(hash.DigestSize()); + hash.Final(pHashData); + + if (MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48)) + { + memcpy(m_anOwnerKey, pHashData.data(), pHashData.size()); + + hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); + hash.Update( m_anOwnerKey + 40, 8); + hash.Update( m_anUserKey, 48); + + CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); + hash.Final(pHashKeyData); + + MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48); + unsigned char empty[16] = {}; + + CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size()); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty); + + CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anOwnerEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true); + stfEncryption.MessageEnd(); + } + } + void CEncrypt::CreateEncryptionKey() + { + CryptoPP::RandomPool prng; + + CryptoPP::SecByteBlock key(32); + CryptoPP::OS_GenerateRandomBlock(false, key, key.size()); + prng.IncorporateEntropy(key, key.size()); + + memcpy(impl->m_anEncryptionKey, key.data(), key.size()); +//------------------------------------------------------------------- + + unsigned long long extended_perms = 0xffffffff00000000LL | m_unPermission; + for (int i = 0; i < 8; ++i) + { + m_anPermEncrypt[i] = static_cast(extended_perms & 0xff); + extended_perms >>= 8; + } + m_anPermEncrypt[8] = /*m_bEncryptMetadata ? 'T' : */'F'; + m_anPermEncrypt[9] = 'a'; + m_anPermEncrypt[10] = 'd'; + m_anPermEncrypt[11] = 'b'; + + CryptoPP::SecByteBlock p(4); + CryptoPP::OS_GenerateRandomBlock(false, p, p.size()); + prng.IncorporateEntropy(p, p.size()); + + memcpy(m_anPermEncrypt + 12, p.data(), p.size()); + + unsigned char empty[16] = {}; + + CryptoPP::AES::Encryption aesEncryption(impl->m_anEncryptionKey, 32); + + CryptoPP::CipherModeFinalTemplate_ExternalCipher ecbEncryption(aesEncryption, empty ); + + CryptoPP::StreamTransformationFilter stfEncryption(ecbEncryption, new CryptoPP::ArraySink( m_anPermEncrypt, 16), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfEncryption.Put2(m_anPermEncrypt, 16, 1, true); + stfEncryption.MessageEnd(); + } + void CEncrypt::InitKey(unsigned int unObjectId, unsigned short unGenNo) + { + impl->m_nObjNum = unObjectId; + impl->m_nObjGen = unGenNo; + } + void CEncrypt::Reset() + { + impl->Reset(); + } + #define PADDING_SIZE 16 + unsigned int CEncrypt::CryptBuf(const BYTE* pSrc, BYTE* pDst, unsigned int unLen) + { + if (impl->m_nCryptAlgorithm == 0) // cryptRC4 + { + impl->rc4Encryption->ProcessData(pDst, pSrc, unLen); + // the algorithm does not change the length of the data + return unLen; + } + // cryptAES & cryptAES256 + + // Note that the pad is present when M is evenly divisible by 16 + unsigned int unLenOut = (unLen / PADDING_SIZE + 1) * PADDING_SIZE; + + memcpy(pDst, impl->streamInitialization, 16); + + CryptoPP::StreamTransformationFilter stfEncryption(*impl->streamEncryption, new CryptoPP::ArraySink( pDst + 16, unLenOut), CryptoPP::StreamTransformationFilter::NO_PADDING ); + + stfEncryption.Put2(pSrc, unLen, 0, true); + + if (unLenOut != unLen) + { + unsigned char empty[16] = {}; + // EXAMPLE A 9-byte message has a pad of 7 bytes, each with the value 0x07. + memset(empty, unLenOut - unLen, 16); + stfEncryption.Put2(empty, unLenOut - unLen, 0, true); + + } + stfEncryption.MessageEnd(); + + return unLenOut + 16; + } + //unsigned int CEncrypt::CryptBuf(const BYTE* pSrc, BYTE* pDst, unsigned int unLen, bool bFirst, bool bLast) + // { + // unsigned int unLenOut = unLen; + + // if (unLenOut % PADDING_SIZE != 0 && bLast) + // unLenOut = (unLen / PADDING_SIZE + 1) * PADDING_SIZE; + + // if(bFirst) + // memcpy(pDst, impl->streamInitialization, 16); + + // CryptoPP::StreamTransformationFilter stfEncryption(*impl->streamEncryption, new CryptoPP::ArraySink( pDst + (bFirst ? 16 : 0), unLenOut), CryptoPP::StreamTransformationFilter::NO_PADDING ); + + // stfEncryption.Put2(pSrc, unLen, 0, true); + // + //if (unLenOut != unLen && bLast) + // { + // unsigned char empty[16] = {}; + // stfEncryption.Put2(empty, unLenOut - unLen, 0, true); + + // } + // if (bLast) + // { + // stfEncryption.MessageEnd(); + // } + // return unLenOut + (bFirst ? 16 : 0); + // } + void CEncrypt::SetKeyLength(unsigned int unLen) + { + impl->m_unEncryptionKeyLength = unLen / 8; + } +} diff --git a/PdfWriter/Src/Encrypt.h b/PdfFile/SrcWriter/Encrypt.h similarity index 100% rename from PdfWriter/Src/Encrypt.h rename to PdfFile/SrcWriter/Encrypt.h diff --git a/PdfWriter/Src/EncryptDictionary.cpp b/PdfFile/SrcWriter/EncryptDictionary.cpp similarity index 97% rename from PdfWriter/Src/EncryptDictionary.cpp rename to PdfFile/SrcWriter/EncryptDictionary.cpp index 429f239a7a..6500e91508 100644 --- a/PdfWriter/Src/EncryptDictionary.cpp +++ b/PdfFile/SrcWriter/EncryptDictionary.cpp @@ -1,397 +1,397 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "EncryptDictionary.h" -#include "Encrypt.h" -#include "Info.h" -#include "Streams.h" - -#include - -#include "../../Common/3dParty/cryptopp/md5.h" -#include "../../UnicodeConverter/UnicodeConverter.h" - -#define SET_BINARY_PARAM(Name, set_func) \ - pObj = Get(Name);\ - if (pObj && pObj->GetType() == object_type_BINARY)\ - m_pEncrypt->set_func(((CBinaryObject*)pObj)->GetValue(), ((CBinaryObject*)pObj)->GetLength()); -#define SET_NUMBER_PARAM(Name, set_func) \ - pObj = Get(Name);\ - if (pObj && pObj->GetType() == object_type_NUMBER)\ - m_pEncrypt->set_func(((CNumberObject*)pObj)->Get()); - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CEncryptDict - //---------------------------------------------------------------------------------------- - CEncryptDict::CEncryptDict() - { - m_pEncrypt = new CEncrypt(); - } - CEncryptDict::CEncryptDict(CXref* pXref) - { - m_pEncrypt = new CEncrypt(); - - pXref->Add(this); - } - void CEncryptDict::Fix() - { - CObjectBase* pObj = NULL; - SET_BINARY_PARAM("O", SetO); - SET_BINARY_PARAM("U", SetU); - SET_BINARY_PARAM("OE", SetOE); - SET_BINARY_PARAM("UE", SetUE); - SET_BINARY_PARAM("Perms", SetPerms); - SET_BINARY_PARAM("ID", SetID); - Remove("ID"); - - SET_NUMBER_PARAM("P", SetPermission); - SET_NUMBER_PARAM("R", SetRevision); - SET_NUMBER_PARAM("V", SetVersion); - SET_NUMBER_PARAM("Length", SetKeyLength); - } - CEncryptDict::~CEncryptDict() - { - if (m_pEncrypt) - delete m_pEncrypt; - } - void CEncryptDict::CreateId(CInfoDict* pInfo, CXref* pXref, BYTE* pBuffer) - { - CryptoPP::MD5 hash; - - std::time_t oTime = time(0); - hash.Update( (BYTE*)&oTime, sizeof(oTime)); - - // Создаем идентификатор файла по элементам библиотеки Info. - if (pInfo) - { - const char *sTemp = NULL; - unsigned int nLen = 0; - - // Author - sTemp = pInfo->GetInfo(InfoAuthor); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen ); - - // Creator - sTemp = pInfo->GetInfo(InfoCreator); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen); - - // Producer - sTemp = pInfo->GetInfo(InfoProducer); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen); - - // Title - sTemp = pInfo->GetInfo(InfoTitle); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen); - - // Subject - sTemp = pInfo->GetInfo(InfoSubject); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen); - - // Keywords - sTemp = pInfo->GetInfo(InfoKeyWords); - if ((nLen = StrLen(sTemp, -1)) > 0) - hash.Update( (const BYTE *)sTemp, nLen); - - int nXrefEntriesCount = pXref->GetCount(); - hash.Update( (const BYTE *)&nXrefEntriesCount, sizeof(unsigned int)); - - } - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - memcpy(pBuffer, buffer.BytePtr(), buffer.size()); - } - std::string CEncryptDict::PadOrTrancatePassword(const std::wstring & wsPassword) - { - NSUnicodeConverter::CUnicodeConverter conv; - std::string sNewPassword = conv.SASLprepToUtf8(wsPassword); - - if (sNewPassword.length() > 127) - sNewPassword = sNewPassword.substr(0, 127); - - return sNewPassword; - } - void CEncryptDict::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) - { - std::string sOwnerPassword = PadOrTrancatePassword(wsOwnerPassword); - std::string sUserPassword = PadOrTrancatePassword(wsUserPassword); - - m_pEncrypt->SetPasswords(sUserPassword, sOwnerPassword); - } - void CEncryptDict::Prepare(CInfoDict* pInfo, CXref* pXref) - { - CreateId(pInfo, pXref, (BYTE*)m_pEncrypt->m_anEncryptID); - - m_pEncrypt->CreateEncryptionKey(); - m_pEncrypt->CreateUserKey(); - m_pEncrypt->CreateOwnerKey(); - - Add("Filter", "Standard"); - Add("V", 5); - Add("Length", m_pEncrypt->m_unKeyLen * 8); - Add("R", 6); - Add("P", m_pEncrypt->m_unPermission); - - CDictObject* pCF = new CDictObject(); - - CDictObject* pStdCF = new CDictObject(); - pCF->Add("StdCF", pStdCF); - - pStdCF->Add("CFM", "AESV3"); - pStdCF->Add("AuthEvent", "DocOpen"); - pStdCF->Add("Length", m_pEncrypt->m_unKeyLen); - - Add("CF", pCF); - Add("StmF", "StdCF"); - Add("StrF", "StdCF"); - - CBinaryObject* pUserKey = new CBinaryObject(m_pEncrypt->m_anUserKey, 48); - if (!pUserKey) - return; - - CBinaryObject* pUserEncryptKey = new CBinaryObject(m_pEncrypt->m_anUserEncryptKey, 32); - if (!pUserKey) - return; - - Add("U", pUserKey); - Add("UE", pUserEncryptKey); - - CBinaryObject* pOwnerKey = new CBinaryObject(m_pEncrypt->m_anOwnerKey, 48); - if (!pOwnerKey) - return; - - CBinaryObject* pOwnerEncryptKey = new CBinaryObject(m_pEncrypt->m_anOwnerEncryptKey, 32); - if (!pOwnerKey) - return; - - Add("O", pOwnerKey); - Add("OE", pOwnerEncryptKey); - - CBinaryObject* pEncryptPerm = new CBinaryObject(m_pEncrypt->m_anPermEncrypt, 16); - Add("Perms", pEncryptPerm); - } - void CEncryptDict::UpdateKey(int nCryptAlgorithm) - { - m_pEncrypt->MakeFileKey(nCryptAlgorithm); - } - //---------------------------------------------------------------------------------------- - // CSignatureDict - //---------------------------------------------------------------------------------------- - CSignatureDict::CSignatureDict(CXref* pXref) - { - pXref->Add(this); - - Add("Type", "Sig"); - Add("Filter", "Adobe.PPKLite"); - Add("SubFilter", "adbe.pkcs7.detached"); - - unsigned int unDigestLength = 15000; - BYTE* pDigest = new BYTE[unDigestLength]; - memset(pDigest, 0, unDigestLength); - Add("Contents", new CBinaryObject(pDigest, unDigestLength)); - RELEASEARRAYOBJECTS(pDigest); - - CArrayObject* pByteRange = new CArrayObject(); - if (!pByteRange) - return; - Add("ByteRange", pByteRange); - pByteRange->Add(0); - pByteRange->Add(1234567890); - pByteRange->Add(1234567890); - pByteRange->Add(1234567890); - - // Reference - Массив справочных словарей сигнатур - - // Changes - Массив из трех чисел, который указывает изменения в документе в порядке: количество измененных страниц, - // количество измененных полей и количество заполненных полей - // Порядок подписей определяется значением ByteRange. Поскольку каждая подпись приводит к добавочному сохранению, - // более поздние подписи имеют большее значение длины - - // Prop_Build - Словарь, который может использоваться обработчиком подписи для записи информации о состоянии компьютерной среды, - // используемой для подписи, такой как имя обработчика, используемого для создания подписи, дата сборки программного обеспечения, - // версия, и операционная система. Спецификация словаря PDF Signature Build содержит рекомендации по использованию этого словаря - - m_nLen1 = 0; - m_nOffset2 = 0; - m_nByteRangeBegin = 0; - m_nByteRangeEnd = 0; - } - CSignatureDict::~CSignatureDict() - { - } - void CSignatureDict::SetByteRange(int nLen1, int nOffset2) - { - m_nLen1 = nLen1; - m_nOffset2 = nOffset2; - } - void CSignatureDict::ByteRangeOffset(int nBegin, int nEnd) - { - m_nByteRangeBegin = nBegin; - m_nByteRangeEnd = nEnd; - } - void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd) - { - // Запись ByteRange - if (m_nByteRangeBegin > 0 && m_nByteRangeEnd > 0 && m_nByteRangeBegin < m_nByteRangeEnd && m_nByteRangeEnd < nFileEnd) - { - CArrayObject* pByteRange = new CArrayObject(); - if (!pByteRange) - return; - if (m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd) - { - pByteRange->Add(0); - pByteRange->Add(m_nLen1); - pByteRange->Add(m_nOffset2); - pByteRange->Add(nFileEnd - m_nOffset2); - - pStream->Seek(m_nByteRangeBegin, EWhenceMode::SeekSet); - pStream->Write(pByteRange, NULL); - - int nEnd = pStream->Tell(); - if (nEnd < m_nByteRangeEnd) - { - unsigned int nLength = m_nByteRangeEnd - nEnd; - BYTE* pDifference = new BYTE[nLength]; - MemSet(pDifference, ' ', nLength); - - pStream->Write(pDifference, nLength); - - RELEASEARRAYOBJECTS(pDifference); - } - } - RELEASEOBJECT(pByteRange); - } - // Запись Contents - if (m_pCertificate && m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd) - { - DWORD dwLenDataForSignature = m_nLen1 + nFileEnd - m_nOffset2; - BYTE* pDataForSignature = new BYTE[dwLenDataForSignature]; - if (!pDataForSignature) - return; - - pStream->Seek(0, EWhenceMode::SeekSet); - unsigned int dwLenReadData = m_nLen1; - pStream->Read(pDataForSignature, &dwLenReadData); - if ((int)dwLenReadData != m_nLen1) - { - RELEASEARRAYOBJECTS(pDataForSignature); - return; - } - - pStream->Seek(m_nOffset2, EWhenceMode::SeekSet); - dwLenReadData = nFileEnd - m_nOffset2; - pStream->Read(pDataForSignature + m_nLen1, &dwLenReadData); - if ((int)dwLenReadData != nFileEnd - m_nOffset2) - { - RELEASEARRAYOBJECTS(pDataForSignature); - return; - } - - BYTE* pDatatoWrite; - unsigned int dwLenDatatoWrite; - m_pCertificate->SignPKCS7(pDataForSignature, dwLenDataForSignature, pDatatoWrite, dwLenDatatoWrite); - RELEASEARRAYOBJECTS(pDataForSignature); - if (!pDatatoWrite) - return; - - pStream->Seek(m_nLen1, EWhenceMode::SeekSet); - CBinaryObject* pContents = new CBinaryObject(pDatatoWrite, dwLenDatatoWrite); - RELEASEARRAYOBJECTS(pDatatoWrite); - if (!pContents) - return; - // Цифровая подпись не шифруется - pStream->Write(pContents, NULL); - RELEASEOBJECT(pContents); - - // Стереть лишний > - BYTE cChar = '0'; - pStream->Seek(pStream->Tell() - 1, EWhenceMode::SeekSet); - pStream->Write(&cChar, 1); - } - } - void CSignatureDict::SetCert(ICertificate* pCert) - { - m_pCertificate = pCert; - } - void CSignatureDict::SetName(const std::string& sName) - { - // Name - Cтрока, Имя лица или органа, подписавшего документ. - // Значение следует использовать когда невозможно извлечь имя из подписи или сертификата подписавшего. - Add("Name", new CStringObject(sName.c_str())); - } - void CSignatureDict::SetReason(const std::string& sReason) - { - // Reason - Строка, Причина подписания, например (Я согласен) - Add("Reason", new CStringObject(sReason.c_str())); - } - void CSignatureDict::SetContact(const std::string& sContacts) - { - // ContactInfo - Строка, Информация, предоставленная подписывающей стороной, - // чтобы получатель мог связаться с подписывающей стороной для проверки подписи, например (номер_телефона) - Add("ContactInfo", new CStringObject(sContacts.c_str())); - } - void CSignatureDict::SetDate() - { - // M - Дата, Время подписания - // Значение следует использовать когда время подписания недоступно в подписи - char sTemp[DATE_TIME_STR_LEN + 1]; - char* pTemp = NULL; - - MemSet(sTemp, 0, DATE_TIME_STR_LEN + 1); - time_t oTime = time(0); - struct tm* oNow = gmtime(&oTime); - - pTemp = (char*)MemCpy((BYTE*)sTemp, (BYTE*)"D:", 2); - *pTemp++; - *pTemp++; - pTemp = ItoA2(pTemp, oNow->tm_year + 1900, 5); - pTemp = ItoA2(pTemp, oNow->tm_mon + 1, 3); - pTemp = ItoA2(pTemp, oNow->tm_mday, 3); - pTemp = ItoA2(pTemp, oNow->tm_hour, 3); - pTemp = ItoA2(pTemp, oNow->tm_min, 3); - pTemp = ItoA2(pTemp, oNow->tm_sec, 3); - *pTemp++ = '+'; - pTemp = ItoA2(pTemp, 0, 3); - *pTemp++ = '\''; - pTemp = ItoA2(pTemp, 0, 3); - *pTemp++ = '\''; - *pTemp = 0; - - Add("M", new CStringObject(sTemp)); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "EncryptDictionary.h" +#include "Encrypt.h" +#include "Info.h" +#include "Streams.h" + +#include + +#include "../../Common/3dParty/cryptopp/md5.h" +#include "../../UnicodeConverter/UnicodeConverter.h" + +#define SET_BINARY_PARAM(Name, set_func) \ + pObj = Get(Name);\ + if (pObj && pObj->GetType() == object_type_BINARY)\ + m_pEncrypt->set_func(((CBinaryObject*)pObj)->GetValue(), ((CBinaryObject*)pObj)->GetLength()); +#define SET_NUMBER_PARAM(Name, set_func) \ + pObj = Get(Name);\ + if (pObj && pObj->GetType() == object_type_NUMBER)\ + m_pEncrypt->set_func(((CNumberObject*)pObj)->Get()); + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CEncryptDict + //---------------------------------------------------------------------------------------- + CEncryptDict::CEncryptDict() + { + m_pEncrypt = new CEncrypt(); + } + CEncryptDict::CEncryptDict(CXref* pXref) + { + m_pEncrypt = new CEncrypt(); + + pXref->Add(this); + } + void CEncryptDict::Fix() + { + CObjectBase* pObj = NULL; + SET_BINARY_PARAM("O", SetO); + SET_BINARY_PARAM("U", SetU); + SET_BINARY_PARAM("OE", SetOE); + SET_BINARY_PARAM("UE", SetUE); + SET_BINARY_PARAM("Perms", SetPerms); + SET_BINARY_PARAM("ID", SetID); + Remove("ID"); + + SET_NUMBER_PARAM("P", SetPermission); + SET_NUMBER_PARAM("R", SetRevision); + SET_NUMBER_PARAM("V", SetVersion); + SET_NUMBER_PARAM("Length", SetKeyLength); + } + CEncryptDict::~CEncryptDict() + { + if (m_pEncrypt) + delete m_pEncrypt; + } + void CEncryptDict::CreateId(CInfoDict* pInfo, CXref* pXref, BYTE* pBuffer) + { + CryptoPP::MD5 hash; + + std::time_t oTime = time(0); + hash.Update( (BYTE*)&oTime, sizeof(oTime)); + + // Создаем идентификатор файла по элементам библиотеки Info. + if (pInfo) + { + const char *sTemp = NULL; + unsigned int nLen = 0; + + // Author + sTemp = pInfo->GetInfo(InfoAuthor); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen ); + + // Creator + sTemp = pInfo->GetInfo(InfoCreator); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen); + + // Producer + sTemp = pInfo->GetInfo(InfoProducer); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen); + + // Title + sTemp = pInfo->GetInfo(InfoTitle); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen); + + // Subject + sTemp = pInfo->GetInfo(InfoSubject); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen); + + // Keywords + sTemp = pInfo->GetInfo(InfoKeyWords); + if ((nLen = StrLen(sTemp, -1)) > 0) + hash.Update( (const BYTE *)sTemp, nLen); + + int nXrefEntriesCount = pXref->GetCount(); + hash.Update( (const BYTE *)&nXrefEntriesCount, sizeof(unsigned int)); + + } + CryptoPP::SecByteBlock buffer(hash.DigestSize()); + hash.Final(buffer); + + memcpy(pBuffer, buffer.BytePtr(), buffer.size()); + } + std::string CEncryptDict::PadOrTrancatePassword(const std::wstring & wsPassword) + { + NSUnicodeConverter::CUnicodeConverter conv; + std::string sNewPassword = conv.SASLprepToUtf8(wsPassword); + + if (sNewPassword.length() > 127) + sNewPassword = sNewPassword.substr(0, 127); + + return sNewPassword; + } + void CEncryptDict::SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword) + { + std::string sOwnerPassword = PadOrTrancatePassword(wsOwnerPassword); + std::string sUserPassword = PadOrTrancatePassword(wsUserPassword); + + m_pEncrypt->SetPasswords(sUserPassword, sOwnerPassword); + } + void CEncryptDict::Prepare(CInfoDict* pInfo, CXref* pXref) + { + CreateId(pInfo, pXref, (BYTE*)m_pEncrypt->m_anEncryptID); + + m_pEncrypt->CreateEncryptionKey(); + m_pEncrypt->CreateUserKey(); + m_pEncrypt->CreateOwnerKey(); + + Add("Filter", "Standard"); + Add("V", 5); + Add("Length", m_pEncrypt->m_unKeyLen * 8); + Add("R", 6); + Add("P", m_pEncrypt->m_unPermission); + + CDictObject* pCF = new CDictObject(); + + CDictObject* pStdCF = new CDictObject(); + pCF->Add("StdCF", pStdCF); + + pStdCF->Add("CFM", "AESV3"); + pStdCF->Add("AuthEvent", "DocOpen"); + pStdCF->Add("Length", m_pEncrypt->m_unKeyLen); + + Add("CF", pCF); + Add("StmF", "StdCF"); + Add("StrF", "StdCF"); + + CBinaryObject* pUserKey = new CBinaryObject(m_pEncrypt->m_anUserKey, 48); + if (!pUserKey) + return; + + CBinaryObject* pUserEncryptKey = new CBinaryObject(m_pEncrypt->m_anUserEncryptKey, 32); + if (!pUserKey) + return; + + Add("U", pUserKey); + Add("UE", pUserEncryptKey); + + CBinaryObject* pOwnerKey = new CBinaryObject(m_pEncrypt->m_anOwnerKey, 48); + if (!pOwnerKey) + return; + + CBinaryObject* pOwnerEncryptKey = new CBinaryObject(m_pEncrypt->m_anOwnerEncryptKey, 32); + if (!pOwnerKey) + return; + + Add("O", pOwnerKey); + Add("OE", pOwnerEncryptKey); + + CBinaryObject* pEncryptPerm = new CBinaryObject(m_pEncrypt->m_anPermEncrypt, 16); + Add("Perms", pEncryptPerm); + } + void CEncryptDict::UpdateKey(int nCryptAlgorithm) + { + m_pEncrypt->MakeFileKey(nCryptAlgorithm); + } + //---------------------------------------------------------------------------------------- + // CSignatureDict + //---------------------------------------------------------------------------------------- + CSignatureDict::CSignatureDict(CXref* pXref) + { + pXref->Add(this); + + Add("Type", "Sig"); + Add("Filter", "Adobe.PPKLite"); + Add("SubFilter", "adbe.pkcs7.detached"); + + unsigned int unDigestLength = 15000; + BYTE* pDigest = new BYTE[unDigestLength]; + memset(pDigest, 0, unDigestLength); + Add("Contents", new CBinaryObject(pDigest, unDigestLength)); + RELEASEARRAYOBJECTS(pDigest); + + CArrayObject* pByteRange = new CArrayObject(); + if (!pByteRange) + return; + Add("ByteRange", pByteRange); + pByteRange->Add(0); + pByteRange->Add(1234567890); + pByteRange->Add(1234567890); + pByteRange->Add(1234567890); + + // Reference - Массив справочных словарей сигнатур + + // Changes - Массив из трех чисел, который указывает изменения в документе в порядке: количество измененных страниц, + // количество измененных полей и количество заполненных полей + // Порядок подписей определяется значением ByteRange. Поскольку каждая подпись приводит к добавочному сохранению, + // более поздние подписи имеют большее значение длины + + // Prop_Build - Словарь, который может использоваться обработчиком подписи для записи информации о состоянии компьютерной среды, + // используемой для подписи, такой как имя обработчика, используемого для создания подписи, дата сборки программного обеспечения, + // версия, и операционная система. Спецификация словаря PDF Signature Build содержит рекомендации по использованию этого словаря + + m_nLen1 = 0; + m_nOffset2 = 0; + m_nByteRangeBegin = 0; + m_nByteRangeEnd = 0; + } + CSignatureDict::~CSignatureDict() + { + } + void CSignatureDict::SetByteRange(int nLen1, int nOffset2) + { + m_nLen1 = nLen1; + m_nOffset2 = nOffset2; + } + void CSignatureDict::ByteRangeOffset(int nBegin, int nEnd) + { + m_nByteRangeBegin = nBegin; + m_nByteRangeEnd = nEnd; + } + void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd) + { + // Запись ByteRange + if (m_nByteRangeBegin > 0 && m_nByteRangeEnd > 0 && m_nByteRangeBegin < m_nByteRangeEnd && m_nByteRangeEnd < nFileEnd) + { + CArrayObject* pByteRange = new CArrayObject(); + if (!pByteRange) + return; + if (m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd) + { + pByteRange->Add(0); + pByteRange->Add(m_nLen1); + pByteRange->Add(m_nOffset2); + pByteRange->Add(nFileEnd - m_nOffset2); + + pStream->Seek(m_nByteRangeBegin, EWhenceMode::SeekSet); + pStream->Write(pByteRange, NULL); + + int nEnd = pStream->Tell(); + if (nEnd < m_nByteRangeEnd) + { + unsigned int nLength = m_nByteRangeEnd - nEnd; + BYTE* pDifference = new BYTE[nLength]; + MemSet(pDifference, ' ', nLength); + + pStream->Write(pDifference, nLength); + + RELEASEARRAYOBJECTS(pDifference); + } + } + RELEASEOBJECT(pByteRange); + } + // Запись Contents + if (m_pCertificate && m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd) + { + DWORD dwLenDataForSignature = m_nLen1 + nFileEnd - m_nOffset2; + BYTE* pDataForSignature = new BYTE[dwLenDataForSignature]; + if (!pDataForSignature) + return; + + pStream->Seek(0, EWhenceMode::SeekSet); + unsigned int dwLenReadData = m_nLen1; + pStream->Read(pDataForSignature, &dwLenReadData); + if ((int)dwLenReadData != m_nLen1) + { + RELEASEARRAYOBJECTS(pDataForSignature); + return; + } + + pStream->Seek(m_nOffset2, EWhenceMode::SeekSet); + dwLenReadData = nFileEnd - m_nOffset2; + pStream->Read(pDataForSignature + m_nLen1, &dwLenReadData); + if ((int)dwLenReadData != nFileEnd - m_nOffset2) + { + RELEASEARRAYOBJECTS(pDataForSignature); + return; + } + + BYTE* pDatatoWrite; + unsigned int dwLenDatatoWrite; + m_pCertificate->SignPKCS7(pDataForSignature, dwLenDataForSignature, pDatatoWrite, dwLenDatatoWrite); + RELEASEARRAYOBJECTS(pDataForSignature); + if (!pDatatoWrite) + return; + + pStream->Seek(m_nLen1, EWhenceMode::SeekSet); + CBinaryObject* pContents = new CBinaryObject(pDatatoWrite, dwLenDatatoWrite); + RELEASEARRAYOBJECTS(pDatatoWrite); + if (!pContents) + return; + // Цифровая подпись не шифруется + pStream->Write(pContents, NULL); + RELEASEOBJECT(pContents); + + // Стереть лишний > + BYTE cChar = '0'; + pStream->Seek(pStream->Tell() - 1, EWhenceMode::SeekSet); + pStream->Write(&cChar, 1); + } + } + void CSignatureDict::SetCert(ICertificate* pCert) + { + m_pCertificate = pCert; + } + void CSignatureDict::SetName(const std::string& sName) + { + // Name - Cтрока, Имя лица или органа, подписавшего документ. + // Значение следует использовать когда невозможно извлечь имя из подписи или сертификата подписавшего. + Add("Name", new CStringObject(sName.c_str())); + } + void CSignatureDict::SetReason(const std::string& sReason) + { + // Reason - Строка, Причина подписания, например (Я согласен) + Add("Reason", new CStringObject(sReason.c_str())); + } + void CSignatureDict::SetContact(const std::string& sContacts) + { + // ContactInfo - Строка, Информация, предоставленная подписывающей стороной, + // чтобы получатель мог связаться с подписывающей стороной для проверки подписи, например (номер_телефона) + Add("ContactInfo", new CStringObject(sContacts.c_str())); + } + void CSignatureDict::SetDate() + { + // M - Дата, Время подписания + // Значение следует использовать когда время подписания недоступно в подписи + char sTemp[DATE_TIME_STR_LEN + 1]; + char* pTemp = NULL; + + MemSet(sTemp, 0, DATE_TIME_STR_LEN + 1); + time_t oTime = time(0); + struct tm* oNow = gmtime(&oTime); + + pTemp = (char*)MemCpy((BYTE*)sTemp, (BYTE*)"D:", 2); + *pTemp++; + *pTemp++; + pTemp = ItoA2(pTemp, oNow->tm_year + 1900, 5); + pTemp = ItoA2(pTemp, oNow->tm_mon + 1, 3); + pTemp = ItoA2(pTemp, oNow->tm_mday, 3); + pTemp = ItoA2(pTemp, oNow->tm_hour, 3); + pTemp = ItoA2(pTemp, oNow->tm_min, 3); + pTemp = ItoA2(pTemp, oNow->tm_sec, 3); + *pTemp++ = '+'; + pTemp = ItoA2(pTemp, 0, 3); + *pTemp++ = '\''; + pTemp = ItoA2(pTemp, 0, 3); + *pTemp++ = '\''; + *pTemp = 0; + + Add("M", new CStringObject(sTemp)); + } +} diff --git a/PdfWriter/Src/EncryptDictionary.h b/PdfFile/SrcWriter/EncryptDictionary.h similarity index 97% rename from PdfWriter/Src/EncryptDictionary.h rename to PdfFile/SrcWriter/EncryptDictionary.h index 8254584140..dd19873ea4 100644 --- a/PdfWriter/Src/EncryptDictionary.h +++ b/PdfFile/SrcWriter/EncryptDictionary.h @@ -1,99 +1,99 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H -#define _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H - -#include "Objects.h" - -#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" - -namespace PdfWriter -{ - class CEncrypt; - class CInfoDict; - class CStream; - - class CEncryptDict : public CDictObject - { - public: - CEncryptDict(); - CEncryptDict(CXref* pXref); - void Fix(); - ~CEncryptDict(); - EDictType GetDictType() const - { - return dict_type_ENCRYPT; - } - - static void CreateId(CInfoDict* pDict, CXref* pXref, BYTE* pBuffer); - void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); - void Prepare(CInfoDict* pInfo, CXref* pXref); - CEncrypt* GetEncrypt() const - { - return m_pEncrypt; - } - void UpdateKey(int nCryptAlgorithm); - private: - CEncrypt* m_pEncrypt; - std::string PadOrTrancatePassword(const std::wstring & wsPassword); - }; - - class CSignatureDict : public CDictObject - { - public: - CSignatureDict(CXref* pXref); - ~CSignatureDict(); - EDictType GetDictType() const - { - return dict_type_SIGNATURE; - } - - void SetByteRange(int nLen1, int nOffset2); - void ByteRangeOffset(int nBegin, int nEnd); - void WriteToStream(CStream* pStream, int nFileEnd); - void SetCert(ICertificate* pCert); - - void SetName(const std::string& sName); - void SetReason(const std::string& sReason); - void SetContact(const std::string& sContacts); - void SetDate(); - private: - ICertificate* m_pCertificate; - - int m_nLen1; // Длина первого интервала сигнатуры - int m_nOffset2; // Начало второго интервала сигнатуры - - int m_nByteRangeBegin; // Смещение начала массива ByteRange - int m_nByteRangeEnd; // Смещение конца массива ByteRange - }; -} -#endif // _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H +#define _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H + +#include "Objects.h" + +#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" + +namespace PdfWriter +{ + class CEncrypt; + class CInfoDict; + class CStream; + + class CEncryptDict : public CDictObject + { + public: + CEncryptDict(); + CEncryptDict(CXref* pXref); + void Fix(); + ~CEncryptDict(); + EDictType GetDictType() const + { + return dict_type_ENCRYPT; + } + + static void CreateId(CInfoDict* pDict, CXref* pXref, BYTE* pBuffer); + void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); + void Prepare(CInfoDict* pInfo, CXref* pXref); + CEncrypt* GetEncrypt() const + { + return m_pEncrypt; + } + void UpdateKey(int nCryptAlgorithm); + private: + CEncrypt* m_pEncrypt; + std::string PadOrTrancatePassword(const std::wstring & wsPassword); + }; + + class CSignatureDict : public CDictObject + { + public: + CSignatureDict(CXref* pXref); + ~CSignatureDict(); + EDictType GetDictType() const + { + return dict_type_SIGNATURE; + } + + void SetByteRange(int nLen1, int nOffset2); + void ByteRangeOffset(int nBegin, int nEnd); + void WriteToStream(CStream* pStream, int nFileEnd); + void SetCert(ICertificate* pCert); + + void SetName(const std::string& sName); + void SetReason(const std::string& sReason); + void SetContact(const std::string& sContacts); + void SetDate(); + private: + ICertificate* m_pCertificate; + + int m_nLen1; // Длина первого интервала сигнатуры + int m_nOffset2; // Начало второго интервала сигнатуры + + int m_nByteRangeBegin; // Смещение начала массива ByteRange + int m_nByteRangeEnd; // Смещение конца массива ByteRange + }; +} +#endif // _PDF_WRITER_SRC_ENCRYPT_DICTIONARY_H diff --git a/PdfWriter/Src/Field.cpp b/PdfFile/SrcWriter/Field.cpp similarity index 100% rename from PdfWriter/Src/Field.cpp rename to PdfFile/SrcWriter/Field.cpp diff --git a/PdfWriter/Src/Field.h b/PdfFile/SrcWriter/Field.h similarity index 100% rename from PdfWriter/Src/Field.h rename to PdfFile/SrcWriter/Field.h diff --git a/PdfWriter/Src/Font.cpp b/PdfFile/SrcWriter/Font.cpp similarity index 97% rename from PdfWriter/Src/Font.cpp rename to PdfFile/SrcWriter/Font.cpp index 04a67b3a78..3523f408bd 100644 --- a/PdfWriter/Src/Font.cpp +++ b/PdfFile/SrcWriter/Font.cpp @@ -1,45 +1,45 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Font.h" - -namespace PdfWriter -{ - CFontDict::CFontDict(CXref* pXref, CDocument* pDocument) - { - m_pXref = pXref; - pXref->Add(this); - m_pDocument = pDocument; - } - CFontDict::~CFontDict() - { - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Font.h" + +namespace PdfWriter +{ + CFontDict::CFontDict(CXref* pXref, CDocument* pDocument) + { + m_pXref = pXref; + pXref->Add(this); + m_pDocument = pDocument; + } + CFontDict::~CFontDict() + { + } +} diff --git a/PdfWriter/Src/Font.h b/PdfFile/SrcWriter/Font.h similarity index 100% rename from PdfWriter/Src/Font.h rename to PdfFile/SrcWriter/Font.h diff --git a/PdfWriter/Src/Font14.cpp b/PdfFile/SrcWriter/Font14.cpp similarity index 97% rename from PdfWriter/Src/Font14.cpp rename to PdfFile/SrcWriter/Font14.cpp index e4c9e06989..11312f78e0 100644 --- a/PdfWriter/Src/Font14.cpp +++ b/PdfFile/SrcWriter/Font14.cpp @@ -1,60 +1,60 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Font14.h" - -namespace PdfWriter -{ - static const char* c_sStandardFontNames[] = - { - "Helvetica", - "Helvetica-Bold", - "Helvetica-Oblique", - "Helvetice-BoldOblique", - "Courier", - "Courier-Bold", - "Courier-Oblique", - "Courier-BoldOblique", - "Times", - "Times-Bold", - "Times-Oblique", - "Times-BoldOblique", - "Symbol", - "ZapfDingbats", - NULL - }; - CFont14::CFont14(CXref* pXref, CDocument* pDocument, EStandard14Fonts eType) : CFontDict(pXref, pDocument) - { - Add("Type", "Font"); - Add("Subtype", "Type1"); - Add("BaseFont", c_sStandardFontNames[(int)eType]); - } +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Font14.h" + +namespace PdfWriter +{ + static const char* c_sStandardFontNames[] = + { + "Helvetica", + "Helvetica-Bold", + "Helvetica-Oblique", + "Helvetice-BoldOblique", + "Courier", + "Courier-Bold", + "Courier-Oblique", + "Courier-BoldOblique", + "Times", + "Times-Bold", + "Times-Oblique", + "Times-BoldOblique", + "Symbol", + "ZapfDingbats", + NULL + }; + CFont14::CFont14(CXref* pXref, CDocument* pDocument, EStandard14Fonts eType) : CFontDict(pXref, pDocument) + { + Add("Type", "Font"); + Add("Subtype", "Type1"); + Add("BaseFont", c_sStandardFontNames[(int)eType]); + } } \ No newline at end of file diff --git a/PdfWriter/Src/Font14.h b/PdfFile/SrcWriter/Font14.h similarity index 97% rename from PdfWriter/Src/Font14.h rename to PdfFile/SrcWriter/Font14.h index d41fbeb206..89278fbfbf 100644 --- a/PdfWriter/Src/Font14.h +++ b/PdfFile/SrcWriter/Font14.h @@ -1,53 +1,53 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_FONT14_H -#define _PDF_WRITER_SRC_FONT14_H - -#include "Font.h" - -namespace PdfWriter -{ - class CXref; - class CDocument; - class CFont14 : public CFontDict - { - public: - CFont14(CXref* pXref, CDocument* pDocument, EStandard14Fonts eType); - EFontType GetFontType() - { - return fontType1; - } - - }; -} - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_FONT14_H +#define _PDF_WRITER_SRC_FONT14_H + +#include "Font.h" + +namespace PdfWriter +{ + class CXref; + class CDocument; + class CFont14 : public CFontDict + { + public: + CFont14(CXref* pXref, CDocument* pDocument, EStandard14Fonts eType); + EFontType GetFontType() + { + return fontType1; + } + + }; +} + #endif // _PDF_WRITER_SRC_FONT14_H \ No newline at end of file diff --git a/PdfWriter/Src/FontCidTT.cpp b/PdfFile/SrcWriter/FontCidTT.cpp similarity index 96% rename from PdfWriter/Src/FontCidTT.cpp rename to PdfFile/SrcWriter/FontCidTT.cpp index 74e387ad45..d1ec00d586 100644 --- a/PdfWriter/Src/FontCidTT.cpp +++ b/PdfFile/SrcWriter/FontCidTT.cpp @@ -1,517 +1,517 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "FontCidTT.h" -#include "Document.h" -#include "Streams.h" -#include "Utils.h" -#include "FontTTWriter.h" - -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/common/File.h" - -#include - -#include FT_TRUETYPE_TABLES_H - -namespace PdfWriter -{ - static const char* c_sToUnicodeHeader = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n"; - static const char* c_sToUnicodeInfo = "/CIDSystemInfo\n<< /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n >> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000> \nendcodespacerange\n"; - static const char* c_sToUnicodeFooter = "endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend\n"; - - static int GetSymbolicCmapIndex(FT_Face pFace) - { - TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2); - if (NULL == pOs2 || 0xFFFF == pOs2->version) - return -1; - - // Проверяем установлен ли 31 бит - if (!(pOs2->ulCodePageRange1 & 0x80000000) && !(pOs2->ulCodePageRange1 == 0 && pOs2->ulCodePageRange2 == 0)) - return -1; - - - for (int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++) - { - // Symbol - if (0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id) - return nIndex; - } - - return -1; - } - //---------------------------------------------------------------------------------------- - // CFontFileBase - //---------------------------------------------------------------------------------------- - CFontCidTrueType::CFontCidTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex) : CFontDict(pXref, pDocument) - { - m_bNeedAddFontName = true; - CFontFileTrueType* pFontTT = CFontFileTrueType::LoadFromFile(wsFontPath, unIndex); - m_pFontFile = pFontTT; - - m_wsFontPath = wsFontPath; - m_unFontIndex = unIndex; - - Add("Type", "Font"); - Add("Subtype", "Type0"); - Add("Encoding", "Identity-H"); - - CDictObject* pFont = new CDictObject(); - m_pXref->Add(pFont); - - CArrayObject* pDescendantFonts = new CArrayObject(); - pDescendantFonts->Add(pFont); - - Add("DescendantFonts", pDescendantFonts); - CDictObject* pToUnicodeDict = new CDictObject(m_pXref); - Add("ToUnicode", pToUnicodeDict); - pToUnicodeDict->SetFilter(STREAM_FILTER_FLATE_DECODE); - m_pToUnicodeStream = pToUnicodeDict->GetStream(); - - CreateCIDFont2(pFont); - - m_pFace = NULL; - m_pFaceMemory = NULL; - m_nGlyphsCount = 0; - m_nSymbolicCmap = -1; - m_ushCodesCount = 0; - } - CFontCidTrueType::~CFontCidTrueType() - { - if (m_pFontFile) - delete m_pFontFile; - - if (m_pFace) - FT_Done_Face(m_pFace); - - if (m_pFaceMemory) - delete[] m_pFaceMemory; - } - void CFontCidTrueType::CreateCIDFont2(CDictObject* pFont) - { - m_pFont = pFont; - pFont->Add("Type", "Font"); - pFont->Add("Subtype", "CIDFontType2"); - - CDictObject* pSystemInfo = new CDictObject(); - pSystemInfo->Add("Registry", new CStringObject("Adobe")); - pSystemInfo->Add("Ordering", new CStringObject("Identity")); - pSystemInfo->Add("Supplement", 0); - - pFont->Add("CIDSystemInfo", pSystemInfo); - - CDictObject* pFontDescriptor = new CDictObject(); - // FontDescriptor обязательно должен идти ссылкой - m_pXref->Add(pFontDescriptor); - pFontDescriptor->Add("Type", "FontDescriptor"); - m_pFontDescriptor = pFontDescriptor; - - // Выставляем бит Symbolic, а бит NonSymbolic убираем - unsigned int nFlags = 0; - if (!(nFlags & 4)) - UIntChangeBit(nFlags, 2); - if (nFlags & 32) - UIntChangeBit(nFlags, 4); - - pFontDescriptor->Add("Flags", nFlags); - - CArrayObject* pBBox = new CArrayObject(); - int* pFontBBox = m_pFontFile->GetBBox(); - pBBox->Add(pFontBBox[0]); - pBBox->Add(pFontBBox[1]); - pBBox->Add(pFontBBox[2]); - pBBox->Add(pFontBBox[3]); - pFontDescriptor->Add("FontBBox", pBBox); - pFontDescriptor->Add("ItalicAngle", 0); - pFontDescriptor->Add("Ascent", m_pFontFile->GetAscent()); - pFontDescriptor->Add("Descent", m_pFontFile->GetDescent()); - pFontDescriptor->Add("CapHeight", m_pFontFile->GetCapHeight()); - pFontDescriptor->Add("StemV", 0); - pFontDescriptor->Add("FontWeight", m_pFontFile->GetWeight()); - - m_pFontFileDict = new CDictObject(m_pXref); - pFontDescriptor->Add("FontFile2", m_pFontFileDict); - - pFont->Add("FontDescriptor", pFontDescriptor); - - CDictObject* pCIDToGIDMapDict = new CDictObject(m_pXref); - pFont->Add("CIDToGIDMap", pCIDToGIDMapDict); - pCIDToGIDMapDict->SetFilter(STREAM_FILTER_FLATE_DECODE); - m_pCidToGidMapStream = pCIDToGIDMapDict->GetStream(); - - if (m_pXref->IsPDFA()) - { - pFontDescriptor->Add("CIDSet", new CDictObject(m_pXref)); - } - } - bool CFontCidTrueType::HaveChar(const unsigned int &unUnicode) - { - if (!OpenFontFace()) - return false; - - return (!!GetGID(m_pFace, unUnicode)); - } - unsigned int CFontCidTrueType::GetWidth(unsigned short ushCode) - { - if (ushCode >= m_vWidths.size()) - return 0; - - return m_vWidths.at(ushCode); - } - unsigned int CFontCidTrueType::GetGlyphWidth(unsigned short ushCode) - { - if (ushCode >= m_vGlypWidths.size()) - return 0; - - return m_vGlypWidths.at(ushCode); - } - bool CFontCidTrueType::IsItalic() - { - if (!OpenFontFace() || !m_pFace) - return false; - - return ((m_pFace->style_flags & FT_STYLE_FLAG_ITALIC) != 0); - } - bool CFontCidTrueType::IsBold() - { - if (!OpenFontFace() || !m_pFace) - return false; - - TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(m_pFace, ft_sfnt_os2); - if (pOS2 && pOS2->version != 0xFFFF && pOS2->usWeightClass >= 800) - return true; - - return ((m_pFace->style_flags & FT_STYLE_FLAG_BOLD) != 0); - } - void CFontCidTrueType::BeforeWrite() - { - if (m_pFontDescriptor) - { - CDictObject* pCIDSet = (CDictObject*)m_pFontDescriptor->Get("CIDSet"); - if (pCIDSet) - { -#ifndef FILTER_FLATE_DECODE_DISABLED - pCIDSet->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif - CStream* pStream = pCIDSet->GetStream(); - - unsigned int unBytes = (m_ushCodesCount) / 8; - - if (unBytes * 8 < m_ushCodesCount) - unBytes++; - - if (1 == unBytes) - { - BYTE nValue = 0xFF; - nValue = (BYTE)(nValue << (8 - m_ushCodesCount)); - nValue &= 0x7F; - pStream->WriteChar(nValue); - } - else - { - BYTE nStartValue = 0x7F, nMidValue = 0xFF; - pStream->WriteChar(nStartValue); - - for (unsigned int unIndex = 0; unIndex < unBytes - 2; ++unIndex) - { - pStream->WriteChar(nMidValue); - } - - BYTE nEndValue = 0xFF; - nEndValue = (BYTE)(nEndValue << (unBytes * 8 - m_ushCodesCount)); - - pStream->WriteChar(nEndValue); - } - } - } - - if (m_pFontFile) - { - unsigned short* pCodeToGid; - unsigned int* pWidths; - unsigned char* pGlyphs; - unsigned int unGlyphsCount; - - if (!GetWidthsAndGids(&pCodeToGid, &pWidths, &pGlyphs, unGlyphsCount)) - return; - - CStream* pStream = m_pFontFileDict->GetStream(); - m_pFontFile->WriteTTF(pStream, NULL, pCodeToGid, m_ushCodesCount, pGlyphs, unGlyphsCount); - m_pFontFileDict->Add("Length1", pStream->Size()); - m_pFontFileDict->SetFilter(STREAM_FILTER_FLATE_DECODE); - - CArrayObject* pWArray = new CArrayObject(); - m_pFont->Add("W", pWArray); - pWArray->Add(0); - CArrayObject* pWidthsArray = new CArrayObject(); - pWArray->Add(pWidthsArray); - for (unsigned short ushIndex = 0; ushIndex < m_ushCodesCount; ushIndex++) - { - pWidthsArray->Add(pWidths[ushIndex]); - } - - pStream = m_pCidToGidMapStream; - for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) - { - unsigned short ushGid = pCodeToGid[ushCode]; - pStream->WriteChar(((ushGid >> 8) & 0xFF)); - pStream->WriteChar((ushGid & 0xFF)); - } - - RELEASEARRAYOBJECTS(pCodeToGid); - RELEASEARRAYOBJECTS(pWidths); - RELEASEARRAYOBJECTS(pGlyphs); - - WriteToUnicode(); - } - } - bool CFontCidTrueType::GetWidthsAndGids(unsigned short** ppCodeToGid, unsigned int** ppWidths, unsigned char** ppGlyphs, unsigned int& unGlyphsCount) - { - *ppCodeToGid = NULL; - *ppWidths = NULL; - *ppGlyphs = NULL; - unGlyphsCount = 0; - - if (!m_nGlyphsCount) - return false; - - unsigned short* pCodeToGID = new unsigned short[m_ushCodesCount]; - if (!pCodeToGID) - return false; - - unsigned int* pWidths = new unsigned int[m_ushCodesCount]; - if (!pWidths) - { - delete[] pCodeToGID; - return false; - } - memset((void*)pWidths, 0x00, m_ushCodesCount * sizeof(unsigned int)); - - for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) - { - pCodeToGID[ushCode] = m_vCodeToGid.at(ushCode); - pWidths[ushCode] = m_vWidths.at(ushCode); - } - - unsigned char *pGlyphs = new unsigned char[m_nGlyphsCount]; - if (!pGlyphs) - { - delete[] pCodeToGID; - delete[] pWidths; - return false; - } - - memset((void *)pGlyphs, 0x00, m_nGlyphsCount * sizeof(unsigned char)); - for (auto oIt : m_mGlyphs) - { - pGlyphs[oIt.first] = 1; - } - - *ppCodeToGid = pCodeToGID; - *ppWidths = pWidths; - *ppGlyphs = pGlyphs; - unGlyphsCount = m_nGlyphsCount; - return true; - } - void CFontCidTrueType::WriteToUnicode() - { - CStream* pS = m_pToUnicodeStream; - - pS->WriteStr(c_sToUnicodeHeader); - pS->WriteStr(c_sToUnicodeInfo); - - pS->WriteInt(m_ushCodesCount); - pS->WriteStr(" beginbfchar\n"); - for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) - { - pS->WriteChar('<'); - pS->WriteHex(ushCode, 4); - pS->WriteStr("> <"); - for (unsigned int i = 0, nLen = m_vUnicodes[ushCode].size(); i < nLen; i++) - { - unsigned int unUnicode = m_vUnicodes[ushCode][i]; - if (unUnicode < 0x10000) - { - pS->WriteHex(unUnicode, 4); - } - else - { - unUnicode = unUnicode - 0x10000; - - unsigned short ushLo = 0xDC00 | (unUnicode & 0x3FF); - unsigned short ushHi = 0xD800 | (unUnicode >> 10); - - pS->WriteHex(ushHi, 4); - pS->WriteHex(ushLo, 4); - } - } - - pS->WriteStr(">\n"); - } - pS->WriteStr("endbfchar\n"); - m_pToUnicodeStream->WriteStr(c_sToUnicodeFooter); - } - void CFontCidTrueType::CloseFontFace() - { - if (m_pFace) - { - FT_Done_Face(m_pFace); - m_pFace = NULL; - } - - RELEASEARRAYOBJECTS(m_pFaceMemory); - } - bool CFontCidTrueType::OpenFontFace() - { - if (m_pFace) - { - m_pDocument->AddFreeTypeFont(this); - return true; - } - - m_nGlyphsCount = 0; - m_nSymbolicCmap = -1; - - FT_Library pLibrary = m_pDocument->GetFreeTypeLibrary(); - if (!pLibrary) - return false; - - DWORD dwFileSize; - m_pFaceMemory = NULL; - NSFile::CFileBinary::ReadAllBytes(m_wsFontPath, &m_pFaceMemory, dwFileSize); - if (!m_pFaceMemory) - return false; - - FT_New_Memory_Face(pLibrary, m_pFaceMemory, dwFileSize, m_unFontIndex, &m_pFace); - - if (!m_pFace) - { - RELEASEARRAYOBJECTS(m_pFaceMemory); - return false; - } - - m_pDocument->AddFreeTypeFont(this); - m_nGlyphsCount = m_pFace->num_glyphs; - m_nSymbolicCmap = GetSymbolicCmapIndex(m_pFace); - - if (m_bNeedAddFontName) - { - // Дописываем имя шрифта во все необходимые словари, а также заполняем дескриптор - std::string sFontName = m_pDocument->GetTTFontTag(); - sFontName += (m_pFace->family_name ? std::string(m_pFace->family_name) : std::string()); - if (m_pFace->style_flags & FT_STYLE_FLAG_ITALIC) - sFontName += "-Italic"; - if (m_pFace->style_flags & FT_STYLE_FLAG_BOLD) - sFontName += "-Bold"; - - const char* sName = sFontName.c_str(); - - Add("BaseFont", sName); - m_pFont->Add("BaseFont", sName); - m_pFontDescriptor->Add("FontName", sName); - m_bNeedAddFontName = false; - } - - return true; - } - unsigned short CFontCidTrueType::EncodeUnicode(const unsigned int &unUnicode) - { - std::map::const_iterator oIter = m_mUnicodeToCode.find(unUnicode); - if (oIter != m_mUnicodeToCode.end()) - return oIter->second; - - unsigned int unGID = GetGID(m_pFace, unUnicode); - if (0 == unGID && -1 != m_nSymbolicCmap) - unGID = GetGID(m_pFace, unUnicode + 0xF000); - - unsigned short ushCode = EncodeGID(unGID, &unUnicode, 1); - m_mUnicodeToCode.insert(std::pair(unUnicode, ushCode)); - return ushCode; - } - unsigned short CFontCidTrueType::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unCount) - { - for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) - { - if (unGID == m_vCodeToGid.at(ushCurCode)) - return ushCurCode; - } - - if (!OpenFontFace()) - return 0; - - unsigned short ushCode = m_ushCodesCount++; - - std::vector vUnicodes; - for (unsigned int i = 0; i < unCount; i++) - { - vUnicodes.push_back(pUnicodes[i]); - } - - m_vUnicodes.push_back(vUnicodes); - m_vCodeToGid.push_back(unGID); - - m_mGlyphs.insert(std::pair(unGID, true)); - - // Если данный символ составной (CompositeGlyf), тогда мы должны учесть все его дочерные символы (subglyfs) - if (0 == FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE)) - { - for (int nSubIndex = 0; nSubIndex < m_pFace->glyph->num_subglyphs; nSubIndex++) - { - FT_Int nSubGID; - FT_UInt unFlags; - FT_Int nArg1; - FT_Int nArg2; - FT_Matrix oMatrix; - FT_Get_SubGlyph_Info(m_pFace->glyph, nSubIndex, &nSubGID, &unFlags, &nArg1, &nArg2, &oMatrix); - - m_mGlyphs.insert(std::pair(nSubGID, true)); - } - - if (0 != m_pFace->units_per_EM) - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); - } - else - { - m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); - m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); - } - } - else - { - m_vWidths.push_back(0); - m_vGlypWidths.push_back(0); - } - - return ushCode; - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "FontCidTT.h" +#include "Document.h" +#include "Streams.h" +#include "Utils.h" +#include "FontTTWriter.h" + +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/common/File.h" + +#include + +#include FT_TRUETYPE_TABLES_H + +namespace PdfWriter +{ + static const char* c_sToUnicodeHeader = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n"; + static const char* c_sToUnicodeInfo = "/CIDSystemInfo\n<< /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n >> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000> \nendcodespacerange\n"; + static const char* c_sToUnicodeFooter = "endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend\n"; + + static int GetSymbolicCmapIndex(FT_Face pFace) + { + TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2); + if (NULL == pOs2 || 0xFFFF == pOs2->version) + return -1; + + // Проверяем установлен ли 31 бит + if (!(pOs2->ulCodePageRange1 & 0x80000000) && !(pOs2->ulCodePageRange1 == 0 && pOs2->ulCodePageRange2 == 0)) + return -1; + + + for (int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++) + { + // Symbol + if (0 == pFace->charmaps[nIndex]->encoding_id && 3 == pFace->charmaps[nIndex]->platform_id) + return nIndex; + } + + return -1; + } + //---------------------------------------------------------------------------------------- + // CFontFileBase + //---------------------------------------------------------------------------------------- + CFontCidTrueType::CFontCidTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex) : CFontDict(pXref, pDocument) + { + m_bNeedAddFontName = true; + CFontFileTrueType* pFontTT = CFontFileTrueType::LoadFromFile(wsFontPath, unIndex); + m_pFontFile = pFontTT; + + m_wsFontPath = wsFontPath; + m_unFontIndex = unIndex; + + Add("Type", "Font"); + Add("Subtype", "Type0"); + Add("Encoding", "Identity-H"); + + CDictObject* pFont = new CDictObject(); + m_pXref->Add(pFont); + + CArrayObject* pDescendantFonts = new CArrayObject(); + pDescendantFonts->Add(pFont); + + Add("DescendantFonts", pDescendantFonts); + CDictObject* pToUnicodeDict = new CDictObject(m_pXref); + Add("ToUnicode", pToUnicodeDict); + pToUnicodeDict->SetFilter(STREAM_FILTER_FLATE_DECODE); + m_pToUnicodeStream = pToUnicodeDict->GetStream(); + + CreateCIDFont2(pFont); + + m_pFace = NULL; + m_pFaceMemory = NULL; + m_nGlyphsCount = 0; + m_nSymbolicCmap = -1; + m_ushCodesCount = 0; + } + CFontCidTrueType::~CFontCidTrueType() + { + if (m_pFontFile) + delete m_pFontFile; + + if (m_pFace) + FT_Done_Face(m_pFace); + + if (m_pFaceMemory) + delete[] m_pFaceMemory; + } + void CFontCidTrueType::CreateCIDFont2(CDictObject* pFont) + { + m_pFont = pFont; + pFont->Add("Type", "Font"); + pFont->Add("Subtype", "CIDFontType2"); + + CDictObject* pSystemInfo = new CDictObject(); + pSystemInfo->Add("Registry", new CStringObject("Adobe")); + pSystemInfo->Add("Ordering", new CStringObject("Identity")); + pSystemInfo->Add("Supplement", 0); + + pFont->Add("CIDSystemInfo", pSystemInfo); + + CDictObject* pFontDescriptor = new CDictObject(); + // FontDescriptor обязательно должен идти ссылкой + m_pXref->Add(pFontDescriptor); + pFontDescriptor->Add("Type", "FontDescriptor"); + m_pFontDescriptor = pFontDescriptor; + + // Выставляем бит Symbolic, а бит NonSymbolic убираем + unsigned int nFlags = 0; + if (!(nFlags & 4)) + UIntChangeBit(nFlags, 2); + if (nFlags & 32) + UIntChangeBit(nFlags, 4); + + pFontDescriptor->Add("Flags", nFlags); + + CArrayObject* pBBox = new CArrayObject(); + int* pFontBBox = m_pFontFile->GetBBox(); + pBBox->Add(pFontBBox[0]); + pBBox->Add(pFontBBox[1]); + pBBox->Add(pFontBBox[2]); + pBBox->Add(pFontBBox[3]); + pFontDescriptor->Add("FontBBox", pBBox); + pFontDescriptor->Add("ItalicAngle", 0); + pFontDescriptor->Add("Ascent", m_pFontFile->GetAscent()); + pFontDescriptor->Add("Descent", m_pFontFile->GetDescent()); + pFontDescriptor->Add("CapHeight", m_pFontFile->GetCapHeight()); + pFontDescriptor->Add("StemV", 0); + pFontDescriptor->Add("FontWeight", m_pFontFile->GetWeight()); + + m_pFontFileDict = new CDictObject(m_pXref); + pFontDescriptor->Add("FontFile2", m_pFontFileDict); + + pFont->Add("FontDescriptor", pFontDescriptor); + + CDictObject* pCIDToGIDMapDict = new CDictObject(m_pXref); + pFont->Add("CIDToGIDMap", pCIDToGIDMapDict); + pCIDToGIDMapDict->SetFilter(STREAM_FILTER_FLATE_DECODE); + m_pCidToGidMapStream = pCIDToGIDMapDict->GetStream(); + + if (m_pXref->IsPDFA()) + { + pFontDescriptor->Add("CIDSet", new CDictObject(m_pXref)); + } + } + bool CFontCidTrueType::HaveChar(const unsigned int &unUnicode) + { + if (!OpenFontFace()) + return false; + + return (!!GetGID(m_pFace, unUnicode)); + } + unsigned int CFontCidTrueType::GetWidth(unsigned short ushCode) + { + if (ushCode >= m_vWidths.size()) + return 0; + + return m_vWidths.at(ushCode); + } + unsigned int CFontCidTrueType::GetGlyphWidth(unsigned short ushCode) + { + if (ushCode >= m_vGlypWidths.size()) + return 0; + + return m_vGlypWidths.at(ushCode); + } + bool CFontCidTrueType::IsItalic() + { + if (!OpenFontFace() || !m_pFace) + return false; + + return ((m_pFace->style_flags & FT_STYLE_FLAG_ITALIC) != 0); + } + bool CFontCidTrueType::IsBold() + { + if (!OpenFontFace() || !m_pFace) + return false; + + TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(m_pFace, ft_sfnt_os2); + if (pOS2 && pOS2->version != 0xFFFF && pOS2->usWeightClass >= 800) + return true; + + return ((m_pFace->style_flags & FT_STYLE_FLAG_BOLD) != 0); + } + void CFontCidTrueType::BeforeWrite() + { + if (m_pFontDescriptor) + { + CDictObject* pCIDSet = (CDictObject*)m_pFontDescriptor->Get("CIDSet"); + if (pCIDSet) + { +#ifndef FILTER_FLATE_DECODE_DISABLED + pCIDSet->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + CStream* pStream = pCIDSet->GetStream(); + + unsigned int unBytes = (m_ushCodesCount) / 8; + + if (unBytes * 8 < m_ushCodesCount) + unBytes++; + + if (1 == unBytes) + { + BYTE nValue = 0xFF; + nValue = (BYTE)(nValue << (8 - m_ushCodesCount)); + nValue &= 0x7F; + pStream->WriteChar(nValue); + } + else + { + BYTE nStartValue = 0x7F, nMidValue = 0xFF; + pStream->WriteChar(nStartValue); + + for (unsigned int unIndex = 0; unIndex < unBytes - 2; ++unIndex) + { + pStream->WriteChar(nMidValue); + } + + BYTE nEndValue = 0xFF; + nEndValue = (BYTE)(nEndValue << (unBytes * 8 - m_ushCodesCount)); + + pStream->WriteChar(nEndValue); + } + } + } + + if (m_pFontFile) + { + unsigned short* pCodeToGid; + unsigned int* pWidths; + unsigned char* pGlyphs; + unsigned int unGlyphsCount; + + if (!GetWidthsAndGids(&pCodeToGid, &pWidths, &pGlyphs, unGlyphsCount)) + return; + + CStream* pStream = m_pFontFileDict->GetStream(); + m_pFontFile->WriteTTF(pStream, NULL, pCodeToGid, m_ushCodesCount, pGlyphs, unGlyphsCount); + m_pFontFileDict->Add("Length1", pStream->Size()); + m_pFontFileDict->SetFilter(STREAM_FILTER_FLATE_DECODE); + + CArrayObject* pWArray = new CArrayObject(); + m_pFont->Add("W", pWArray); + pWArray->Add(0); + CArrayObject* pWidthsArray = new CArrayObject(); + pWArray->Add(pWidthsArray); + for (unsigned short ushIndex = 0; ushIndex < m_ushCodesCount; ushIndex++) + { + pWidthsArray->Add(pWidths[ushIndex]); + } + + pStream = m_pCidToGidMapStream; + for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) + { + unsigned short ushGid = pCodeToGid[ushCode]; + pStream->WriteChar(((ushGid >> 8) & 0xFF)); + pStream->WriteChar((ushGid & 0xFF)); + } + + RELEASEARRAYOBJECTS(pCodeToGid); + RELEASEARRAYOBJECTS(pWidths); + RELEASEARRAYOBJECTS(pGlyphs); + + WriteToUnicode(); + } + } + bool CFontCidTrueType::GetWidthsAndGids(unsigned short** ppCodeToGid, unsigned int** ppWidths, unsigned char** ppGlyphs, unsigned int& unGlyphsCount) + { + *ppCodeToGid = NULL; + *ppWidths = NULL; + *ppGlyphs = NULL; + unGlyphsCount = 0; + + if (!m_nGlyphsCount) + return false; + + unsigned short* pCodeToGID = new unsigned short[m_ushCodesCount]; + if (!pCodeToGID) + return false; + + unsigned int* pWidths = new unsigned int[m_ushCodesCount]; + if (!pWidths) + { + delete[] pCodeToGID; + return false; + } + memset((void*)pWidths, 0x00, m_ushCodesCount * sizeof(unsigned int)); + + for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) + { + pCodeToGID[ushCode] = m_vCodeToGid.at(ushCode); + pWidths[ushCode] = m_vWidths.at(ushCode); + } + + unsigned char *pGlyphs = new unsigned char[m_nGlyphsCount]; + if (!pGlyphs) + { + delete[] pCodeToGID; + delete[] pWidths; + return false; + } + + memset((void *)pGlyphs, 0x00, m_nGlyphsCount * sizeof(unsigned char)); + for (auto oIt : m_mGlyphs) + { + pGlyphs[oIt.first] = 1; + } + + *ppCodeToGid = pCodeToGID; + *ppWidths = pWidths; + *ppGlyphs = pGlyphs; + unGlyphsCount = m_nGlyphsCount; + return true; + } + void CFontCidTrueType::WriteToUnicode() + { + CStream* pS = m_pToUnicodeStream; + + pS->WriteStr(c_sToUnicodeHeader); + pS->WriteStr(c_sToUnicodeInfo); + + pS->WriteInt(m_ushCodesCount); + pS->WriteStr(" beginbfchar\n"); + for (unsigned short ushCode = 0; ushCode < m_ushCodesCount; ushCode++) + { + pS->WriteChar('<'); + pS->WriteHex(ushCode, 4); + pS->WriteStr("> <"); + for (unsigned int i = 0, nLen = m_vUnicodes[ushCode].size(); i < nLen; i++) + { + unsigned int unUnicode = m_vUnicodes[ushCode][i]; + if (unUnicode < 0x10000) + { + pS->WriteHex(unUnicode, 4); + } + else + { + unUnicode = unUnicode - 0x10000; + + unsigned short ushLo = 0xDC00 | (unUnicode & 0x3FF); + unsigned short ushHi = 0xD800 | (unUnicode >> 10); + + pS->WriteHex(ushHi, 4); + pS->WriteHex(ushLo, 4); + } + } + + pS->WriteStr(">\n"); + } + pS->WriteStr("endbfchar\n"); + m_pToUnicodeStream->WriteStr(c_sToUnicodeFooter); + } + void CFontCidTrueType::CloseFontFace() + { + if (m_pFace) + { + FT_Done_Face(m_pFace); + m_pFace = NULL; + } + + RELEASEARRAYOBJECTS(m_pFaceMemory); + } + bool CFontCidTrueType::OpenFontFace() + { + if (m_pFace) + { + m_pDocument->AddFreeTypeFont(this); + return true; + } + + m_nGlyphsCount = 0; + m_nSymbolicCmap = -1; + + FT_Library pLibrary = m_pDocument->GetFreeTypeLibrary(); + if (!pLibrary) + return false; + + DWORD dwFileSize; + m_pFaceMemory = NULL; + NSFile::CFileBinary::ReadAllBytes(m_wsFontPath, &m_pFaceMemory, dwFileSize); + if (!m_pFaceMemory) + return false; + + FT_New_Memory_Face(pLibrary, m_pFaceMemory, dwFileSize, m_unFontIndex, &m_pFace); + + if (!m_pFace) + { + RELEASEARRAYOBJECTS(m_pFaceMemory); + return false; + } + + m_pDocument->AddFreeTypeFont(this); + m_nGlyphsCount = m_pFace->num_glyphs; + m_nSymbolicCmap = GetSymbolicCmapIndex(m_pFace); + + if (m_bNeedAddFontName) + { + // Дописываем имя шрифта во все необходимые словари, а также заполняем дескриптор + std::string sFontName = m_pDocument->GetTTFontTag(); + sFontName += (m_pFace->family_name ? std::string(m_pFace->family_name) : std::string()); + if (m_pFace->style_flags & FT_STYLE_FLAG_ITALIC) + sFontName += "-Italic"; + if (m_pFace->style_flags & FT_STYLE_FLAG_BOLD) + sFontName += "-Bold"; + + const char* sName = sFontName.c_str(); + + Add("BaseFont", sName); + m_pFont->Add("BaseFont", sName); + m_pFontDescriptor->Add("FontName", sName); + m_bNeedAddFontName = false; + } + + return true; + } + unsigned short CFontCidTrueType::EncodeUnicode(const unsigned int &unUnicode) + { + std::map::const_iterator oIter = m_mUnicodeToCode.find(unUnicode); + if (oIter != m_mUnicodeToCode.end()) + return oIter->second; + + unsigned int unGID = GetGID(m_pFace, unUnicode); + if (0 == unGID && -1 != m_nSymbolicCmap) + unGID = GetGID(m_pFace, unUnicode + 0xF000); + + unsigned short ushCode = EncodeGID(unGID, &unUnicode, 1); + m_mUnicodeToCode.insert(std::pair(unUnicode, ushCode)); + return ushCode; + } + unsigned short CFontCidTrueType::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unCount) + { + for (unsigned short ushCurCode = 0, ushCodesCount = m_vCodeToGid.size(); ushCurCode < ushCodesCount; ushCurCode++) + { + if (unGID == m_vCodeToGid.at(ushCurCode)) + return ushCurCode; + } + + if (!OpenFontFace()) + return 0; + + unsigned short ushCode = m_ushCodesCount++; + + std::vector vUnicodes; + for (unsigned int i = 0; i < unCount; i++) + { + vUnicodes.push_back(pUnicodes[i]); + } + + m_vUnicodes.push_back(vUnicodes); + m_vCodeToGid.push_back(unGID); + + m_mGlyphs.insert(std::pair(unGID, true)); + + // Если данный символ составной (CompositeGlyf), тогда мы должны учесть все его дочерные символы (subglyfs) + if (0 == FT_Load_Glyph(m_pFace, unGID, FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE)) + { + for (int nSubIndex = 0; nSubIndex < m_pFace->glyph->num_subglyphs; nSubIndex++) + { + FT_Int nSubGID; + FT_UInt unFlags; + FT_Int nArg1; + FT_Int nArg2; + FT_Matrix oMatrix; + FT_Get_SubGlyph_Info(m_pFace->glyph, nSubIndex, &nSubGID, &unFlags, &nArg1, &nArg2, &oMatrix); + + m_mGlyphs.insert(std::pair(nSubGID, true)); + } + + if (0 != m_pFace->units_per_EM) + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance * 1000 / m_pFace->units_per_EM); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + else + { + m_vWidths.push_back((unsigned int)m_pFace->glyph->metrics.horiAdvance); + m_vGlypWidths.push_back((unsigned int)(m_pFace->glyph->metrics.width) * 1000 / m_pFace->units_per_EM); + } + } + else + { + m_vWidths.push_back(0); + m_vGlypWidths.push_back(0); + } + + return ushCode; + } +} diff --git a/PdfWriter/Src/FontCidTT.h b/PdfFile/SrcWriter/FontCidTT.h similarity index 97% rename from PdfWriter/Src/FontCidTT.h rename to PdfFile/SrcWriter/FontCidTT.h index a622d55d23..4f6549e2ea 100644 --- a/PdfWriter/Src/FontCidTT.h +++ b/PdfFile/SrcWriter/FontCidTT.h @@ -1,157 +1,157 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_FONTCIDTT_H -#define _PDF_WRITER_SRC_FONTCIDTT_H - -#include "Font.h" -#include "Objects.h" -#include -#include -#include - -#include "../../DesktopEditor/common/File.h" - -#include -#include FT_TRUETYPE_TABLES_H - -namespace PdfWriter -{ - static unsigned int GetGID(FT_Face pFace, unsigned int unUnicode) - { - int nCharIndex = 0; - - if (!pFace) - return nCharIndex; - - for (int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++) - { - FT_CharMap pCharMap = pFace->charmaps[nIndex]; - - if (FT_Set_Charmap(pFace, pCharMap)) - continue; - FT_Encoding pEncoding = pCharMap->encoding; - - if (FT_ENCODING_UNICODE == pEncoding) - { - if (nCharIndex = FT_Get_Char_Index(pFace, unUnicode)) - return nCharIndex; - } - - if (FT_ENCODING_NONE == pEncoding || FT_ENCODING_MS_SYMBOL == pEncoding || FT_ENCODING_APPLE_ROMAN == pEncoding) - { - nCharIndex = FT_Get_Char_Index(pFace, unUnicode); - } - /*else if ( FT_ENCODING_ADOBE_STANDARD == pEncoding ) - { - nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); - } - else if ( FT_ENCODING_ADOBE_CUSTOM == pEncoding ) - { - nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); - } - else if ( FT_ENCODING_ADOBE_EXPERT == pEncoding ) - { - nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); - }*/ - } - - return nCharIndex; - } - - - class CXref; - class CStream; - class CFontFileTrueType; - class CDocument; - //---------------------------------------------------------------------------------------- - // CFontFileBase - //---------------------------------------------------------------------------------------- - class CFontCidTrueType : public CFontDict - { - public: - - CFontCidTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex); - ~CFontCidTrueType(); - unsigned short EncodeUnicode(const unsigned int& unUnicode); - unsigned short EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unCount); - - bool HaveChar(const unsigned int& unUnicode); - unsigned int GetWidth(unsigned short ushCode); - unsigned int GetGlyphWidth(unsigned short ushCode); - bool IsItalic(); - bool IsBold(); - EFontType GetFontType() - { - return fontCIDType2; - } - - private: - - void BeforeWrite(); - bool GetWidthsAndGids(unsigned short** ppCodeToGid, unsigned int** pWidths, unsigned char** ppGlyphs, unsigned int& unGlyphsCount); - void CreateCIDFont2(CDictObject* pFont); - void WriteToUnicode(); - bool OpenFontFace(); - void CloseFontFace(); - - private: - - std::wstring m_wsFontPath; - unsigned int m_unFontIndex; - - CFontFileTrueType* m_pFontFile; - CDictObject* m_pFontFileDict; - CStream* m_pCidToGidMapStream; - CStream* m_pToUnicodeStream; - CDictObject* m_pFont; - CDictObject* m_pFontDescriptor; - - unsigned short m_ushCodesCount; // Количество закодированных символов - std::map m_mUnicodeToCode; // Мап Юникод->код символа - std::vector> m_vUnicodes; // Обратный мап код символа -> юникодЫ - - std::vector m_vCodeToGid; - std::vector m_vWidths; // glyph.advance - std::map m_mGlyphs; - std::vector m_vGlypWidths; // glyph.width - - FT_Face m_pFace; - FT_Byte* m_pFaceMemory; - int m_nGlyphsCount; - int m_nSymbolicCmap; - bool m_bNeedAddFontName; - - friend class CDocument; - }; -} - -#endif // _PDF_WRITER_SRC_FONTCIDTT_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_FONTCIDTT_H +#define _PDF_WRITER_SRC_FONTCIDTT_H + +#include "Font.h" +#include "Objects.h" +#include +#include +#include + +#include "../../DesktopEditor/common/File.h" + +#include +#include FT_TRUETYPE_TABLES_H + +namespace PdfWriter +{ + static unsigned int GetGID(FT_Face pFace, unsigned int unUnicode) + { + int nCharIndex = 0; + + if (!pFace) + return nCharIndex; + + for (int nIndex = 0; nIndex < pFace->num_charmaps; nIndex++) + { + FT_CharMap pCharMap = pFace->charmaps[nIndex]; + + if (FT_Set_Charmap(pFace, pCharMap)) + continue; + FT_Encoding pEncoding = pCharMap->encoding; + + if (FT_ENCODING_UNICODE == pEncoding) + { + if (nCharIndex = FT_Get_Char_Index(pFace, unUnicode)) + return nCharIndex; + } + + if (FT_ENCODING_NONE == pEncoding || FT_ENCODING_MS_SYMBOL == pEncoding || FT_ENCODING_APPLE_ROMAN == pEncoding) + { + nCharIndex = FT_Get_Char_Index(pFace, unUnicode); + } + /*else if ( FT_ENCODING_ADOBE_STANDARD == pEncoding ) + { + nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); + } + else if ( FT_ENCODING_ADOBE_CUSTOM == pEncoding ) + { + nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); + } + else if ( FT_ENCODING_ADOBE_EXPERT == pEncoding ) + { + nCharIndex = FT_Get_Char_Index( pFace, unUnicode ); + }*/ + } + + return nCharIndex; + } + + + class CXref; + class CStream; + class CFontFileTrueType; + class CDocument; + //---------------------------------------------------------------------------------------- + // CFontFileBase + //---------------------------------------------------------------------------------------- + class CFontCidTrueType : public CFontDict + { + public: + + CFontCidTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex); + ~CFontCidTrueType(); + unsigned short EncodeUnicode(const unsigned int& unUnicode); + unsigned short EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unCount); + + bool HaveChar(const unsigned int& unUnicode); + unsigned int GetWidth(unsigned short ushCode); + unsigned int GetGlyphWidth(unsigned short ushCode); + bool IsItalic(); + bool IsBold(); + EFontType GetFontType() + { + return fontCIDType2; + } + + private: + + void BeforeWrite(); + bool GetWidthsAndGids(unsigned short** ppCodeToGid, unsigned int** pWidths, unsigned char** ppGlyphs, unsigned int& unGlyphsCount); + void CreateCIDFont2(CDictObject* pFont); + void WriteToUnicode(); + bool OpenFontFace(); + void CloseFontFace(); + + private: + + std::wstring m_wsFontPath; + unsigned int m_unFontIndex; + + CFontFileTrueType* m_pFontFile; + CDictObject* m_pFontFileDict; + CStream* m_pCidToGidMapStream; + CStream* m_pToUnicodeStream; + CDictObject* m_pFont; + CDictObject* m_pFontDescriptor; + + unsigned short m_ushCodesCount; // Количество закодированных символов + std::map m_mUnicodeToCode; // Мап Юникод->код символа + std::vector> m_vUnicodes; // Обратный мап код символа -> юникодЫ + + std::vector m_vCodeToGid; + std::vector m_vWidths; // glyph.advance + std::map m_mGlyphs; + std::vector m_vGlypWidths; // glyph.width + + FT_Face m_pFace; + FT_Byte* m_pFaceMemory; + int m_nGlyphsCount; + int m_nSymbolicCmap; + bool m_bNeedAddFontName; + + friend class CDocument; + }; +} + +#endif // _PDF_WRITER_SRC_FONTCIDTT_H diff --git a/PdfWriter/Src/FontTT.cpp b/PdfFile/SrcWriter/FontTT.cpp similarity index 100% rename from PdfWriter/Src/FontTT.cpp rename to PdfFile/SrcWriter/FontTT.cpp diff --git a/PdfWriter/Src/FontTT.h b/PdfFile/SrcWriter/FontTT.h similarity index 100% rename from PdfWriter/Src/FontTT.h rename to PdfFile/SrcWriter/FontTT.h diff --git a/PdfWriter/Src/FontTTWriter.cpp b/PdfFile/SrcWriter/FontTTWriter.cpp similarity index 96% rename from PdfWriter/Src/FontTTWriter.cpp rename to PdfFile/SrcWriter/FontTTWriter.cpp index 2088cfde20..90434b2fcf 100644 --- a/PdfWriter/Src/FontTTWriter.cpp +++ b/PdfFile/SrcWriter/FontTTWriter.cpp @@ -1,1236 +1,1236 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "FontTTWriter.h" -#include "../../DesktopEditor/common/File.h" - -#define ttcfTag 0x74746366 -#define cmapTag 0x636d6170 -#define glyfTag 0x676c7966 -#define headTag 0x68656164 -#define hheaTag 0x68686561 -#define hmtxTag 0x686d7478 -#define locaTag 0x6c6f6361 -#define nameTag 0x6e616d65 -#define os2Tag 0x4f532f32 -#define postTag 0x706f7374 - -#define cvtTag 0x63767420 -#define fpgmTag 0x6670676d -#define maxpTag 0x6d617870 -#define prepTag 0x70726570 - -namespace PdfWriter -{ - struct TrueTypeTable - { - unsigned int unTag; - unsigned int unChecksum; - int nOffset; - int nOrigOffset; - int nLen; - }; - struct TrueTypeCmap - { - int nPlatform; - int nEncoding; - int nOffset; - int nLen; - int nFormat; - }; - struct TrueTypeLoca - { - int nIndex; - int nOrigOffset; - int nNewOffset; - int nLen; - }; - static int CompareTrueTypeLocaOffset(const void *pL1, const void *pL2) - { - TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; - TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; - - if (pLoca1->nOrigOffset == pLoca2->nOrigOffset) - return pLoca1->nIndex - pLoca2->nIndex; - - return pLoca1->nOrigOffset - pLoca2->nOrigOffset; - } - static int CompareTrueTypeLocaIndex(const void *pL1, const void *pL2) - { - TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; - TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; - - return pLoca1->nIndex - pLoca2->nIndex; - } - static int CompareTrueTypeTableTag(const void *pTab1, const void *pTab2) - { - TrueTypeTable *pTable1 = (TrueTypeTable *)pTab1; - TrueTypeTable *pTable2 = (TrueTypeTable *)pTab2; - - return (int)pTable1->unTag - (int)pTable2->unTag; - } - //---------------------------------------------------------------------------------------- - // CFontFileBase - //---------------------------------------------------------------------------------------- - CFontFileBase::CFontFileBase(char *sFile, int nLen, bool bFreeFileData) - { - m_sFileData = m_sFile = (unsigned char *)sFile; - m_nLen = nLen; - m_bFreeFileData = bFreeFileData; - } - CFontFileBase::~CFontFileBase() - { - if (m_bFreeFileData) - free(m_sFileData); - } - char* CFontFileBase::ReadFile(const std::wstring & wsFileName, int *pnFileLen) - { - NSFile::CFileBinary oFile; - - if (oFile.OpenFile(wsFileName) == false) - return NULL; - - int nLen = oFile.GetFileSize(); - DWORD nLenRead = 0; - - char *sBuffer = (char *)malloc(nLen); - if (NULL != sBuffer) - { - if ((int)oFile.ReadFile((BYTE*)sBuffer, nLen, nLenRead) == false) - { - if (sBuffer) - free(sBuffer); - - oFile.CloseFile(); - return NULL; - } - - oFile.CloseFile(); - *pnFileLen = nLen; - } - else - { - oFile.CloseFile(); - } - return sBuffer; - } - int CFontFileBase::GetS8(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - if (nRes & 0x80) - nRes |= ~0xff; - return nRes; - } - int CFontFileBase::GetU8(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - if (nPos < 0 || nPos >= m_nLen) - { - *pbSuccess = false; - return 0; - } - return m_sFile[nPos]; - } - int CFontFileBase::GetS16BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 1 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - if (nRes & 0x8000) - nRes |= ~0xffff; - return nRes; - } - int CFontFileBase::GetU16BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 1 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - return nRes; - } - int CFontFileBase::GetS32BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 3 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - nRes = (nRes << 8) + m_sFile[nPos + 2]; - nRes = (nRes << 8) + m_sFile[nPos + 3]; - if (nRes & 0x80000000) - nRes |= ~0xffffffff; - - return nRes; - } - unsigned int CFontFileBase::GetU32BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 3 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - unsigned int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - nRes = (nRes << 8) + m_sFile[nPos + 2]; - nRes = (nRes << 8) + m_sFile[nPos + 3]; - return nRes; - } - unsigned int CFontFileBase::GetUVarBE(int nPos, int nSize, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + nSize > m_nLen) - { - *pbSuccess = false; - return 0; - } - unsigned int nRes = 0; - for (int nIndex = 0; nIndex < nSize; ++nIndex) - nRes = (nRes << 8) + m_sFile[nPos + nIndex]; - - return nRes; - } - bool CFontFileBase::CheckRegion(int nPos, int nSize) - { - return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen); - } - //---------------------------------------------------------------------------------------- - // CFontFileTrueType - //---------------------------------------------------------------------------------------- - CFontFileTrueType::CFontFileTrueType(char *sBuffer, int nLen, bool bFreeFileData, unsigned int unFontIndex) :CFontFileBase(sBuffer, nLen, bFreeFileData) - { - m_pTables = NULL; - m_nTablesCount = 0; - m_pCMaps = NULL; - m_nCMapsCount = 0; - m_bSuccess = false; - m_unFontIndex = unFontIndex; - - m_nAscent = 1000; - m_nDescent = -500; - m_nCapHeight = 800; - - Parse(); - } - CFontFileTrueType* CFontFileTrueType::LoadFromBuffer(char *sBuffer, int nLen, unsigned int unIndex) - { - CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, false, unIndex); - if (!pTTF->m_bSuccess) - { - delete pTTF; - return NULL; - } - return pTTF; - } - CFontFileTrueType* CFontFileTrueType::LoadFromFile(const std::wstring& wsFileName, unsigned int unIndex) - { - char *sBuffer; - int nLen = 0; - - if (!(sBuffer = CFontFileBase::ReadFile(wsFileName, &nLen))) - return NULL; - - CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, true, unIndex); - if (!pTTF->m_bSuccess) - { - delete pTTF; - return NULL; - } - return pTTF; - } - CFontFileTrueType::~CFontFileTrueType() - { - if (m_pTables) - free(m_pTables); - - if (m_pCMaps) - free(m_pCMaps); - } - void CFontFileTrueType::WriteTTF(CStream* pOutputStream, char* sName, unsigned short* pCodeToGID, unsigned int unCodesCount, unsigned char* pUseGlyfs, long lGlyfsCount) - { - static char arrCMapTab[36] = - { - 0, 0, // table version number - 0, 1, // number of encoding tables - 0, 1, // platform ID - 0, 0, // encoding ID - 0, 0, 0, 12, // offset of subtable - 0, 4, // subtable format - 0, 24, // subtable length - 0, 0, // subtable version - 0, 2, // segment count * 2 - 0, 2, // 2 * 2 ^ floor(log2(segCount)) - 0, 0, // floor(log2(segCount)) - 0, 0, // 2*segCount - 2*2^floor(log2(segCount)) - (char)0xff, (char)0xff, // endCount[0] - 0, 0, // reserved - 0, 0, // startCount[0] - 0, 0, // idDelta[0] - 0, 0 // pad to a mulitple of four bytes - }; - - static char arrNameTab[8] = - { - 0, 0, // format - 0, 0, // number of name records - 0, 6, // offset to start of string storage - 0, 0 // pad to multiple of four bytes - }; - static char arrPostTab[32] = - { - 0, 1, 0, 0, // format - 0, 0, 0, 0, // italic angle - 0, 0, // underline position - 0, 0, // underline thickness - 0, 0, 0, 0, // fixed pitch - 0, 0, 0, 0, // min Type 42 memory - 0, 0, 0, 0, // max Type 42 memory - 0, 0, 0, 0, // min Type 1 memory - 0, 0, 0, 0 // max Type 1 memory - }; - static char arrOS2Tab[86] = - { - 0, 1, // version - 0, 1, // xAvgCharWidth - 0, 0, // usWeightClass - 0, 0, // usWidthClass - 0, 0, // fsType - 0, 0, // ySubscriptXSize - 0, 0, // ySubscriptYSize - 0, 0, // ySubscriptXOffset - 0, 0, // ySubscriptYOffset - 0, 0, // ySuperscriptXSize - 0, 0, // ySuperscriptYSize - 0, 0, // ySuperscriptXOffset - 0, 0, // ySuperscriptYOffset - 0, 0, // yStrikeoutSize - 0, 0, // yStrikeoutPosition - 0, 0, // sFamilyClass - 0, 0, 0, 0, 0, // panose - 0, 0, 0, 0, 0, - 0, 0, 0, 0, // ulUnicodeRange1 - 0, 0, 0, 0, // ulUnicodeRange2 - 0, 0, 0, 0, // ulUnicodeRange3 - 0, 0, 0, 0, // ulUnicodeRange4 - 0, 0, 0, 0, // achVendID - 0, 0, // fsSelection - 0, 0, // usFirstCharIndex - 0, 0, // usLastCharIndex - 0, 0, // sTypoAscender - 0, 0, // sTypoDescender - 0, 0, // sTypoLineGap - 0, 0, // usWinAscent - 0, 0, // usWinDescent - 0, 0, 0, 0, // ulCodePageRange1 - 0, 0, 0, 0 // ulCodePageRange2 - }; - bool badCmapLen, abbrevHMTX; - - int nZeroLengthTables; - int nHMetrics, nAdvWidth, nLeftSideBearing; - TrueTypeTable *pNewTables; - char *arrNewNameTable, *arrNewCmapTable, *arrNewHHEATable, *arrNewHMTXTable; - int nNewTables, nCmapIndex, nCmapLen, nGlyphLen, nNewNameLen, nNewCmapLen, nNext; - int nNewHHEALen, nNewHMTXLen; - unsigned int nLocaChecksum, nGlyphChecksum, nFileChecksum; - char *arrTableDir; - char arrLocaBuf[4], arrChecksumBuf[4]; - unsigned int t; - int nPos = 0, i, j, k, n; - - // Записываем OpenType шрифт не меняя его - if (m_bOpenTypeCFF) - { - WriteOTF(pOutputStream, sName, pCodeToGID); - return; - } - - // Проверяем недостающие таблицы - bool bMissingCmap = (nCmapIndex = SeekTable("cmap")) < 0; - bool bMissingName = SeekTable("name") < 0; - bool bMissingPost = SeekTable("post") < 0; - bool bMissingOS2 = SeekTable("OS/2") < 0; - - TrueTypeLoca *pLocaTable = (TrueTypeLoca *)malloc((m_nGlyphs + 1) * sizeof(TrueTypeLoca)); - bool bUnsortedLoca = false; - i = SeekTable("loca"); - nPos = m_pTables[i].nOffset; - bool bSuccess = true; - - for (i = 0; i <= m_nGlyphs; ++i) - { - if (m_nLocaFormat) - { - pLocaTable[i].nOrigOffset = (int)GetU32BE(nPos + i * 4, &bSuccess); - } - else - { - pLocaTable[i].nOrigOffset = 2 * GetU16BE(nPos + i * 2, &bSuccess); - } - if (i > 0 && pLocaTable[i].nOrigOffset < pLocaTable[i - 1].nOrigOffset) - { - bUnsortedLoca = true; - } - // Описание глифа должны быть как минимум 12 байт (nContours, - // xMin, yMin, xMax, yMax, instructionLength - каждый по 2 байта); - if (i > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset < 12) - { - pLocaTable[i - 1].nOrigOffset = pLocaTable[i].nOrigOffset; - bUnsortedLoca = true; - } - pLocaTable[i].nIndex = i; - } - - // Проверяем наличие нулевых таблиц - nZeroLengthTables = 0; - for (i = 0; i < m_nTablesCount; ++i) - { - if (m_pTables[i].nLen == 0) - ++nZeroLengthTables; - } - - // Проверяем длину таблицы Cmap - badCmapLen = false; - nCmapLen = 0; - if (!bMissingCmap) - { - nCmapLen = m_pCMaps[0].nOffset + m_pCMaps[0].nLen; - for (i = 1; i < m_nCMapsCount; ++i) - { - if (m_pCMaps[i].nOffset + m_pCMaps[i].nLen > nCmapLen) - { - nCmapLen = m_pCMaps[i].nOffset + m_pCMaps[i].nLen; - } - } - nCmapLen -= m_pTables[nCmapIndex].nOffset; - if (nCmapLen > m_pTables[nCmapIndex].nLen) - { - badCmapLen = true; - } - } - - // Проверяем, является ли таблица 'hmtx' сокращенной. - i = SeekTable("hhea"); - nHMetrics = GetU16BE(m_pTables[i].nOffset + 34, &bSuccess); - abbrevHMTX = nHMetrics < m_nGlyphs; - - // Если все впорядке, и нам не надо переписывать таблицы 'cmap' и 'name', тогда пишем файл TTF как он есть - if (!bMissingCmap && !bMissingName && !bMissingPost && !bMissingOS2 && !bUnsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 && !sName && !pCodeToGID) - { - pOutputStream->Write((BYTE *)m_sFile, m_nLen); - free(pLocaTable); - return; - } - - // Сортируем таблицу 'loca': некоторые шрифты содержат неупорядоченную - // таблицу 'loca'; а некоторые шрифты с нормальной таблицей 'loca' - // содержат пустые элементы в середине таблицы, cmpTrueTypeLocaOffset - // использует сдвиги как основной ключ для сортировки, а номера глифов - // как второй ключ (чтобы элементы в таблице, которые имели одинаковую позицию - // шли в том же порядке, как и в исходном шрифте) - nGlyphLen = 0; - if (bUnsortedLoca || pUseGlyfs) - { - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaOffset); - for (i = 0; i < m_nGlyphs; ++i) - { - pLocaTable[i].nLen = pLocaTable[i + 1].nOrigOffset - pLocaTable[i].nOrigOffset; - } - pLocaTable[m_nGlyphs].nLen = 0; - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); - nPos = 0; - - for (i = 0; i <= m_nGlyphs; ++i) - { - // TO DO: Протестировать тут запись только тех глифов, которые нам нужны - - if (pUseGlyfs && lGlyfsCount == m_nGlyphs) - { - pLocaTable[i].nNewOffset = nPos; - int nCurGlyfLen = pLocaTable[i].nLen; - pLocaTable[i].nLen = 0; - - if (1 == pUseGlyfs[i]) - { - pLocaTable[i].nLen = nCurGlyfLen; - - nPos += pLocaTable[i].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - } - else - { - pLocaTable[i].nNewOffset = nPos; - nPos += pLocaTable[i].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - } - nGlyphLen = nPos; - } - - // Вычисляем чексуммы таблиц 'loca' и 'glyf' - nLocaChecksum = nGlyphChecksum = 0; - if (bUnsortedLoca || pUseGlyfs) - { - if (m_nLocaFormat) - { - for (j = 0; j <= m_nGlyphs; ++j) - { - nLocaChecksum += pLocaTable[j].nNewOffset; - } - } - else - { - for (j = 0; j <= m_nGlyphs; j += 2) - { - nLocaChecksum += pLocaTable[j].nNewOffset << 16; - if (j + 1 <= m_nGlyphs) - { - nLocaChecksum += pLocaTable[j + 1].nNewOffset; - } - } - } - nPos = m_pTables[SeekTable("glyf")].nOffset; - for (j = 0; j < m_nGlyphs; ++j) - { - n = pLocaTable[j].nLen; - if (n > 0) - { - k = pLocaTable[j].nOrigOffset; - if (CheckRegion(nPos + k, n)) - { - nGlyphChecksum += ComputeTableChecksum(m_sFile + nPos + k, n); - } - } - } - } - - // Строим новую таблицу 'name' - if (sName) - { - n = strlen(sName); - nNewNameLen = (6 + 4 * 12 + 2 * (3 * n + 7) + 3) & ~3; - arrNewNameTable = (char *)malloc(nNewNameLen); - memset(arrNewNameTable, 0, nNewNameLen); - arrNewNameTable[0] = 0; // format selector - arrNewNameTable[1] = 0; - arrNewNameTable[2] = 0; // number of name records - arrNewNameTable[3] = 4; - arrNewNameTable[4] = 0; // offset to start of string storage - arrNewNameTable[5] = 6 + 4 * 12; - nNext = 0; - for (i = 0; i < 4; ++i) - { - arrNewNameTable[6 + i * 12 + 0] = 0; // platform ID = Microsoft - arrNewNameTable[6 + i * 12 + 1] = 3; - arrNewNameTable[6 + i * 12 + 2] = 0; // encoding ID = Unicode - arrNewNameTable[6 + i * 12 + 3] = 1; - arrNewNameTable[6 + i * 12 + 4] = 0x04; // language ID = American English - arrNewNameTable[6 + i * 12 + 5] = 0x09; - arrNewNameTable[6 + i * 12 + 6] = 0; // name ID - arrNewNameTable[6 + i * 12 + 7] = i + 1; - arrNewNameTable[6 + i * 12 + 8] = i + 1 == 2 ? 0 : ((2 * n) >> 8); // string length - arrNewNameTable[6 + i * 12 + 9] = i + 1 == 2 ? 14 : ((2 * n) & 0xff); - arrNewNameTable[6 + i * 12 + 10] = nNext >> 8; // string offset - arrNewNameTable[6 + i * 12 + 11] = nNext & 0xff; - if (i + 1 == 2) - { - memcpy(arrNewNameTable + 6 + 4 * 12 + nNext, "\0R\0e\0g\0u\0l\0a\0r", 14); - nNext += 14; - } - else - { - for (j = 0; j < n; ++j) - { - arrNewNameTable[6 + 4 * 12 + nNext + 2 * j] = 0; - arrNewNameTable[6 + 4 * 12 + nNext + 2 * j + 1] = sName[j]; - } - nNext += 2 * n; - } - } - } - else - { - nNewNameLen = 0; - arrNewNameTable = NULL; - } - - // Строим новую таблицу 'cmap' - if (pCodeToGID) - { - unsigned short ushSubTableLen = 10 + unCodesCount * 2; - nNewCmapLen = 12 + ushSubTableLen; - arrNewCmapTable = (char *)malloc(nNewCmapLen); - arrNewCmapTable[0] = 0; // table version number = 0 - arrNewCmapTable[1] = 0; // - arrNewCmapTable[2] = 0; // number of encoding tables = 1 - arrNewCmapTable[3] = 1; // - arrNewCmapTable[4] = 0; // platform ID = 1 (MacOS) // Эти два поля обязательно должны - arrNewCmapTable[5] = 1; // // иметь таки значения, иначе, Adobe - arrNewCmapTable[6] = 0; // encoding ID = 0 // Acrobat может открыть данный шрифт. - arrNewCmapTable[7] = 0; // // - arrNewCmapTable[8] = 0; // offset of subtable - arrNewCmapTable[9] = 0; // - arrNewCmapTable[10] = 0; // - arrNewCmapTable[11] = 12; // - arrNewCmapTable[12] = 0; // subtable format = 6 - arrNewCmapTable[13] = 6; // - arrNewCmapTable[14] = (ushSubTableLen >> 8) & 0xFF; // subtable length - arrNewCmapTable[15] = ushSubTableLen & 0xFF; // - arrNewCmapTable[16] = 0; // subtable version = 0 - arrNewCmapTable[17] = 0; // - arrNewCmapTable[18] = 0; // firstCode - arrNewCmapTable[19] = 0; // - arrNewCmapTable[20] = 0x01; // entryCount - arrNewCmapTable[21] = 0x00; // - - for (i = 0; i < unCodesCount; ++i) - { - arrNewCmapTable[22 + 2 * i] = pCodeToGID[i] >> 8; - arrNewCmapTable[22 + 2 * i + 1] = pCodeToGID[i] & 0xff; - } - } - else - { - nNewCmapLen = 0; - arrNewCmapTable = NULL; - } - - // Генерируем новую таблицу 'hmtx' и обновляем таблицу 'hhea' - if (abbrevHMTX) - { - i = SeekTable("hhea"); - nPos = m_pTables[i].nOffset; - nNewHHEALen = 36; - arrNewHHEATable = (char *)malloc(nNewHHEALen); - for (i = 0; i < nNewHHEALen; ++i) - { - arrNewHHEATable[i] = GetU8(nPos++, &bSuccess); - } - arrNewHHEATable[34] = m_nGlyphs >> 8; - arrNewHHEATable[35] = m_nGlyphs & 0xff; - i = SeekTable("hmtx"); - nPos = m_pTables[i].nOffset; - nNewHMTXLen = 4 * m_nGlyphs; - arrNewHMTXTable = (char *)malloc(nNewHMTXLen); - nAdvWidth = 0; - for (i = 0; i < nHMetrics; ++i) - { - nAdvWidth = GetU16BE(nPos, &bSuccess); - nLeftSideBearing = GetU16BE(nPos + 2, &bSuccess); - nPos += 4; - arrNewHMTXTable[4 * i] = nAdvWidth >> 8; - arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; - arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; - arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; - } - for (; i < m_nGlyphs; ++i) - { - nLeftSideBearing = GetU16BE(nPos, &bSuccess); - nPos += 2; - arrNewHMTXTable[4 * i] = nAdvWidth >> 8; - arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; - arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; - arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; - } - } - else - { - arrNewHHEATable = arrNewHMTXTable = NULL; - nNewHHEALen = nNewHMTXLen = 0; - } - - // Создаем список таблиц: - // - сохраняем исходные ненулевые таблицы - // - переписываем длину таблицы 'cmap', если необходимо - // - добавляем недостающие таблицы - // - сортируем таблицы по тэгам - // - вычисляем новые позиции таблиц, с учетом 4-байтового выравнивания - // - пересчитываем чексуммы таблиц - nNewTables = m_nTablesCount - nZeroLengthTables + (bMissingCmap ? 1 : 0) + (bMissingName ? 1 : 0) + (bMissingPost ? 1 : 0) + (bMissingOS2 ? 1 : 0); - pNewTables = (TrueTypeTable *)malloc(nNewTables * sizeof(TrueTypeTable)); - j = 0; - for (i = 0; i < m_nTablesCount; ++i) - { - if (m_pTables[i].nLen > 0) - { - pNewTables[j] = m_pTables[i]; - pNewTables[j].nOrigOffset = m_pTables[i].nOffset; - if (CheckRegion(m_pTables[i].nOffset, pNewTables[i].nLen)) - { - pNewTables[j].unChecksum = ComputeTableChecksum(m_sFile + m_pTables[i].nOffset, m_pTables[i].nLen); - if (m_pTables[i].unTag == headTag) - { - // don't include the file checksum - pNewTables[j].unChecksum -= GetU32BE(m_pTables[i].nOffset + 8, &bSuccess); - } - } - if (pNewTables[j].unTag == cmapTag && pCodeToGID) - { - pNewTables[j].nLen = nNewCmapLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); - } - else if (pNewTables[j].unTag == cmapTag && badCmapLen) - { - pNewTables[j].nLen = nCmapLen; - } - else if (pNewTables[j].unTag == locaTag && (bUnsortedLoca || pCodeToGID)) - { - pNewTables[j].nLen = (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2); - pNewTables[j].unChecksum = nLocaChecksum; - } - else if (pNewTables[j].unTag == glyfTag && (bUnsortedLoca || pCodeToGID)) - { - pNewTables[j].nLen = nGlyphLen; - pNewTables[j].unChecksum = nGlyphChecksum; - } - else if (pNewTables[j].unTag == nameTag && sName) - { - pNewTables[j].nLen = nNewNameLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); - } - else if (pNewTables[j].unTag == hheaTag && abbrevHMTX) - { - pNewTables[j].nLen = nNewHHEALen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHHEATable, nNewHHEALen); - } - else if (pNewTables[j].unTag == hmtxTag && abbrevHMTX) - { - pNewTables[j].nLen = nNewHMTXLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHMTXTable, nNewHMTXLen); - } - ++j; - } - } - if (bMissingCmap) - { - pNewTables[j].unTag = cmapTag; - if (pCodeToGID) - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); - pNewTables[j].nLen = nNewCmapLen; - } - else - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrCMapTab, sizeof(arrCMapTab)); - pNewTables[j].nLen = sizeof(arrCMapTab); - } - ++j; - } - if (bMissingName) - { - pNewTables[j].unTag = nameTag; - if (sName) - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); - pNewTables[j].nLen = nNewNameLen; - } - else - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNameTab, sizeof(arrNameTab)); - pNewTables[j].nLen = sizeof(arrNameTab); - } - ++j; - } - if (bMissingPost) - { - pNewTables[j].unTag = postTag; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrPostTab, sizeof(arrPostTab)); - pNewTables[j].nLen = sizeof(arrPostTab); - ++j; - } - if (bMissingOS2) - { - pNewTables[j].unTag = os2Tag; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrOS2Tab, sizeof(arrOS2Tab)); - pNewTables[j].nLen = sizeof(arrOS2Tab); - ++j; - } - qsort(pNewTables, nNewTables, sizeof(TrueTypeTable), CompareTrueTypeTableTag); - - unsigned char *pUseTable = new unsigned char[nNewTables]; - if (!pUseTable) - { - free(arrNewHMTXTable); - free(arrNewHHEATable); - free(arrNewCmapTable); - free(arrNewNameTable); - free(pNewTables); - free(pLocaTable); - return; - } - ::memset(pUseTable, 0, nNewTables * sizeof(unsigned char)); - int nNewReqTables = 0; - for (int nIndex = 0; nIndex < nNewTables; nIndex++) - { - if (pNewTables[nIndex].unTag == cmapTag || pNewTables[nIndex].unTag == glyfTag || - pNewTables[nIndex].unTag == headTag || pNewTables[nIndex].unTag == hheaTag || - pNewTables[nIndex].unTag == hmtxTag || pNewTables[nIndex].unTag == locaTag || - pNewTables[nIndex].unTag == nameTag || pNewTables[nIndex].unTag == os2Tag || - pNewTables[nIndex].unTag == postTag || pNewTables[nIndex].unTag == cvtTag || - pNewTables[nIndex].unTag == fpgmTag || pNewTables[nIndex].unTag == maxpTag || - pNewTables[nIndex].unTag == prepTag) - { - pUseTable[nIndex] = 1; - nNewReqTables++; - } - } - - nPos = 12 + nNewReqTables * 16; - for (i = 0; i < nNewTables; ++i) - { - if (1 == pUseTable[i]) - { - pNewTables[i].nOffset = nPos; - nPos += pNewTables[i].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - } - - // Записываем информацию о таблицах в файле - arrTableDir = (char *)malloc(12 + nNewReqTables * 16); - arrTableDir[0] = 0x00; // sfnt version - arrTableDir[1] = 0x01; // - arrTableDir[2] = 0x00; // - arrTableDir[3] = 0x00; // - arrTableDir[4] = (char)((nNewReqTables >> 8) & 0xff); // numTables - arrTableDir[5] = (char)(nNewReqTables & 0xff); - for (i = -1, t = (unsigned int)nNewReqTables; t; ++i, t >>= 1); - t = 1 << (4 + i); - arrTableDir[6] = (char)((t >> 8) & 0xff); // searchRange - arrTableDir[7] = (char)(t & 0xff); - arrTableDir[8] = (char)((i >> 8) & 0xff); // entrySelector - arrTableDir[9] = (char)(i & 0xff); - t = nNewReqTables * 16 - t; - arrTableDir[10] = (char)((t >> 8) & 0xff); // rangeShift - arrTableDir[11] = (char)(t & 0xff); - nPos = 12; - for (i = 0; i < nNewTables; ++i) - { - if (1 == pUseTable[i]) - { - arrTableDir[nPos] = (char)(pNewTables[i].unTag >> 24); - arrTableDir[nPos + 1] = (char)(pNewTables[i].unTag >> 16); - arrTableDir[nPos + 2] = (char)(pNewTables[i].unTag >> 8); - arrTableDir[nPos + 3] = (char)pNewTables[i].unTag; - arrTableDir[nPos + 4] = (char)(pNewTables[i].unChecksum >> 24); - arrTableDir[nPos + 5] = (char)(pNewTables[i].unChecksum >> 16); - arrTableDir[nPos + 6] = (char)(pNewTables[i].unChecksum >> 8); - arrTableDir[nPos + 7] = (char)pNewTables[i].unChecksum; - arrTableDir[nPos + 8] = (char)(pNewTables[i].nOffset >> 24); - arrTableDir[nPos + 9] = (char)(pNewTables[i].nOffset >> 16); - arrTableDir[nPos + 10] = (char)(pNewTables[i].nOffset >> 8); - arrTableDir[nPos + 11] = (char)pNewTables[i].nOffset; - arrTableDir[nPos + 12] = (char)(pNewTables[i].nLen >> 24); - arrTableDir[nPos + 13] = (char)(pNewTables[i].nLen >> 16); - arrTableDir[nPos + 14] = (char)(pNewTables[i].nLen >> 8); - arrTableDir[nPos + 15] = (char)pNewTables[i].nLen; - nPos += 16; - } - } - pOutputStream->Write((BYTE*)arrTableDir, 12 + nNewReqTables * 16); - - // Вычисляем чексумму файла - nFileChecksum = ComputeTableChecksum((unsigned char *)arrTableDir, 12 + nNewReqTables * 16); - for (i = 0; i < nNewTables; ++i) - { - if (1 == pUseTable[i]) - { - nFileChecksum += pNewTables[i].unChecksum; - } - } - nFileChecksum = 0xb1b0afba - nFileChecksum; - - // Записываем сами таблицы - for (i = 0; i < nNewTables; ++i) - { - if (1 == pUseTable[i]) - { - if (pNewTables[i].unTag == headTag) - { - if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) - { - pOutputStream->Write((BYTE*)m_sFile + pNewTables[i].nOrigOffset, 8); - arrChecksumBuf[0] = nFileChecksum >> 24; - arrChecksumBuf[1] = nFileChecksum >> 16; - arrChecksumBuf[2] = nFileChecksum >> 8; - arrChecksumBuf[3] = nFileChecksum; - pOutputStream->Write((BYTE*)arrChecksumBuf, 4); - pOutputStream->Write((BYTE*)((char *)m_sFile + pNewTables[i].nOrigOffset + 12), pNewTables[i].nLen - 12); - } - else - { - for (j = 0; j < pNewTables[i].nLen; ++j) - { - pOutputStream->Write((BYTE*)"\0", 1); - } - } - } - else if (pNewTables[i].unTag == cmapTag && pCodeToGID) - pOutputStream->Write((BYTE*)arrNewCmapTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == cmapTag && bMissingCmap) - pOutputStream->Write((BYTE*)arrCMapTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == nameTag && sName) - pOutputStream->Write((BYTE*)arrNewNameTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == nameTag && bMissingName) - pOutputStream->Write((BYTE*)arrNameTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == postTag && bMissingPost) - pOutputStream->Write((BYTE*)arrPostTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == os2Tag && bMissingOS2) - pOutputStream->Write((BYTE*)arrOS2Tab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == hheaTag && abbrevHMTX) - pOutputStream->Write((BYTE*)arrNewHHEATable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == hmtxTag && abbrevHMTX) - pOutputStream->Write((BYTE*)arrNewHMTXTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == locaTag && (bUnsortedLoca || pCodeToGID)) - { - for (j = 0; j <= m_nGlyphs; ++j) - { - if (m_nLocaFormat) - { - arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 24); - arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 16); - arrLocaBuf[2] = (char)(pLocaTable[j].nNewOffset >> 8); - arrLocaBuf[3] = (char)pLocaTable[j].nNewOffset; - pOutputStream->Write((BYTE*)arrLocaBuf, 4); - } - else - { - arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 9); - arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 1); - pOutputStream->Write((BYTE*)arrLocaBuf, 2); - } - } - } - else if (pNewTables[i].unTag == glyfTag && (bUnsortedLoca || pCodeToGID)) - { - nPos = m_pTables[SeekTable("glyf")].nOffset; - - for (j = 0; j < m_nGlyphs; ++j) - { - n = pLocaTable[j].nLen; - if (n > 0) - { - k = pLocaTable[j].nOrigOffset; - if (CheckRegion(nPos + k, n)) - { - pOutputStream->Write((BYTE*)((char *)m_sFile + nPos + k), n); - } - else - { - for (k = 0; k < n; ++k) - { - pOutputStream->Write((BYTE*)"\0", 1); - } - } - if ((k = pLocaTable[j].nLen & 3)) - { - pOutputStream->Write((BYTE*)"\0\0\0\0", 4 - k); - } - } - } - } - else - { - if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) - { - pOutputStream->Write((BYTE*)((char *)m_sFile + pNewTables[i].nOrigOffset), pNewTables[i].nLen); - } - else - { - for (j = 0; j < pNewTables[i].nLen; ++j) - { - pOutputStream->Write((BYTE*)"\0", 1); - } - } - } - if (pNewTables[i].nLen & 3) - { - pOutputStream->Write((BYTE*)"\0\0\0", 4 - (pNewTables[i].nLen & 3)); - } - } - } - - delete[]pUseTable; - free(arrNewHMTXTable); - free(arrNewHHEATable); - free(arrNewCmapTable); - free(arrNewNameTable); - free(arrTableDir); - free(pNewTables); - free(pLocaTable); - } - void CFontFileTrueType::WriteOTF(CStream* pOutputStream, char* sName, unsigned short* pCodeToGID) - { - if (!m_bOpenTypeCFF || SeekTable("CFF ") < 0) - return; - - // Open Type Font записываем так как он есть, не изменяя его - pOutputStream->Write((BYTE*)m_sFile, m_nLen); - - return; - } - int CFontFileTrueType::GetAscent() - { - return m_nAscent; - } - int CFontFileTrueType::GetDescent() - { - return m_nDescent; - } - int CFontFileTrueType::GetCapHeight() - { - return m_nCapHeight; - } - int* CFontFileTrueType::GetBBox() - { - return m_arrBBox; - } - int CFontFileTrueType::GetWeight() - { - return m_nWeight; - } - unsigned int CFontFileTrueType::ComputeTableChecksum(unsigned char *sData, int nLength) - { - unsigned int nWord = 0; - - unsigned int nChecksum = 0; - for (int nIndex = 0; nIndex + 3 < nLength; nIndex += 4) - { - nWord = ((sData[nIndex] & 0xff) << 24) + ((sData[nIndex + 1] & 0xff) << 16) + ((sData[nIndex + 2] & 0xff) << 8) + (sData[nIndex + 3] & 0xff); - nChecksum += nWord; - } - if (nLength & 3) - { - nWord = 0; - int nTemp = nLength & ~3; - switch (nLength & 3) - { - case 3: - nWord |= (sData[nTemp + 2] & 0xff) << 8; - case 2: - nWord |= (sData[nTemp + 1] & 0xff) << 16; - case 1: - nWord |= (sData[nTemp] & 0xff) << 24; - break; - } - nChecksum += nWord; - } - return nChecksum; - } - void CFontFileTrueType::Parse() - { - int nPos = 0, nIndex = 0, nJ; - - m_bSuccess = true; - - // Проверяем является ли данный файл (TTC) - unsigned int unTopTag = GetU32BE(0, &m_bSuccess); - if (!m_bSuccess) - return; - - if (unTopTag == ttcfTag) - { - unsigned int unVersion = GetU32BE(4, &m_bSuccess); - unsigned int unNumFonts = GetU32BE(8, &m_bSuccess); - unsigned int unFontIndex = m_unFontIndex >= unNumFonts ? 0 : m_unFontIndex; - nPos = GetU32BE(12 + 4 * unFontIndex, &m_bSuccess); - if (!m_bSuccess) - return; - } - else - nPos = 0; - - // Проверяем sfnt версию - int nSfntVersion = GetU32BE(nPos, &m_bSuccess); - if (!m_bSuccess) - return; - - // Проверяем на формат данных. CCF или нет? - m_bOpenTypeCFF = (nSfntVersion == 0x4f54544f); // 'OTTO' - - m_nTablesCount = GetU16BE(nPos + 4, &m_bSuccess); - if (!m_bSuccess) - return; - - m_pTables = (TrueTypeTable *)malloc(m_nTablesCount * sizeof(TrueTypeTable)); - nPos += 12; - - for (nIndex = 0; nIndex < m_nTablesCount; ++nIndex) - { - m_pTables[nIndex].unTag = GetU32BE(nPos, &m_bSuccess); - m_pTables[nIndex].unChecksum = GetU32BE(nPos + 4, &m_bSuccess); - m_pTables[nIndex].nOffset = (int)GetU32BE(nPos + 8, &m_bSuccess); - m_pTables[nIndex].nLen = (int)GetU32BE(nPos + 12, &m_bSuccess); - if (m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen < m_pTables[nIndex].nOffset || m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen > m_nLen) - { - m_bSuccess = false; - } - nPos += 16; - } - if (!m_bSuccess) - return; - - // ищем таблицы необходимые как и для TrueType так и для Type 42 - if (SeekTable("head") < 0 || SeekTable("hhea") < 0 || SeekTable("maxp") < 0 || SeekTable("hmtx") < 0 || (!m_bOpenTypeCFF && SeekTable("loca") < 0) || (!m_bOpenTypeCFF && SeekTable("glyf") < 0) || (m_bOpenTypeCFF && SeekTable("CFF ") < 0)) - { - m_bSuccess = false; - return; - } - - // читаем таблицы CMaps - if ((nIndex = SeekTable("cmap")) >= 0) - { - nPos = m_pTables[nIndex].nOffset + 2; - m_nCMapsCount = GetU16BE(nPos, &m_bSuccess); - nPos += 2; - if (!m_bSuccess) - return; - - m_pCMaps = (TrueTypeCmap *)malloc(m_nCMapsCount * sizeof(TrueTypeCmap)); - - for (nJ = 0; nJ < m_nCMapsCount; ++nJ) - { - m_pCMaps[nJ].nPlatform = GetU16BE(nPos, &m_bSuccess); - m_pCMaps[nJ].nEncoding = GetU16BE(nPos + 2, &m_bSuccess); - unsigned int nTemp = GetU32BE(nPos + 4, &m_bSuccess); - m_pCMaps[nJ].nOffset = m_pTables[nIndex].nOffset + GetU32BE(nPos + 4, &m_bSuccess); - nPos += 8; - m_pCMaps[nJ].nFormat = GetU16BE(m_pCMaps[nJ].nOffset, &m_bSuccess); - m_pCMaps[nJ].nLen = GetU16BE(m_pCMaps[nJ].nOffset + 2, &m_bSuccess); - } - if (!m_bSuccess) - return; - } - else - m_nCMapsCount = 0; - - nIndex = SeekTable("maxp"); - m_nGlyphs = GetU16BE(m_pTables[nIndex].nOffset + 4, &m_bSuccess); - if (!m_bSuccess) - return; - - nIndex = SeekTable("head"); - m_arrBBox[0] = GetS16BE(m_pTables[nIndex].nOffset + 36, &m_bSuccess); - m_arrBBox[1] = GetS16BE(m_pTables[nIndex].nOffset + 38, &m_bSuccess); - m_arrBBox[2] = GetS16BE(m_pTables[nIndex].nOffset + 40, &m_bSuccess); - m_arrBBox[3] = GetS16BE(m_pTables[nIndex].nOffset + 42, &m_bSuccess); - m_nLocaFormat = GetS16BE(m_pTables[nIndex].nOffset + 50, &m_bSuccess); - if (!m_bSuccess) - return; - - // Проверяем корректность таблицы loca - if (!m_bOpenTypeCFF) - { - nIndex = SeekTable("loca"); - if (m_pTables[nIndex].nLen < 0) - { - m_bSuccess = false; - return; - } - if (m_pTables[nIndex].nLen < (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2)) - { - m_nGlyphs = m_pTables[nIndex].nLen / (m_nLocaFormat ? 4 : 2) - 1; - } - for (nJ = 0; nJ <= m_nGlyphs; ++nJ) - { - if (m_nLocaFormat) - nPos = (int)GetU32BE(m_pTables[nIndex].nOffset + nJ * 4, &m_bSuccess); - else - nPos = GetU16BE(m_pTables[nIndex].nOffset + nJ * 2, &m_bSuccess); - - if (nPos < 0 || nPos > m_nLen) - m_bSuccess = false; - } - if (!m_bSuccess) - return; - } - - ReadOS2(); - } - int CFontFileTrueType::SeekTable(const char *sTag) - { - unsigned int nTagIndex = ((sTag[0] & 0xff) << 24) | ((sTag[1] & 0xff) << 16) | ((sTag[2] & 0xff) << 8) | (sTag[3] & 0xff); - for (int nIndex = 0; nIndex < m_nTablesCount; ++nIndex) - { - if (m_pTables[nIndex].unTag == nTagIndex) - { - return nIndex; - } - } - return -1; - } - void CFontFileTrueType::ReadOS2() - { - int nIndex = SeekTable("OS/2"); - if (-1 != nIndex && m_pTables[nIndex].nLen > 0) - { - unsigned int unOffset = m_pTables[nIndex].nOffset; - m_nWeight = GetS16BE(unOffset + 4, &m_bSuccess); - m_nAscent = GetS16BE(unOffset + 68, &m_bSuccess); - m_nDescent = GetS16BE(unOffset + 70, &m_bSuccess); - m_nCapHeight = GetS16BE(unOffset + 88, &m_bSuccess); - } - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "FontTTWriter.h" +#include "../../DesktopEditor/common/File.h" + +#define ttcfTag 0x74746366 +#define cmapTag 0x636d6170 +#define glyfTag 0x676c7966 +#define headTag 0x68656164 +#define hheaTag 0x68686561 +#define hmtxTag 0x686d7478 +#define locaTag 0x6c6f6361 +#define nameTag 0x6e616d65 +#define os2Tag 0x4f532f32 +#define postTag 0x706f7374 + +#define cvtTag 0x63767420 +#define fpgmTag 0x6670676d +#define maxpTag 0x6d617870 +#define prepTag 0x70726570 + +namespace PdfWriter +{ + struct TrueTypeTable + { + unsigned int unTag; + unsigned int unChecksum; + int nOffset; + int nOrigOffset; + int nLen; + }; + struct TrueTypeCmap + { + int nPlatform; + int nEncoding; + int nOffset; + int nLen; + int nFormat; + }; + struct TrueTypeLoca + { + int nIndex; + int nOrigOffset; + int nNewOffset; + int nLen; + }; + static int CompareTrueTypeLocaOffset(const void *pL1, const void *pL2) + { + TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; + TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; + + if (pLoca1->nOrigOffset == pLoca2->nOrigOffset) + return pLoca1->nIndex - pLoca2->nIndex; + + return pLoca1->nOrigOffset - pLoca2->nOrigOffset; + } + static int CompareTrueTypeLocaIndex(const void *pL1, const void *pL2) + { + TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; + TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; + + return pLoca1->nIndex - pLoca2->nIndex; + } + static int CompareTrueTypeTableTag(const void *pTab1, const void *pTab2) + { + TrueTypeTable *pTable1 = (TrueTypeTable *)pTab1; + TrueTypeTable *pTable2 = (TrueTypeTable *)pTab2; + + return (int)pTable1->unTag - (int)pTable2->unTag; + } + //---------------------------------------------------------------------------------------- + // CFontFileBase + //---------------------------------------------------------------------------------------- + CFontFileBase::CFontFileBase(char *sFile, int nLen, bool bFreeFileData) + { + m_sFileData = m_sFile = (unsigned char *)sFile; + m_nLen = nLen; + m_bFreeFileData = bFreeFileData; + } + CFontFileBase::~CFontFileBase() + { + if (m_bFreeFileData) + free(m_sFileData); + } + char* CFontFileBase::ReadFile(const std::wstring & wsFileName, int *pnFileLen) + { + NSFile::CFileBinary oFile; + + if (oFile.OpenFile(wsFileName) == false) + return NULL; + + int nLen = oFile.GetFileSize(); + DWORD nLenRead = 0; + + char *sBuffer = (char *)malloc(nLen); + if (NULL != sBuffer) + { + if ((int)oFile.ReadFile((BYTE*)sBuffer, nLen, nLenRead) == false) + { + if (sBuffer) + free(sBuffer); + + oFile.CloseFile(); + return NULL; + } + + oFile.CloseFile(); + *pnFileLen = nLen; + } + else + { + oFile.CloseFile(); + } + return sBuffer; + } + int CFontFileBase::GetS8(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos >= m_nLen) + { + *pbSuccess = false; + return 0; + } + int nRes = m_sFile[nPos]; + if (nRes & 0x80) + nRes |= ~0xff; + return nRes; + } + int CFontFileBase::GetU8(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + if (nPos < 0 || nPos >= m_nLen) + { + *pbSuccess = false; + return 0; + } + return m_sFile[nPos]; + } + int CFontFileBase::GetS16BE(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos + 1 >= m_nLen) + { + *pbSuccess = false; + return 0; + } + int nRes = m_sFile[nPos]; + nRes = (nRes << 8) + m_sFile[nPos + 1]; + if (nRes & 0x8000) + nRes |= ~0xffff; + return nRes; + } + int CFontFileBase::GetU16BE(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos + 1 >= m_nLen) + { + *pbSuccess = false; + return 0; + } + int nRes = m_sFile[nPos]; + nRes = (nRes << 8) + m_sFile[nPos + 1]; + return nRes; + } + int CFontFileBase::GetS32BE(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos + 3 >= m_nLen) + { + *pbSuccess = false; + return 0; + } + int nRes = m_sFile[nPos]; + nRes = (nRes << 8) + m_sFile[nPos + 1]; + nRes = (nRes << 8) + m_sFile[nPos + 2]; + nRes = (nRes << 8) + m_sFile[nPos + 3]; + if (nRes & 0x80000000) + nRes |= ~0xffffffff; + + return nRes; + } + unsigned int CFontFileBase::GetU32BE(int nPos, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos + 3 >= m_nLen) + { + *pbSuccess = false; + return 0; + } + unsigned int nRes = m_sFile[nPos]; + nRes = (nRes << 8) + m_sFile[nPos + 1]; + nRes = (nRes << 8) + m_sFile[nPos + 2]; + nRes = (nRes << 8) + m_sFile[nPos + 3]; + return nRes; + } + unsigned int CFontFileBase::GetUVarBE(int nPos, int nSize, bool *pbSuccess) + { + *pbSuccess = true; + + if (nPos < 0 || nPos + nSize > m_nLen) + { + *pbSuccess = false; + return 0; + } + unsigned int nRes = 0; + for (int nIndex = 0; nIndex < nSize; ++nIndex) + nRes = (nRes << 8) + m_sFile[nPos + nIndex]; + + return nRes; + } + bool CFontFileBase::CheckRegion(int nPos, int nSize) + { + return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen); + } + //---------------------------------------------------------------------------------------- + // CFontFileTrueType + //---------------------------------------------------------------------------------------- + CFontFileTrueType::CFontFileTrueType(char *sBuffer, int nLen, bool bFreeFileData, unsigned int unFontIndex) :CFontFileBase(sBuffer, nLen, bFreeFileData) + { + m_pTables = NULL; + m_nTablesCount = 0; + m_pCMaps = NULL; + m_nCMapsCount = 0; + m_bSuccess = false; + m_unFontIndex = unFontIndex; + + m_nAscent = 1000; + m_nDescent = -500; + m_nCapHeight = 800; + + Parse(); + } + CFontFileTrueType* CFontFileTrueType::LoadFromBuffer(char *sBuffer, int nLen, unsigned int unIndex) + { + CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, false, unIndex); + if (!pTTF->m_bSuccess) + { + delete pTTF; + return NULL; + } + return pTTF; + } + CFontFileTrueType* CFontFileTrueType::LoadFromFile(const std::wstring& wsFileName, unsigned int unIndex) + { + char *sBuffer; + int nLen = 0; + + if (!(sBuffer = CFontFileBase::ReadFile(wsFileName, &nLen))) + return NULL; + + CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, true, unIndex); + if (!pTTF->m_bSuccess) + { + delete pTTF; + return NULL; + } + return pTTF; + } + CFontFileTrueType::~CFontFileTrueType() + { + if (m_pTables) + free(m_pTables); + + if (m_pCMaps) + free(m_pCMaps); + } + void CFontFileTrueType::WriteTTF(CStream* pOutputStream, char* sName, unsigned short* pCodeToGID, unsigned int unCodesCount, unsigned char* pUseGlyfs, long lGlyfsCount) + { + static char arrCMapTab[36] = + { + 0, 0, // table version number + 0, 1, // number of encoding tables + 0, 1, // platform ID + 0, 0, // encoding ID + 0, 0, 0, 12, // offset of subtable + 0, 4, // subtable format + 0, 24, // subtable length + 0, 0, // subtable version + 0, 2, // segment count * 2 + 0, 2, // 2 * 2 ^ floor(log2(segCount)) + 0, 0, // floor(log2(segCount)) + 0, 0, // 2*segCount - 2*2^floor(log2(segCount)) + (char)0xff, (char)0xff, // endCount[0] + 0, 0, // reserved + 0, 0, // startCount[0] + 0, 0, // idDelta[0] + 0, 0 // pad to a mulitple of four bytes + }; + + static char arrNameTab[8] = + { + 0, 0, // format + 0, 0, // number of name records + 0, 6, // offset to start of string storage + 0, 0 // pad to multiple of four bytes + }; + static char arrPostTab[32] = + { + 0, 1, 0, 0, // format + 0, 0, 0, 0, // italic angle + 0, 0, // underline position + 0, 0, // underline thickness + 0, 0, 0, 0, // fixed pitch + 0, 0, 0, 0, // min Type 42 memory + 0, 0, 0, 0, // max Type 42 memory + 0, 0, 0, 0, // min Type 1 memory + 0, 0, 0, 0 // max Type 1 memory + }; + static char arrOS2Tab[86] = + { + 0, 1, // version + 0, 1, // xAvgCharWidth + 0, 0, // usWeightClass + 0, 0, // usWidthClass + 0, 0, // fsType + 0, 0, // ySubscriptXSize + 0, 0, // ySubscriptYSize + 0, 0, // ySubscriptXOffset + 0, 0, // ySubscriptYOffset + 0, 0, // ySuperscriptXSize + 0, 0, // ySuperscriptYSize + 0, 0, // ySuperscriptXOffset + 0, 0, // ySuperscriptYOffset + 0, 0, // yStrikeoutSize + 0, 0, // yStrikeoutPosition + 0, 0, // sFamilyClass + 0, 0, 0, 0, 0, // panose + 0, 0, 0, 0, 0, + 0, 0, 0, 0, // ulUnicodeRange1 + 0, 0, 0, 0, // ulUnicodeRange2 + 0, 0, 0, 0, // ulUnicodeRange3 + 0, 0, 0, 0, // ulUnicodeRange4 + 0, 0, 0, 0, // achVendID + 0, 0, // fsSelection + 0, 0, // usFirstCharIndex + 0, 0, // usLastCharIndex + 0, 0, // sTypoAscender + 0, 0, // sTypoDescender + 0, 0, // sTypoLineGap + 0, 0, // usWinAscent + 0, 0, // usWinDescent + 0, 0, 0, 0, // ulCodePageRange1 + 0, 0, 0, 0 // ulCodePageRange2 + }; + bool badCmapLen, abbrevHMTX; + + int nZeroLengthTables; + int nHMetrics, nAdvWidth, nLeftSideBearing; + TrueTypeTable *pNewTables; + char *arrNewNameTable, *arrNewCmapTable, *arrNewHHEATable, *arrNewHMTXTable; + int nNewTables, nCmapIndex, nCmapLen, nGlyphLen, nNewNameLen, nNewCmapLen, nNext; + int nNewHHEALen, nNewHMTXLen; + unsigned int nLocaChecksum, nGlyphChecksum, nFileChecksum; + char *arrTableDir; + char arrLocaBuf[4], arrChecksumBuf[4]; + unsigned int t; + int nPos = 0, i, j, k, n; + + // Записываем OpenType шрифт не меняя его + if (m_bOpenTypeCFF) + { + WriteOTF(pOutputStream, sName, pCodeToGID); + return; + } + + // Проверяем недостающие таблицы + bool bMissingCmap = (nCmapIndex = SeekTable("cmap")) < 0; + bool bMissingName = SeekTable("name") < 0; + bool bMissingPost = SeekTable("post") < 0; + bool bMissingOS2 = SeekTable("OS/2") < 0; + + TrueTypeLoca *pLocaTable = (TrueTypeLoca *)malloc((m_nGlyphs + 1) * sizeof(TrueTypeLoca)); + bool bUnsortedLoca = false; + i = SeekTable("loca"); + nPos = m_pTables[i].nOffset; + bool bSuccess = true; + + for (i = 0; i <= m_nGlyphs; ++i) + { + if (m_nLocaFormat) + { + pLocaTable[i].nOrigOffset = (int)GetU32BE(nPos + i * 4, &bSuccess); + } + else + { + pLocaTable[i].nOrigOffset = 2 * GetU16BE(nPos + i * 2, &bSuccess); + } + if (i > 0 && pLocaTable[i].nOrigOffset < pLocaTable[i - 1].nOrigOffset) + { + bUnsortedLoca = true; + } + // Описание глифа должны быть как минимум 12 байт (nContours, + // xMin, yMin, xMax, yMax, instructionLength - каждый по 2 байта); + if (i > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset < 12) + { + pLocaTable[i - 1].nOrigOffset = pLocaTable[i].nOrigOffset; + bUnsortedLoca = true; + } + pLocaTable[i].nIndex = i; + } + + // Проверяем наличие нулевых таблиц + nZeroLengthTables = 0; + for (i = 0; i < m_nTablesCount; ++i) + { + if (m_pTables[i].nLen == 0) + ++nZeroLengthTables; + } + + // Проверяем длину таблицы Cmap + badCmapLen = false; + nCmapLen = 0; + if (!bMissingCmap) + { + nCmapLen = m_pCMaps[0].nOffset + m_pCMaps[0].nLen; + for (i = 1; i < m_nCMapsCount; ++i) + { + if (m_pCMaps[i].nOffset + m_pCMaps[i].nLen > nCmapLen) + { + nCmapLen = m_pCMaps[i].nOffset + m_pCMaps[i].nLen; + } + } + nCmapLen -= m_pTables[nCmapIndex].nOffset; + if (nCmapLen > m_pTables[nCmapIndex].nLen) + { + badCmapLen = true; + } + } + + // Проверяем, является ли таблица 'hmtx' сокращенной. + i = SeekTable("hhea"); + nHMetrics = GetU16BE(m_pTables[i].nOffset + 34, &bSuccess); + abbrevHMTX = nHMetrics < m_nGlyphs; + + // Если все впорядке, и нам не надо переписывать таблицы 'cmap' и 'name', тогда пишем файл TTF как он есть + if (!bMissingCmap && !bMissingName && !bMissingPost && !bMissingOS2 && !bUnsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 && !sName && !pCodeToGID) + { + pOutputStream->Write((BYTE *)m_sFile, m_nLen); + free(pLocaTable); + return; + } + + // Сортируем таблицу 'loca': некоторые шрифты содержат неупорядоченную + // таблицу 'loca'; а некоторые шрифты с нормальной таблицей 'loca' + // содержат пустые элементы в середине таблицы, cmpTrueTypeLocaOffset + // использует сдвиги как основной ключ для сортировки, а номера глифов + // как второй ключ (чтобы элементы в таблице, которые имели одинаковую позицию + // шли в том же порядке, как и в исходном шрифте) + nGlyphLen = 0; + if (bUnsortedLoca || pUseGlyfs) + { + qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaOffset); + for (i = 0; i < m_nGlyphs; ++i) + { + pLocaTable[i].nLen = pLocaTable[i + 1].nOrigOffset - pLocaTable[i].nOrigOffset; + } + pLocaTable[m_nGlyphs].nLen = 0; + qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); + nPos = 0; + + for (i = 0; i <= m_nGlyphs; ++i) + { + // TO DO: Протестировать тут запись только тех глифов, которые нам нужны + + if (pUseGlyfs && lGlyfsCount == m_nGlyphs) + { + pLocaTable[i].nNewOffset = nPos; + int nCurGlyfLen = pLocaTable[i].nLen; + pLocaTable[i].nLen = 0; + + if (1 == pUseGlyfs[i]) + { + pLocaTable[i].nLen = nCurGlyfLen; + + nPos += pLocaTable[i].nLen; + if (nPos & 3) + { + nPos += 4 - (nPos & 3); + } + } + } + else + { + pLocaTable[i].nNewOffset = nPos; + nPos += pLocaTable[i].nLen; + if (nPos & 3) + { + nPos += 4 - (nPos & 3); + } + } + } + nGlyphLen = nPos; + } + + // Вычисляем чексуммы таблиц 'loca' и 'glyf' + nLocaChecksum = nGlyphChecksum = 0; + if (bUnsortedLoca || pUseGlyfs) + { + if (m_nLocaFormat) + { + for (j = 0; j <= m_nGlyphs; ++j) + { + nLocaChecksum += pLocaTable[j].nNewOffset; + } + } + else + { + for (j = 0; j <= m_nGlyphs; j += 2) + { + nLocaChecksum += pLocaTable[j].nNewOffset << 16; + if (j + 1 <= m_nGlyphs) + { + nLocaChecksum += pLocaTable[j + 1].nNewOffset; + } + } + } + nPos = m_pTables[SeekTable("glyf")].nOffset; + for (j = 0; j < m_nGlyphs; ++j) + { + n = pLocaTable[j].nLen; + if (n > 0) + { + k = pLocaTable[j].nOrigOffset; + if (CheckRegion(nPos + k, n)) + { + nGlyphChecksum += ComputeTableChecksum(m_sFile + nPos + k, n); + } + } + } + } + + // Строим новую таблицу 'name' + if (sName) + { + n = strlen(sName); + nNewNameLen = (6 + 4 * 12 + 2 * (3 * n + 7) + 3) & ~3; + arrNewNameTable = (char *)malloc(nNewNameLen); + memset(arrNewNameTable, 0, nNewNameLen); + arrNewNameTable[0] = 0; // format selector + arrNewNameTable[1] = 0; + arrNewNameTable[2] = 0; // number of name records + arrNewNameTable[3] = 4; + arrNewNameTable[4] = 0; // offset to start of string storage + arrNewNameTable[5] = 6 + 4 * 12; + nNext = 0; + for (i = 0; i < 4; ++i) + { + arrNewNameTable[6 + i * 12 + 0] = 0; // platform ID = Microsoft + arrNewNameTable[6 + i * 12 + 1] = 3; + arrNewNameTable[6 + i * 12 + 2] = 0; // encoding ID = Unicode + arrNewNameTable[6 + i * 12 + 3] = 1; + arrNewNameTable[6 + i * 12 + 4] = 0x04; // language ID = American English + arrNewNameTable[6 + i * 12 + 5] = 0x09; + arrNewNameTable[6 + i * 12 + 6] = 0; // name ID + arrNewNameTable[6 + i * 12 + 7] = i + 1; + arrNewNameTable[6 + i * 12 + 8] = i + 1 == 2 ? 0 : ((2 * n) >> 8); // string length + arrNewNameTable[6 + i * 12 + 9] = i + 1 == 2 ? 14 : ((2 * n) & 0xff); + arrNewNameTable[6 + i * 12 + 10] = nNext >> 8; // string offset + arrNewNameTable[6 + i * 12 + 11] = nNext & 0xff; + if (i + 1 == 2) + { + memcpy(arrNewNameTable + 6 + 4 * 12 + nNext, "\0R\0e\0g\0u\0l\0a\0r", 14); + nNext += 14; + } + else + { + for (j = 0; j < n; ++j) + { + arrNewNameTable[6 + 4 * 12 + nNext + 2 * j] = 0; + arrNewNameTable[6 + 4 * 12 + nNext + 2 * j + 1] = sName[j]; + } + nNext += 2 * n; + } + } + } + else + { + nNewNameLen = 0; + arrNewNameTable = NULL; + } + + // Строим новую таблицу 'cmap' + if (pCodeToGID) + { + unsigned short ushSubTableLen = 10 + unCodesCount * 2; + nNewCmapLen = 12 + ushSubTableLen; + arrNewCmapTable = (char *)malloc(nNewCmapLen); + arrNewCmapTable[0] = 0; // table version number = 0 + arrNewCmapTable[1] = 0; // + arrNewCmapTable[2] = 0; // number of encoding tables = 1 + arrNewCmapTable[3] = 1; // + arrNewCmapTable[4] = 0; // platform ID = 1 (MacOS) // Эти два поля обязательно должны + arrNewCmapTable[5] = 1; // // иметь таки значения, иначе, Adobe + arrNewCmapTable[6] = 0; // encoding ID = 0 // Acrobat может открыть данный шрифт. + arrNewCmapTable[7] = 0; // // + arrNewCmapTable[8] = 0; // offset of subtable + arrNewCmapTable[9] = 0; // + arrNewCmapTable[10] = 0; // + arrNewCmapTable[11] = 12; // + arrNewCmapTable[12] = 0; // subtable format = 6 + arrNewCmapTable[13] = 6; // + arrNewCmapTable[14] = (ushSubTableLen >> 8) & 0xFF; // subtable length + arrNewCmapTable[15] = ushSubTableLen & 0xFF; // + arrNewCmapTable[16] = 0; // subtable version = 0 + arrNewCmapTable[17] = 0; // + arrNewCmapTable[18] = 0; // firstCode + arrNewCmapTable[19] = 0; // + arrNewCmapTable[20] = 0x01; // entryCount + arrNewCmapTable[21] = 0x00; // + + for (i = 0; i < unCodesCount; ++i) + { + arrNewCmapTable[22 + 2 * i] = pCodeToGID[i] >> 8; + arrNewCmapTable[22 + 2 * i + 1] = pCodeToGID[i] & 0xff; + } + } + else + { + nNewCmapLen = 0; + arrNewCmapTable = NULL; + } + + // Генерируем новую таблицу 'hmtx' и обновляем таблицу 'hhea' + if (abbrevHMTX) + { + i = SeekTable("hhea"); + nPos = m_pTables[i].nOffset; + nNewHHEALen = 36; + arrNewHHEATable = (char *)malloc(nNewHHEALen); + for (i = 0; i < nNewHHEALen; ++i) + { + arrNewHHEATable[i] = GetU8(nPos++, &bSuccess); + } + arrNewHHEATable[34] = m_nGlyphs >> 8; + arrNewHHEATable[35] = m_nGlyphs & 0xff; + i = SeekTable("hmtx"); + nPos = m_pTables[i].nOffset; + nNewHMTXLen = 4 * m_nGlyphs; + arrNewHMTXTable = (char *)malloc(nNewHMTXLen); + nAdvWidth = 0; + for (i = 0; i < nHMetrics; ++i) + { + nAdvWidth = GetU16BE(nPos, &bSuccess); + nLeftSideBearing = GetU16BE(nPos + 2, &bSuccess); + nPos += 4; + arrNewHMTXTable[4 * i] = nAdvWidth >> 8; + arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; + arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; + arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; + } + for (; i < m_nGlyphs; ++i) + { + nLeftSideBearing = GetU16BE(nPos, &bSuccess); + nPos += 2; + arrNewHMTXTable[4 * i] = nAdvWidth >> 8; + arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; + arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; + arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; + } + } + else + { + arrNewHHEATable = arrNewHMTXTable = NULL; + nNewHHEALen = nNewHMTXLen = 0; + } + + // Создаем список таблиц: + // - сохраняем исходные ненулевые таблицы + // - переписываем длину таблицы 'cmap', если необходимо + // - добавляем недостающие таблицы + // - сортируем таблицы по тэгам + // - вычисляем новые позиции таблиц, с учетом 4-байтового выравнивания + // - пересчитываем чексуммы таблиц + nNewTables = m_nTablesCount - nZeroLengthTables + (bMissingCmap ? 1 : 0) + (bMissingName ? 1 : 0) + (bMissingPost ? 1 : 0) + (bMissingOS2 ? 1 : 0); + pNewTables = (TrueTypeTable *)malloc(nNewTables * sizeof(TrueTypeTable)); + j = 0; + for (i = 0; i < m_nTablesCount; ++i) + { + if (m_pTables[i].nLen > 0) + { + pNewTables[j] = m_pTables[i]; + pNewTables[j].nOrigOffset = m_pTables[i].nOffset; + if (CheckRegion(m_pTables[i].nOffset, pNewTables[i].nLen)) + { + pNewTables[j].unChecksum = ComputeTableChecksum(m_sFile + m_pTables[i].nOffset, m_pTables[i].nLen); + if (m_pTables[i].unTag == headTag) + { + // don't include the file checksum + pNewTables[j].unChecksum -= GetU32BE(m_pTables[i].nOffset + 8, &bSuccess); + } + } + if (pNewTables[j].unTag == cmapTag && pCodeToGID) + { + pNewTables[j].nLen = nNewCmapLen; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); + } + else if (pNewTables[j].unTag == cmapTag && badCmapLen) + { + pNewTables[j].nLen = nCmapLen; + } + else if (pNewTables[j].unTag == locaTag && (bUnsortedLoca || pCodeToGID)) + { + pNewTables[j].nLen = (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2); + pNewTables[j].unChecksum = nLocaChecksum; + } + else if (pNewTables[j].unTag == glyfTag && (bUnsortedLoca || pCodeToGID)) + { + pNewTables[j].nLen = nGlyphLen; + pNewTables[j].unChecksum = nGlyphChecksum; + } + else if (pNewTables[j].unTag == nameTag && sName) + { + pNewTables[j].nLen = nNewNameLen; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); + } + else if (pNewTables[j].unTag == hheaTag && abbrevHMTX) + { + pNewTables[j].nLen = nNewHHEALen; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHHEATable, nNewHHEALen); + } + else if (pNewTables[j].unTag == hmtxTag && abbrevHMTX) + { + pNewTables[j].nLen = nNewHMTXLen; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHMTXTable, nNewHMTXLen); + } + ++j; + } + } + if (bMissingCmap) + { + pNewTables[j].unTag = cmapTag; + if (pCodeToGID) + { + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); + pNewTables[j].nLen = nNewCmapLen; + } + else + { + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrCMapTab, sizeof(arrCMapTab)); + pNewTables[j].nLen = sizeof(arrCMapTab); + } + ++j; + } + if (bMissingName) + { + pNewTables[j].unTag = nameTag; + if (sName) + { + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); + pNewTables[j].nLen = nNewNameLen; + } + else + { + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNameTab, sizeof(arrNameTab)); + pNewTables[j].nLen = sizeof(arrNameTab); + } + ++j; + } + if (bMissingPost) + { + pNewTables[j].unTag = postTag; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrPostTab, sizeof(arrPostTab)); + pNewTables[j].nLen = sizeof(arrPostTab); + ++j; + } + if (bMissingOS2) + { + pNewTables[j].unTag = os2Tag; + pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrOS2Tab, sizeof(arrOS2Tab)); + pNewTables[j].nLen = sizeof(arrOS2Tab); + ++j; + } + qsort(pNewTables, nNewTables, sizeof(TrueTypeTable), CompareTrueTypeTableTag); + + unsigned char *pUseTable = new unsigned char[nNewTables]; + if (!pUseTable) + { + free(arrNewHMTXTable); + free(arrNewHHEATable); + free(arrNewCmapTable); + free(arrNewNameTable); + free(pNewTables); + free(pLocaTable); + return; + } + ::memset(pUseTable, 0, nNewTables * sizeof(unsigned char)); + int nNewReqTables = 0; + for (int nIndex = 0; nIndex < nNewTables; nIndex++) + { + if (pNewTables[nIndex].unTag == cmapTag || pNewTables[nIndex].unTag == glyfTag || + pNewTables[nIndex].unTag == headTag || pNewTables[nIndex].unTag == hheaTag || + pNewTables[nIndex].unTag == hmtxTag || pNewTables[nIndex].unTag == locaTag || + pNewTables[nIndex].unTag == nameTag || pNewTables[nIndex].unTag == os2Tag || + pNewTables[nIndex].unTag == postTag || pNewTables[nIndex].unTag == cvtTag || + pNewTables[nIndex].unTag == fpgmTag || pNewTables[nIndex].unTag == maxpTag || + pNewTables[nIndex].unTag == prepTag) + { + pUseTable[nIndex] = 1; + nNewReqTables++; + } + } + + nPos = 12 + nNewReqTables * 16; + for (i = 0; i < nNewTables; ++i) + { + if (1 == pUseTable[i]) + { + pNewTables[i].nOffset = nPos; + nPos += pNewTables[i].nLen; + if (nPos & 3) + { + nPos += 4 - (nPos & 3); + } + } + } + + // Записываем информацию о таблицах в файле + arrTableDir = (char *)malloc(12 + nNewReqTables * 16); + arrTableDir[0] = 0x00; // sfnt version + arrTableDir[1] = 0x01; // + arrTableDir[2] = 0x00; // + arrTableDir[3] = 0x00; // + arrTableDir[4] = (char)((nNewReqTables >> 8) & 0xff); // numTables + arrTableDir[5] = (char)(nNewReqTables & 0xff); + for (i = -1, t = (unsigned int)nNewReqTables; t; ++i, t >>= 1); + t = 1 << (4 + i); + arrTableDir[6] = (char)((t >> 8) & 0xff); // searchRange + arrTableDir[7] = (char)(t & 0xff); + arrTableDir[8] = (char)((i >> 8) & 0xff); // entrySelector + arrTableDir[9] = (char)(i & 0xff); + t = nNewReqTables * 16 - t; + arrTableDir[10] = (char)((t >> 8) & 0xff); // rangeShift + arrTableDir[11] = (char)(t & 0xff); + nPos = 12; + for (i = 0; i < nNewTables; ++i) + { + if (1 == pUseTable[i]) + { + arrTableDir[nPos] = (char)(pNewTables[i].unTag >> 24); + arrTableDir[nPos + 1] = (char)(pNewTables[i].unTag >> 16); + arrTableDir[nPos + 2] = (char)(pNewTables[i].unTag >> 8); + arrTableDir[nPos + 3] = (char)pNewTables[i].unTag; + arrTableDir[nPos + 4] = (char)(pNewTables[i].unChecksum >> 24); + arrTableDir[nPos + 5] = (char)(pNewTables[i].unChecksum >> 16); + arrTableDir[nPos + 6] = (char)(pNewTables[i].unChecksum >> 8); + arrTableDir[nPos + 7] = (char)pNewTables[i].unChecksum; + arrTableDir[nPos + 8] = (char)(pNewTables[i].nOffset >> 24); + arrTableDir[nPos + 9] = (char)(pNewTables[i].nOffset >> 16); + arrTableDir[nPos + 10] = (char)(pNewTables[i].nOffset >> 8); + arrTableDir[nPos + 11] = (char)pNewTables[i].nOffset; + arrTableDir[nPos + 12] = (char)(pNewTables[i].nLen >> 24); + arrTableDir[nPos + 13] = (char)(pNewTables[i].nLen >> 16); + arrTableDir[nPos + 14] = (char)(pNewTables[i].nLen >> 8); + arrTableDir[nPos + 15] = (char)pNewTables[i].nLen; + nPos += 16; + } + } + pOutputStream->Write((BYTE*)arrTableDir, 12 + nNewReqTables * 16); + + // Вычисляем чексумму файла + nFileChecksum = ComputeTableChecksum((unsigned char *)arrTableDir, 12 + nNewReqTables * 16); + for (i = 0; i < nNewTables; ++i) + { + if (1 == pUseTable[i]) + { + nFileChecksum += pNewTables[i].unChecksum; + } + } + nFileChecksum = 0xb1b0afba - nFileChecksum; + + // Записываем сами таблицы + for (i = 0; i < nNewTables; ++i) + { + if (1 == pUseTable[i]) + { + if (pNewTables[i].unTag == headTag) + { + if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) + { + pOutputStream->Write((BYTE*)m_sFile + pNewTables[i].nOrigOffset, 8); + arrChecksumBuf[0] = nFileChecksum >> 24; + arrChecksumBuf[1] = nFileChecksum >> 16; + arrChecksumBuf[2] = nFileChecksum >> 8; + arrChecksumBuf[3] = nFileChecksum; + pOutputStream->Write((BYTE*)arrChecksumBuf, 4); + pOutputStream->Write((BYTE*)((char *)m_sFile + pNewTables[i].nOrigOffset + 12), pNewTables[i].nLen - 12); + } + else + { + for (j = 0; j < pNewTables[i].nLen; ++j) + { + pOutputStream->Write((BYTE*)"\0", 1); + } + } + } + else if (pNewTables[i].unTag == cmapTag && pCodeToGID) + pOutputStream->Write((BYTE*)arrNewCmapTable, pNewTables[i].nLen); + else if (pNewTables[i].unTag == cmapTag && bMissingCmap) + pOutputStream->Write((BYTE*)arrCMapTab, pNewTables[i].nLen); + else if (pNewTables[i].unTag == nameTag && sName) + pOutputStream->Write((BYTE*)arrNewNameTable, pNewTables[i].nLen); + else if (pNewTables[i].unTag == nameTag && bMissingName) + pOutputStream->Write((BYTE*)arrNameTab, pNewTables[i].nLen); + else if (pNewTables[i].unTag == postTag && bMissingPost) + pOutputStream->Write((BYTE*)arrPostTab, pNewTables[i].nLen); + else if (pNewTables[i].unTag == os2Tag && bMissingOS2) + pOutputStream->Write((BYTE*)arrOS2Tab, pNewTables[i].nLen); + else if (pNewTables[i].unTag == hheaTag && abbrevHMTX) + pOutputStream->Write((BYTE*)arrNewHHEATable, pNewTables[i].nLen); + else if (pNewTables[i].unTag == hmtxTag && abbrevHMTX) + pOutputStream->Write((BYTE*)arrNewHMTXTable, pNewTables[i].nLen); + else if (pNewTables[i].unTag == locaTag && (bUnsortedLoca || pCodeToGID)) + { + for (j = 0; j <= m_nGlyphs; ++j) + { + if (m_nLocaFormat) + { + arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 24); + arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 16); + arrLocaBuf[2] = (char)(pLocaTable[j].nNewOffset >> 8); + arrLocaBuf[3] = (char)pLocaTable[j].nNewOffset; + pOutputStream->Write((BYTE*)arrLocaBuf, 4); + } + else + { + arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 9); + arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 1); + pOutputStream->Write((BYTE*)arrLocaBuf, 2); + } + } + } + else if (pNewTables[i].unTag == glyfTag && (bUnsortedLoca || pCodeToGID)) + { + nPos = m_pTables[SeekTable("glyf")].nOffset; + + for (j = 0; j < m_nGlyphs; ++j) + { + n = pLocaTable[j].nLen; + if (n > 0) + { + k = pLocaTable[j].nOrigOffset; + if (CheckRegion(nPos + k, n)) + { + pOutputStream->Write((BYTE*)((char *)m_sFile + nPos + k), n); + } + else + { + for (k = 0; k < n; ++k) + { + pOutputStream->Write((BYTE*)"\0", 1); + } + } + if ((k = pLocaTable[j].nLen & 3)) + { + pOutputStream->Write((BYTE*)"\0\0\0\0", 4 - k); + } + } + } + } + else + { + if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) + { + pOutputStream->Write((BYTE*)((char *)m_sFile + pNewTables[i].nOrigOffset), pNewTables[i].nLen); + } + else + { + for (j = 0; j < pNewTables[i].nLen; ++j) + { + pOutputStream->Write((BYTE*)"\0", 1); + } + } + } + if (pNewTables[i].nLen & 3) + { + pOutputStream->Write((BYTE*)"\0\0\0", 4 - (pNewTables[i].nLen & 3)); + } + } + } + + delete[]pUseTable; + free(arrNewHMTXTable); + free(arrNewHHEATable); + free(arrNewCmapTable); + free(arrNewNameTable); + free(arrTableDir); + free(pNewTables); + free(pLocaTable); + } + void CFontFileTrueType::WriteOTF(CStream* pOutputStream, char* sName, unsigned short* pCodeToGID) + { + if (!m_bOpenTypeCFF || SeekTable("CFF ") < 0) + return; + + // Open Type Font записываем так как он есть, не изменяя его + pOutputStream->Write((BYTE*)m_sFile, m_nLen); + + return; + } + int CFontFileTrueType::GetAscent() + { + return m_nAscent; + } + int CFontFileTrueType::GetDescent() + { + return m_nDescent; + } + int CFontFileTrueType::GetCapHeight() + { + return m_nCapHeight; + } + int* CFontFileTrueType::GetBBox() + { + return m_arrBBox; + } + int CFontFileTrueType::GetWeight() + { + return m_nWeight; + } + unsigned int CFontFileTrueType::ComputeTableChecksum(unsigned char *sData, int nLength) + { + unsigned int nWord = 0; + + unsigned int nChecksum = 0; + for (int nIndex = 0; nIndex + 3 < nLength; nIndex += 4) + { + nWord = ((sData[nIndex] & 0xff) << 24) + ((sData[nIndex + 1] & 0xff) << 16) + ((sData[nIndex + 2] & 0xff) << 8) + (sData[nIndex + 3] & 0xff); + nChecksum += nWord; + } + if (nLength & 3) + { + nWord = 0; + int nTemp = nLength & ~3; + switch (nLength & 3) + { + case 3: + nWord |= (sData[nTemp + 2] & 0xff) << 8; + case 2: + nWord |= (sData[nTemp + 1] & 0xff) << 16; + case 1: + nWord |= (sData[nTemp] & 0xff) << 24; + break; + } + nChecksum += nWord; + } + return nChecksum; + } + void CFontFileTrueType::Parse() + { + int nPos = 0, nIndex = 0, nJ; + + m_bSuccess = true; + + // Проверяем является ли данный файл (TTC) + unsigned int unTopTag = GetU32BE(0, &m_bSuccess); + if (!m_bSuccess) + return; + + if (unTopTag == ttcfTag) + { + unsigned int unVersion = GetU32BE(4, &m_bSuccess); + unsigned int unNumFonts = GetU32BE(8, &m_bSuccess); + unsigned int unFontIndex = m_unFontIndex >= unNumFonts ? 0 : m_unFontIndex; + nPos = GetU32BE(12 + 4 * unFontIndex, &m_bSuccess); + if (!m_bSuccess) + return; + } + else + nPos = 0; + + // Проверяем sfnt версию + int nSfntVersion = GetU32BE(nPos, &m_bSuccess); + if (!m_bSuccess) + return; + + // Проверяем на формат данных. CCF или нет? + m_bOpenTypeCFF = (nSfntVersion == 0x4f54544f); // 'OTTO' + + m_nTablesCount = GetU16BE(nPos + 4, &m_bSuccess); + if (!m_bSuccess) + return; + + m_pTables = (TrueTypeTable *)malloc(m_nTablesCount * sizeof(TrueTypeTable)); + nPos += 12; + + for (nIndex = 0; nIndex < m_nTablesCount; ++nIndex) + { + m_pTables[nIndex].unTag = GetU32BE(nPos, &m_bSuccess); + m_pTables[nIndex].unChecksum = GetU32BE(nPos + 4, &m_bSuccess); + m_pTables[nIndex].nOffset = (int)GetU32BE(nPos + 8, &m_bSuccess); + m_pTables[nIndex].nLen = (int)GetU32BE(nPos + 12, &m_bSuccess); + if (m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen < m_pTables[nIndex].nOffset || m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen > m_nLen) + { + m_bSuccess = false; + } + nPos += 16; + } + if (!m_bSuccess) + return; + + // ищем таблицы необходимые как и для TrueType так и для Type 42 + if (SeekTable("head") < 0 || SeekTable("hhea") < 0 || SeekTable("maxp") < 0 || SeekTable("hmtx") < 0 || (!m_bOpenTypeCFF && SeekTable("loca") < 0) || (!m_bOpenTypeCFF && SeekTable("glyf") < 0) || (m_bOpenTypeCFF && SeekTable("CFF ") < 0)) + { + m_bSuccess = false; + return; + } + + // читаем таблицы CMaps + if ((nIndex = SeekTable("cmap")) >= 0) + { + nPos = m_pTables[nIndex].nOffset + 2; + m_nCMapsCount = GetU16BE(nPos, &m_bSuccess); + nPos += 2; + if (!m_bSuccess) + return; + + m_pCMaps = (TrueTypeCmap *)malloc(m_nCMapsCount * sizeof(TrueTypeCmap)); + + for (nJ = 0; nJ < m_nCMapsCount; ++nJ) + { + m_pCMaps[nJ].nPlatform = GetU16BE(nPos, &m_bSuccess); + m_pCMaps[nJ].nEncoding = GetU16BE(nPos + 2, &m_bSuccess); + unsigned int nTemp = GetU32BE(nPos + 4, &m_bSuccess); + m_pCMaps[nJ].nOffset = m_pTables[nIndex].nOffset + GetU32BE(nPos + 4, &m_bSuccess); + nPos += 8; + m_pCMaps[nJ].nFormat = GetU16BE(m_pCMaps[nJ].nOffset, &m_bSuccess); + m_pCMaps[nJ].nLen = GetU16BE(m_pCMaps[nJ].nOffset + 2, &m_bSuccess); + } + if (!m_bSuccess) + return; + } + else + m_nCMapsCount = 0; + + nIndex = SeekTable("maxp"); + m_nGlyphs = GetU16BE(m_pTables[nIndex].nOffset + 4, &m_bSuccess); + if (!m_bSuccess) + return; + + nIndex = SeekTable("head"); + m_arrBBox[0] = GetS16BE(m_pTables[nIndex].nOffset + 36, &m_bSuccess); + m_arrBBox[1] = GetS16BE(m_pTables[nIndex].nOffset + 38, &m_bSuccess); + m_arrBBox[2] = GetS16BE(m_pTables[nIndex].nOffset + 40, &m_bSuccess); + m_arrBBox[3] = GetS16BE(m_pTables[nIndex].nOffset + 42, &m_bSuccess); + m_nLocaFormat = GetS16BE(m_pTables[nIndex].nOffset + 50, &m_bSuccess); + if (!m_bSuccess) + return; + + // Проверяем корректность таблицы loca + if (!m_bOpenTypeCFF) + { + nIndex = SeekTable("loca"); + if (m_pTables[nIndex].nLen < 0) + { + m_bSuccess = false; + return; + } + if (m_pTables[nIndex].nLen < (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2)) + { + m_nGlyphs = m_pTables[nIndex].nLen / (m_nLocaFormat ? 4 : 2) - 1; + } + for (nJ = 0; nJ <= m_nGlyphs; ++nJ) + { + if (m_nLocaFormat) + nPos = (int)GetU32BE(m_pTables[nIndex].nOffset + nJ * 4, &m_bSuccess); + else + nPos = GetU16BE(m_pTables[nIndex].nOffset + nJ * 2, &m_bSuccess); + + if (nPos < 0 || nPos > m_nLen) + m_bSuccess = false; + } + if (!m_bSuccess) + return; + } + + ReadOS2(); + } + int CFontFileTrueType::SeekTable(const char *sTag) + { + unsigned int nTagIndex = ((sTag[0] & 0xff) << 24) | ((sTag[1] & 0xff) << 16) | ((sTag[2] & 0xff) << 8) | (sTag[3] & 0xff); + for (int nIndex = 0; nIndex < m_nTablesCount; ++nIndex) + { + if (m_pTables[nIndex].unTag == nTagIndex) + { + return nIndex; + } + } + return -1; + } + void CFontFileTrueType::ReadOS2() + { + int nIndex = SeekTable("OS/2"); + if (-1 != nIndex && m_pTables[nIndex].nLen > 0) + { + unsigned int unOffset = m_pTables[nIndex].nOffset; + m_nWeight = GetS16BE(unOffset + 4, &m_bSuccess); + m_nAscent = GetS16BE(unOffset + 68, &m_bSuccess); + m_nDescent = GetS16BE(unOffset + 70, &m_bSuccess); + m_nCapHeight = GetS16BE(unOffset + 88, &m_bSuccess); + } + } +} diff --git a/PdfWriter/Src/FontTTWriter.h b/PdfFile/SrcWriter/FontTTWriter.h similarity index 97% rename from PdfWriter/Src/FontTTWriter.h rename to PdfFile/SrcWriter/FontTTWriter.h index 4674ccfbb5..f4e9374e06 100644 --- a/PdfWriter/Src/FontTTWriter.h +++ b/PdfFile/SrcWriter/FontTTWriter.h @@ -1,126 +1,126 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_TTWRITER_H -#define _PDF_WRITER_SRC_TTWRITER_H - -#include "Streams.h" - -namespace PdfWriter -{ - struct TrueTypeTable; - struct TrueTypeCmap; - //---------------------------------------------------------------------------------------- - // CFontFileBase - //---------------------------------------------------------------------------------------- - class CFontFileBase - { - public: - - virtual ~CFontFileBase(); - - protected: - - CFontFileBase(char *sFile, int nLen, bool bFreeFileData); - - static char *ReadFile(const std::wstring & wsFileName, int *pnFileLen); - int GetS8(int nPos, bool *pbSuccess); - int GetU8(int nPos, bool *pbSuccess); - int GetS16BE(int nPos, bool *pbSuccess); - int GetU16BE(int nPos, bool *pbSuccess); - int GetS32BE(int nPos, bool *pbSuccess); - unsigned int GetU32BE(int nPos, bool *pbSuccess); - unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess); - bool CheckRegion(int nPos, int nSize); - - protected: - - unsigned char *m_sFileData; - unsigned char *m_sFile; - int m_nLen; - bool m_bFreeFileData; - - }; - //---------------------------------------------------------------------------------------- - // CFontFileTrueType - //---------------------------------------------------------------------------------------- - class CFontFileTrueType : public CFontFileBase - { - public: - - static CFontFileTrueType *LoadFromBuffer(char* sBuffer, int nLen, unsigned int unIndex); - static CFontFileTrueType *LoadFromFile(const std::wstring& wsFileName, unsigned int unIndex); - ~CFontFileTrueType(); - - // Записываем TrueTypeFont File, заполняя недостающие таблицы и корректируя - // различные ошибки. Если задан парметр , в шрифте переписываем таблицу - // 'name'. Если задан парамтре , тогда в шрифте переписываем - // таблицу 'cmap'. - void WriteTTF(CStream* pOutputStream, char *sName = NULL, unsigned short *pCodeToGID = NULL, unsigned int unCodesCount = 0, unsigned char *pUseGlyfs = NULL, long lGlyfsCount = 0); - void WriteOTF(CStream* pOutputStream, char *sName = NULL, unsigned short *pCodeToGID = NULL); - - int GetAscent(); - int GetDescent(); - int GetCapHeight(); - int* GetBBox(); - int GetWeight(); - - private: - - CFontFileTrueType(char *sBuffer, int nLen, bool bFreeFileData, unsigned int unFontIndex); - - unsigned int ComputeTableChecksum(unsigned char *sData, int nLength); - void Parse(); - int SeekTable(const char *sTag); - void ReadOS2(); - - private: - - unsigned int m_unFontIndex; - TrueTypeTable* m_pTables; - int m_nTablesCount; - TrueTypeCmap* m_pCMaps; - int m_nCMapsCount; - int m_nGlyphs; - int m_nLocaFormat; - int m_arrBBox[4]; - bool m_bOpenTypeCFF; - - int m_nAscent; - int m_nDescent; - int m_nCapHeight; - int m_nWeight; - - bool m_bSuccess; - }; -} - -#endif // _PDF_WRITER_SRC_TTWRITER_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_TTWRITER_H +#define _PDF_WRITER_SRC_TTWRITER_H + +#include "Streams.h" + +namespace PdfWriter +{ + struct TrueTypeTable; + struct TrueTypeCmap; + //---------------------------------------------------------------------------------------- + // CFontFileBase + //---------------------------------------------------------------------------------------- + class CFontFileBase + { + public: + + virtual ~CFontFileBase(); + + protected: + + CFontFileBase(char *sFile, int nLen, bool bFreeFileData); + + static char *ReadFile(const std::wstring & wsFileName, int *pnFileLen); + int GetS8(int nPos, bool *pbSuccess); + int GetU8(int nPos, bool *pbSuccess); + int GetS16BE(int nPos, bool *pbSuccess); + int GetU16BE(int nPos, bool *pbSuccess); + int GetS32BE(int nPos, bool *pbSuccess); + unsigned int GetU32BE(int nPos, bool *pbSuccess); + unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess); + bool CheckRegion(int nPos, int nSize); + + protected: + + unsigned char *m_sFileData; + unsigned char *m_sFile; + int m_nLen; + bool m_bFreeFileData; + + }; + //---------------------------------------------------------------------------------------- + // CFontFileTrueType + //---------------------------------------------------------------------------------------- + class CFontFileTrueType : public CFontFileBase + { + public: + + static CFontFileTrueType *LoadFromBuffer(char* sBuffer, int nLen, unsigned int unIndex); + static CFontFileTrueType *LoadFromFile(const std::wstring& wsFileName, unsigned int unIndex); + ~CFontFileTrueType(); + + // Записываем TrueTypeFont File, заполняя недостающие таблицы и корректируя + // различные ошибки. Если задан парметр , в шрифте переписываем таблицу + // 'name'. Если задан парамтре , тогда в шрифте переписываем + // таблицу 'cmap'. + void WriteTTF(CStream* pOutputStream, char *sName = NULL, unsigned short *pCodeToGID = NULL, unsigned int unCodesCount = 0, unsigned char *pUseGlyfs = NULL, long lGlyfsCount = 0); + void WriteOTF(CStream* pOutputStream, char *sName = NULL, unsigned short *pCodeToGID = NULL); + + int GetAscent(); + int GetDescent(); + int GetCapHeight(); + int* GetBBox(); + int GetWeight(); + + private: + + CFontFileTrueType(char *sBuffer, int nLen, bool bFreeFileData, unsigned int unFontIndex); + + unsigned int ComputeTableChecksum(unsigned char *sData, int nLength); + void Parse(); + int SeekTable(const char *sTag); + void ReadOS2(); + + private: + + unsigned int m_unFontIndex; + TrueTypeTable* m_pTables; + int m_nTablesCount; + TrueTypeCmap* m_pCMaps; + int m_nCMapsCount; + int m_nGlyphs; + int m_nLocaFormat; + int m_arrBBox[4]; + bool m_bOpenTypeCFF; + + int m_nAscent; + int m_nDescent; + int m_nCapHeight; + int m_nWeight; + + bool m_bSuccess; + }; +} + +#endif // _PDF_WRITER_SRC_TTWRITER_H diff --git a/PdfWriter/Src/GState.cpp b/PdfFile/SrcWriter/GState.cpp similarity index 96% rename from PdfWriter/Src/GState.cpp rename to PdfFile/SrcWriter/GState.cpp index 3b74ddf033..f32b5aceea 100644 --- a/PdfWriter/Src/GState.cpp +++ b/PdfFile/SrcWriter/GState.cpp @@ -1,159 +1,159 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "GState.h" - -namespace PdfWriter -{ - const static char* c_sBlendModeNames[] = - { - "Normal", - "Multiply", - "Screen", - "Overlay", - "Darken", - "Lighten", - "ColorDodge", - "ColorBurn", - "HardLight", - "SoftLight", - "Difference", - "Exclusion" - }; - //---------------------------------------------------------------------------------------- - // CGrState - //---------------------------------------------------------------------------------------- - CGrState::CGrState(CGrState* pCurrent) - { - if (pCurrent) - { - m_oMatrix = pCurrent->m_oMatrix; - m_dLineWidth = pCurrent->m_dLineWidth; - m_eLineCap = pCurrent->m_eLineCap; - m_eLineJoin = pCurrent->m_eLineJoin; - m_dMiterLimit = pCurrent->m_dMiterLimit; - m_oDashMode = pCurrent->m_oDashMode; - m_dFlatness = pCurrent->m_dFlatness; - - m_dCharSpace = pCurrent->m_dCharSpace; - m_dWordSpace = pCurrent->m_dWordSpace; - m_dHScalling = pCurrent->m_dHScalling; - m_dTextLeading = pCurrent->m_dTextLeading; - m_eRenderingMode = pCurrent->m_eRenderingMode; - m_dTextRise = pCurrent->m_dTextRise; - - m_oFillColor = pCurrent->m_oFillColor; - m_oStrokeColor = pCurrent->m_oStrokeColor; - - m_pFont = pCurrent->m_pFont; - m_dFontSize = pCurrent->m_dFontSize; - - m_pPrev = pCurrent; - m_unDepth = pCurrent->m_unDepth + 1; - } - else - { - m_dLineWidth = DEF_LINEWIDTH; - m_eLineCap = DEF_LINECAP; - m_eLineJoin = DEF_LINEJOIN; - m_dMiterLimit = DEF_MITERLIMIT; - m_dFlatness = DEF_FLATNESS; - - m_dCharSpace = DEF_CHARSPACE; - m_dWordSpace = DEF_WORDSPACE; - m_dHScalling = DEF_HSCALING; - m_dTextLeading = DEF_LEADING; - m_eRenderingMode = DEF_RENDERING_MODE; - m_dTextRise = DEF_RISE; - - m_pFont = NULL; - m_dFontSize = 0; - - m_pPrev = NULL; - m_unDepth = 1; - } - } - CGrState::~CGrState() - { - } - //---------------------------------------------------------------------------------------- - // CExtGrState - //---------------------------------------------------------------------------------------- - CExtGrState::CExtGrState(CXref* pXref) - { - pXref->Add(this); - Add("Type", "ExtGState"); - - m_eBlendMode = blendmode_Unknown; - m_dAlphaFill = 1; - m_dAlphaStroke = 1; - m_bStrokeAdj = true; - } - void CExtGrState::SetAlphaStroke (double dValue) - { - dValue = std::min(1.0, std::max(0.0, dValue)); - Add("CA", dValue); - m_dAlphaStroke = dValue; - } - void CExtGrState::SetAlphaFill (double dValue) - { - dValue = std::min(1.0, std::max(0.0, dValue)); - Add("ca", dValue); - m_dAlphaFill = dValue; - } - void CExtGrState::SetBlendMode (EBlendMode eBlendMode) - { - eBlendMode = std::min(blendmode_Max, std::max(blendmode_Min, eBlendMode)); - Add("BM", c_sBlendModeNames[(int)eBlendMode]); - m_eBlendMode = eBlendMode; - } - void CExtGrState::SetStrokeAdjustment(bool bValue) - { - Add("SA", bValue); - m_bStrokeAdj = bValue; - } - double CExtGrState::GetAlphaStroke() - { - return m_dAlphaStroke; - } - double CExtGrState::GetAlphaFill() - { - return m_dAlphaFill; - } - EBlendMode CExtGrState::GetBlendMode() - { - return m_eBlendMode; - } - bool CExtGrState::GetStrokeAdjustment() - { - return m_bStrokeAdj; - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "GState.h" + +namespace PdfWriter +{ + const static char* c_sBlendModeNames[] = + { + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDodge", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + }; + //---------------------------------------------------------------------------------------- + // CGrState + //---------------------------------------------------------------------------------------- + CGrState::CGrState(CGrState* pCurrent) + { + if (pCurrent) + { + m_oMatrix = pCurrent->m_oMatrix; + m_dLineWidth = pCurrent->m_dLineWidth; + m_eLineCap = pCurrent->m_eLineCap; + m_eLineJoin = pCurrent->m_eLineJoin; + m_dMiterLimit = pCurrent->m_dMiterLimit; + m_oDashMode = pCurrent->m_oDashMode; + m_dFlatness = pCurrent->m_dFlatness; + + m_dCharSpace = pCurrent->m_dCharSpace; + m_dWordSpace = pCurrent->m_dWordSpace; + m_dHScalling = pCurrent->m_dHScalling; + m_dTextLeading = pCurrent->m_dTextLeading; + m_eRenderingMode = pCurrent->m_eRenderingMode; + m_dTextRise = pCurrent->m_dTextRise; + + m_oFillColor = pCurrent->m_oFillColor; + m_oStrokeColor = pCurrent->m_oStrokeColor; + + m_pFont = pCurrent->m_pFont; + m_dFontSize = pCurrent->m_dFontSize; + + m_pPrev = pCurrent; + m_unDepth = pCurrent->m_unDepth + 1; + } + else + { + m_dLineWidth = DEF_LINEWIDTH; + m_eLineCap = DEF_LINECAP; + m_eLineJoin = DEF_LINEJOIN; + m_dMiterLimit = DEF_MITERLIMIT; + m_dFlatness = DEF_FLATNESS; + + m_dCharSpace = DEF_CHARSPACE; + m_dWordSpace = DEF_WORDSPACE; + m_dHScalling = DEF_HSCALING; + m_dTextLeading = DEF_LEADING; + m_eRenderingMode = DEF_RENDERING_MODE; + m_dTextRise = DEF_RISE; + + m_pFont = NULL; + m_dFontSize = 0; + + m_pPrev = NULL; + m_unDepth = 1; + } + } + CGrState::~CGrState() + { + } + //---------------------------------------------------------------------------------------- + // CExtGrState + //---------------------------------------------------------------------------------------- + CExtGrState::CExtGrState(CXref* pXref) + { + pXref->Add(this); + Add("Type", "ExtGState"); + + m_eBlendMode = blendmode_Unknown; + m_dAlphaFill = 1; + m_dAlphaStroke = 1; + m_bStrokeAdj = true; + } + void CExtGrState::SetAlphaStroke (double dValue) + { + dValue = std::min(1.0, std::max(0.0, dValue)); + Add("CA", dValue); + m_dAlphaStroke = dValue; + } + void CExtGrState::SetAlphaFill (double dValue) + { + dValue = std::min(1.0, std::max(0.0, dValue)); + Add("ca", dValue); + m_dAlphaFill = dValue; + } + void CExtGrState::SetBlendMode (EBlendMode eBlendMode) + { + eBlendMode = std::min(blendmode_Max, std::max(blendmode_Min, eBlendMode)); + Add("BM", c_sBlendModeNames[(int)eBlendMode]); + m_eBlendMode = eBlendMode; + } + void CExtGrState::SetStrokeAdjustment(bool bValue) + { + Add("SA", bValue); + m_bStrokeAdj = bValue; + } + double CExtGrState::GetAlphaStroke() + { + return m_dAlphaStroke; + } + double CExtGrState::GetAlphaFill() + { + return m_dAlphaFill; + } + EBlendMode CExtGrState::GetBlendMode() + { + return m_eBlendMode; + } + bool CExtGrState::GetStrokeAdjustment() + { + return m_bStrokeAdj; + } +} diff --git a/PdfWriter/Src/GState.h b/PdfFile/SrcWriter/GState.h similarity index 96% rename from PdfWriter/Src/GState.h rename to PdfFile/SrcWriter/GState.h index e7d1c0ecc4..4aebfed60b 100644 --- a/PdfWriter/Src/GState.h +++ b/PdfFile/SrcWriter/GState.h @@ -1,132 +1,132 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_GSTATE_H -#define _PDF_WRITER_SRC_GSTATE_H - -#include "Types.h" -#include "Objects.h" - -// Стандартные значения для Graphic State -#define DEF_FONT "Helvetica" -#define DEF_WORDSPACE 0 -#define DEF_CHARSPACE 0 -#define DEF_FONTSIZE 10 -#define DEF_HSCALING 100 -#define DEF_LEADING 0 -#define DEF_RENDERING_MODE PdfWriter::textrenderingmode_Fill -#define DEF_RISE 0 -#define DEF_LINEWIDTH 1 -#define DEF_LINECAP PdfWriter::linecap_Butt -#define DEF_LINEJOIN PdfWriter::linejoin_Miter -#define DEF_MITERLIMIT 10 -#define DEF_FLATNESS 1 -#define DEF_PAGE_NUM 1 - -namespace PdfWriter -{ - class CFontDict; - class CDictObject; - //---------------------------------------------------------------------------------------- - // CGrState - //---------------------------------------------------------------------------------------- - class CGrState - { - public: - - CGrState(CGrState* pCurrent); - ~CGrState(); - CGrState* GetPrev() - { - return m_pPrev; - } - unsigned int GetDepth() - { - return m_unDepth; - } - - private: - - CMatrix m_oMatrix; - double m_dLineWidth; - ELineCapStyle m_eLineCap; - ELineJoinStyle m_eLineJoin; - double m_dMiterLimit; - CDashMode m_oDashMode; - double m_dFlatness; - - double m_dCharSpace; - double m_dWordSpace; - double m_dHScalling; - double m_dTextLeading; - ETextRenderingMode m_eRenderingMode; - double m_dTextRise; - - TRgb m_oFillColor; - TRgb m_oStrokeColor; - - CFontDict* m_pFont; - double m_dFontSize; - - CGrState* m_pPrev; - unsigned int m_unDepth; - - friend class CPage; - }; - //---------------------------------------------------------------------------------------- - // CExtGrState - //---------------------------------------------------------------------------------------- - class CExtGrState : public CDictObject - { - public: - CExtGrState(CXref* pXref); - void SetAlphaStroke (double dValue); - void SetAlphaFill (double dValue); - void SetBlendMode (EBlendMode eBlendMode); - void SetStrokeAdjustment(bool bValue); - double GetAlphaStroke(); - double GetAlphaFill(); - EBlendMode GetBlendMode(); - bool GetStrokeAdjustment(); - EDictType GetDictType() const - { - return dict_type_EXT_GSTATE; - } - private: - double m_dAlphaStroke; - double m_dAlphaFill; - EBlendMode m_eBlendMode; - bool m_bStrokeAdj; - }; -} - -#endif // _PDF_WRITER_SRC_GSTATE_H - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_GSTATE_H +#define _PDF_WRITER_SRC_GSTATE_H + +#include "Types.h" +#include "Objects.h" + +// Стандартные значения для Graphic State +#define DEF_FONT "Helvetica" +#define DEF_WORDSPACE 0 +#define DEF_CHARSPACE 0 +#define DEF_FONTSIZE 10 +#define DEF_HSCALING 100 +#define DEF_LEADING 0 +#define DEF_RENDERING_MODE PdfWriter::textrenderingmode_Fill +#define DEF_RISE 0 +#define DEF_LINEWIDTH 1 +#define DEF_LINECAP PdfWriter::linecap_Butt +#define DEF_LINEJOIN PdfWriter::linejoin_Miter +#define DEF_MITERLIMIT 10 +#define DEF_FLATNESS 1 +#define DEF_PAGE_NUM 1 + +namespace PdfWriter +{ + class CFontDict; + class CDictObject; + //---------------------------------------------------------------------------------------- + // CGrState + //---------------------------------------------------------------------------------------- + class CGrState + { + public: + + CGrState(CGrState* pCurrent); + ~CGrState(); + CGrState* GetPrev() + { + return m_pPrev; + } + unsigned int GetDepth() + { + return m_unDepth; + } + + private: + + CMatrix m_oMatrix; + double m_dLineWidth; + ELineCapStyle m_eLineCap; + ELineJoinStyle m_eLineJoin; + double m_dMiterLimit; + CDashMode m_oDashMode; + double m_dFlatness; + + double m_dCharSpace; + double m_dWordSpace; + double m_dHScalling; + double m_dTextLeading; + ETextRenderingMode m_eRenderingMode; + double m_dTextRise; + + TRgb m_oFillColor; + TRgb m_oStrokeColor; + + CFontDict* m_pFont; + double m_dFontSize; + + CGrState* m_pPrev; + unsigned int m_unDepth; + + friend class CPage; + }; + //---------------------------------------------------------------------------------------- + // CExtGrState + //---------------------------------------------------------------------------------------- + class CExtGrState : public CDictObject + { + public: + CExtGrState(CXref* pXref); + void SetAlphaStroke (double dValue); + void SetAlphaFill (double dValue); + void SetBlendMode (EBlendMode eBlendMode); + void SetStrokeAdjustment(bool bValue); + double GetAlphaStroke(); + double GetAlphaFill(); + EBlendMode GetBlendMode(); + bool GetStrokeAdjustment(); + EDictType GetDictType() const + { + return dict_type_EXT_GSTATE; + } + private: + double m_dAlphaStroke; + double m_dAlphaFill; + EBlendMode m_eBlendMode; + bool m_bStrokeAdj; + }; +} + +#endif // _PDF_WRITER_SRC_GSTATE_H + diff --git a/PdfWriter/Src/ICCProfile.h b/PdfFile/SrcWriter/ICCProfile.h similarity index 100% rename from PdfWriter/Src/ICCProfile.h rename to PdfFile/SrcWriter/ICCProfile.h diff --git a/PdfWriter/Src/Image.cpp b/PdfFile/SrcWriter/Image.cpp similarity index 96% rename from PdfWriter/Src/Image.cpp rename to PdfFile/SrcWriter/Image.cpp index a45a999bd5..e5902529c5 100644 --- a/PdfWriter/Src/Image.cpp +++ b/PdfFile/SrcWriter/Image.cpp @@ -1,569 +1,569 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Image.h" -#include "Streams.h" -#include "Document.h" - -// TODO: write JPG from Photoshop... -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/raster/BgraFrame.h" - -namespace NSImageReSaver -{ - static void CorrectImage(const wchar_t* wsFileName, BYTE*& pBuffer, int& nBufferSize, unsigned int& unWidth, unsigned int& unHeight) - { - pBuffer = NULL; - nBufferSize = 0; - - CImageFileFormatChecker oChecker(wsFileName); - if (oChecker.eFileType != _CXIMAGE_FORMAT_JPG) - return; - - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(wsFileName)) - return; - - if (20 > oFile.GetFileSize()) - return; - - BYTE data[20]; - DWORD dwRead = 0; - if (!oFile.ReadFile(data, 20, dwRead)) - return; - - std::string sFind((char*)data, 20); - oFile.CloseFile(); - - if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) - return; - - CBgraFrame oFrame; - if (!oFrame.OpenFile(wsFileName)) - return; - - oFrame.SetJpegQuality(85.0); - if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) - return; - - if (!pBuffer || !nBufferSize) - return; - - unWidth = (unsigned int)oFrame.get_Width(); - unHeight = (unsigned int)oFrame.get_Height(); - } -} - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CImageDict - //---------------------------------------------------------------------------------------- - CImageDict::CImageDict(CXref* pXref, CDocument* pDocument) - { - m_pXref = pXref; - m_pDocument = pDocument; - } - void CImageDict::LoadJpeg(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight, bool bGrayScale) - { - BYTE* pCorrectBuffer = NULL; - int nBufferSize = 0; - NSImageReSaver::CorrectImage(wsFilePath, pCorrectBuffer, nBufferSize, unWidth, unHeight); - - if (pCorrectBuffer != NULL) - { - this->LoadJpeg(pCorrectBuffer, nBufferSize, unWidth, unHeight, bGrayScale); - free(pCorrectBuffer); - return; - } - - - CImageFileStream* pStream = new CImageFileStream(); - if (!pStream) - return; - - pStream->OpenFile(wsFilePath); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - - if (bGrayScale) - Add("ColorSpace", "DeviceGray"); - else - Add("ColorSpace", "DeviceRGB"); - - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_DCT_DECODE); - } - void CImageDict::LoadJpeg(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight, bool bGrayScale) - { - CMemoryStream* pStream = new CMemoryStream(); - if (!pStream) - return; - - pStream->Write(pBuffer, nBufferSize); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - - if (bGrayScale) - Add("ColorSpace", "DeviceGray"); - else - Add("ColorSpace", "DeviceRGB"); - - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_DCT_DECODE); - } - void CImageDict::LoadJpx(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight) - { - CImageFileStream* pStream = new CImageFileStream(); - if (!pStream) - return; - - pStream->OpenFile(wsFilePath); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceRGB"); - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_JPX_DECODE); - } - void CImageDict::LoadJpx(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight) - { - CMemoryStream* pStream = new CMemoryStream(); - if (!pStream) - return; - - pStream->Write(pBuffer, nBufferSize); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceRGB"); - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_JPX_DECODE); - } - void CImageDict::LoadJb2(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight) - { - CImageFileStream* pStream = new CImageFileStream(); - if (!pStream) - return; - - pStream->OpenFile(wsFilePath); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceGray"); - Add("BitsPerComponent", 1); - SetFilter(STREAM_FILTER_JBIG2_DECODE); - } - void CImageDict::LoadCCITT4(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight) - { - CImageFileStream* pStream = new CImageFileStream(); - if (!pStream) - return; - - pStream->OpenFile(wsTempFile); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceGray"); - Add("BitsPerComponent", 1); - - CArrayObject* pDecodeParams = new CArrayObject(); - CDictObject* pParams = new CDictObject(); - pDecodeParams->Add(pParams); - pParams->Add("K", 0); - pParams->Add("Columns", unWidth); - pParams->Add("EncodedByteAlign", true); - Add("DecodeParams", pDecodeParams); - - SetFilter(STREAM_FILTER_CCITT_DECODE); - - } - void CImageDict::LoadRaw(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight) - { - CMemoryStream* pStream = new CMemoryStream(3 * unWidth * unHeight); - if (!pStream) - return; - - for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) - { - pStream->Write(pBgra + unIndex, 3); - } - - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("ColorSpace", "DeviceRGB"); - Add("Width", unWidth); - Add("Height", unHeight); - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_FLATE_DECODE); - } - void CImageDict::LoadRaw(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight) - { - CMemoryStream* pStream = new CMemoryStream(unSize); - if (!pStream) - return; - pStream->Write(pBuffer, unSize); - SetStream(m_pXref, pStream); - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("ColorSpace", "DeviceRGB"); - Add("Width", unWidth); - Add("Height", unHeight); - Add("BitsPerComponent", 8); - SetFilter(STREAM_FILTER_FLATE_DECODE); - } - void CImageDict::LoadSMask(CMemoryStream* pStream, const unsigned int unWidth, const unsigned int& unHeight) - { - CImageDict* pImageSMask = new CImageDict(m_pXref, m_pDocument); - if (!pImageSMask) - return; - - pImageSMask->SetStream(m_pXref, pStream); - pImageSMask->Add("Type", "XObject"); - pImageSMask->Add("Subtype", "Image"); - pImageSMask->Add("ColorSpace", "DeviceGray"); - pImageSMask->Add("Width", unWidth); - pImageSMask->Add("Height", unHeight); - pImageSMask->Add("BitsPerComponent", 8); - -//#ifndef FILTER_FLATE_DECODE_DISABLED -// pImageSMask->SetFilter(STREAM_FILTER_LZW_DECODE | STREAM_FILTER_FLATE_DECODE); -//#else - pImageSMask->SetFilter(STREAM_FILTER_FLATE_DECODE); -//#endif - - Add("SMask", pImageSMask); - } - void CImageDict::LoadSMask(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight, unsigned char unAlpha, bool bVerFlip) - { - if (m_pDocument->IsPDFA()) - return; - - CMemoryStream* pStream = new CMemoryStream(unWidth * unHeight); - if (!pStream) - return; - - if (255 != unAlpha) - { - double dKoef = unAlpha / 255.0; - - if (!bVerFlip) - { - for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) - { - BYTE nChar = *(pBgra + unIndex + 3) * dKoef; - pStream->Write(&nChar, 1); - } - } - else - { - int nWidth = (int)unWidth; - int nHeight = (int)unHeight; - for (int nY = nHeight - 1; nY >= 0; nY--) - { - for (int nX = 0; nX < nWidth; nX++) - { - int unIndex = 4 * (nX + nY * nWidth); - BYTE nChar = *(pBgra + unIndex + 3) * dKoef; - pStream->Write(&nChar, 1); - } - } - } - } - else - { - if (!bVerFlip) - { - for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) - { - pStream->Write(pBgra + unIndex + 3, 1); - } - } - else - { - int nWidth = (int)unWidth; - int nHeight = (int)unHeight; - for (int nY = nHeight - 1; nY >= 0; nY--) - { - for (int nX = 0; nX < nWidth; nX++) - { - int unIndex = 4 * (nX + nY * nWidth); - pStream->Write(pBgra + unIndex + 3, 1); - } - } - } - } - - LoadSMask(pStream, unWidth, unHeight); - } - void CImageDict::LoadSMask(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight) - { - CMemoryStream* pStream = new CMemoryStream(unSize); - if (!pStream) - return; - - pStream->Write(pBuffer, unSize); - LoadSMask(pStream, unWidth, unHeight); - } - void CImageDict::LoadSMask(const BYTE& unAlpha, const unsigned int& unWidth, const unsigned int& unHeight) - { - unsigned int unSize = unWidth * unHeight; - CMemoryStream* pStream = new CMemoryStream(unSize); - if (!pStream) - return; - - for (unsigned int unPos = 0; unPos < unSize; unPos++) - pStream->WriteChar(unAlpha); - - LoadSMask(pStream, unWidth, unHeight); - } - void CImageDict::LoadBW(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride) - { - SetStream(m_pXref, new CMemoryStream()); - CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); - pJbig2Global->AddImage(pImage, unWidth, unHeight, unStride, GetStream()); - - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceGray"); - Add("BitsPerComponent", 1); - SetFilter(STREAM_FILTER_JBIG2_DECODE); - - CArrayObject* pDecodeParams = new CArrayObject(); - CDictObject* pParams = new CDictObject(); - pDecodeParams->Add(pParams); - pParams->Add("JBIG2Globals", pJbig2Global); - Add("DecodeParms", pDecodeParams); - } - void CImageDict::LoadBW(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight) - { - SetStream(m_pXref, new CMemoryStream()); - CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); - pJbig2Global->AddImage(pPix, GetStream()); - - Add("Type", "XObject"); - Add("Subtype", "Image"); - Add("Height", unHeight); - Add("Width", unWidth); - Add("ColorSpace", "DeviceGray"); - Add("BitsPerComponent", 1); - SetFilter(STREAM_FILTER_JBIG2_DECODE); - - CArrayObject* pDecodeParams = new CArrayObject(); - CDictObject* pParams = new CDictObject(); - pDecodeParams->Add(pParams); - pParams->Add("JBIG2Globals", pJbig2Global); - Add("DecodeParms", pDecodeParams); - } - void CImageDict::LoadMask(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight) - { - CImageDict* pMask = new CImageDict(m_pXref, m_pDocument); - if (!pMask) - return; - - pMask->SetStream(m_pXref, new CMemoryStream()); - CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); - pJbig2Global->AddImage(pPix, pMask->GetStream()); - - pMask->Add("Type", "XObject"); - pMask->Add("Subtype", "Image"); - pMask->Add("Width", unWidth); - pMask->Add("Height", unHeight); - pMask->Add("BitsPerComponent", 1); - pMask->Add("ImageMask", true); - pMask->SetFilter(STREAM_FILTER_JBIG2_DECODE); - - CArrayObject* pDecodeParams = new CArrayObject(); - CDictObject* pParams = new CDictObject(); - pDecodeParams->Add(pParams); - pParams->Add("JBIG2Globals", pJbig2Global); - pMask->Add("DecodeParms", pDecodeParams); - - Add("Mask", pMask); - } - void CImageDict::AddTransparency(const BYTE& unAlpha) - { - if (CheckSMask()) - { - CImageDict* pSMask = (CImageDict*)Get("SMask"); - CStream* pMaskStream = pSMask->GetStream(); - - pMaskStream->Seek(0, EWhenceMode::SeekEnd); - int nSize = pMaskStream->Tell(); - if (nSize <= 0) - return; - - CMemoryStream* pStream = new CMemoryStream(nSize); - if (!pStream) - return; - - double dKoef = unAlpha / 255.0; - - pMaskStream->Seek(0, EWhenceMode::SeekSet); - while (!pMaskStream->IsEof()) - { - BYTE nChar = pMaskStream->ReadUChar(); - pStream->WriteChar((BYTE)(nChar * dKoef)); - } - - pSMask->SetStream(m_pXref, pStream); - } - else - { - LoadSMask(unAlpha, GetWidth(), GetHeight()); - } - } - unsigned int CImageDict::GetWidth() const - { - return ((unsigned int)((CNumberObject*)this->Get("Width"))->Get()); - } - unsigned int CImageDict::GetHeight() const - { - return ((unsigned int)((CNumberObject*)this->Get("Height"))->Get()); - } - bool CImageDict::CheckSMask() - { - CImageDict* pSMask = (CImageDict*)this->Get("SMask"); - if (!pSMask) - return false; - - CStream* pMaskStream = pSMask->GetStream(); - if (!pMaskStream) - return false; - - CNumberObject* pBits = (CNumberObject*)pSMask->Get("BitsPerComponent"); - if (!pBits || 8 != pBits->Get()) - return false; - - return true; - } - //---------------------------------------------------------------------------------------- - // CJbig2Global - //---------------------------------------------------------------------------------------- - CJbig2Global::CJbig2Global(CXref* pXref) : CDictObject(pXref) - { - m_pXref = pXref; - m_pContext.Init(0.85, 0.5, -1, -1, false, -1); - } - CJbig2Global::~CJbig2Global() - { - m_pContext.Destroy(); - } - void CJbig2Global::FlushStreams() - { - CStream* pStream = GetStream(); - - int nLen = 0; - BYTE* pBuffer = m_pContext.PagesComplete(&nLen); - - if (pBuffer) - { - pStream->Write(pBuffer, nLen); - free(pBuffer); - } - - for (int nIndex = 0, nCount = m_vImages.size(); nIndex < nCount; nIndex++) - { - pBuffer = m_pContext.ProducePage(nIndex, -1, -1, &nLen); - if (pBuffer) - { - pStream = m_vImages.at(nIndex); - if (pStream) - { - pStream->Write(pBuffer, nLen); - } - free(pBuffer); - } - } - - m_pContext.Destroy(); - } - void CJbig2Global::AddImage(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride, CStream* pImageStream) - { - if (!m_pContext.IsInit()) - return; - - NSImages::CPixJbig2 pPix; - if (!pPix.Create(unWidth, unHeight, 1)) - return; - - BYTE* pLine = (BYTE*)pImage; - for (unsigned int unY = 0; unY < unHeight; unY++, pLine += unStride) - { - char nBit = 0; - BYTE* pCur = pLine; - for (unsigned int unX = 0; unX < unWidth; unX++) - { - pPix.SetPixel(unX, unY, pCur[0] & (1 << nBit)); - nBit++; - - if (8 == nBit) - { - nBit = 0; - pCur++; - } - } - } - - m_pContext.AddPage(&pPix); - pPix.Destroy(); - m_vImages.push_back(pImageStream); - } - void CJbig2Global::AddImage(NSImages::CPixJbig2* pPix, CStream* pImageStream) - { - if (!m_pContext.IsInit()) - return; - - m_pContext.AddPage(pPix); - m_vImages.push_back(pImageStream); - } - int CJbig2Global::GetImagesCount() - { - return m_vImages.size(); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Image.h" +#include "Streams.h" +#include "Document.h" + +// TODO: write JPG from Photoshop... +#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../DesktopEditor/raster/BgraFrame.h" + +namespace NSImageReSaver +{ + static void CorrectImage(const wchar_t* wsFileName, BYTE*& pBuffer, int& nBufferSize, unsigned int& unWidth, unsigned int& unHeight) + { + pBuffer = NULL; + nBufferSize = 0; + + CImageFileFormatChecker oChecker(wsFileName); + if (oChecker.eFileType != _CXIMAGE_FORMAT_JPG) + return; + + NSFile::CFileBinary oFile; + if (!oFile.OpenFile(wsFileName)) + return; + + if (20 > oFile.GetFileSize()) + return; + + BYTE data[20]; + DWORD dwRead = 0; + if (!oFile.ReadFile(data, 20, dwRead)) + return; + + std::string sFind((char*)data, 20); + oFile.CloseFile(); + + if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) + return; + + CBgraFrame oFrame; + if (!oFrame.OpenFile(wsFileName)) + return; + + oFrame.SetJpegQuality(85.0); + if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG)) + return; + + if (!pBuffer || !nBufferSize) + return; + + unWidth = (unsigned int)oFrame.get_Width(); + unHeight = (unsigned int)oFrame.get_Height(); + } +} + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CImageDict + //---------------------------------------------------------------------------------------- + CImageDict::CImageDict(CXref* pXref, CDocument* pDocument) + { + m_pXref = pXref; + m_pDocument = pDocument; + } + void CImageDict::LoadJpeg(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight, bool bGrayScale) + { + BYTE* pCorrectBuffer = NULL; + int nBufferSize = 0; + NSImageReSaver::CorrectImage(wsFilePath, pCorrectBuffer, nBufferSize, unWidth, unHeight); + + if (pCorrectBuffer != NULL) + { + this->LoadJpeg(pCorrectBuffer, nBufferSize, unWidth, unHeight, bGrayScale); + free(pCorrectBuffer); + return; + } + + + CImageFileStream* pStream = new CImageFileStream(); + if (!pStream) + return; + + pStream->OpenFile(wsFilePath); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + + if (bGrayScale) + Add("ColorSpace", "DeviceGray"); + else + Add("ColorSpace", "DeviceRGB"); + + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_DCT_DECODE); + } + void CImageDict::LoadJpeg(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight, bool bGrayScale) + { + CMemoryStream* pStream = new CMemoryStream(); + if (!pStream) + return; + + pStream->Write(pBuffer, nBufferSize); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + + if (bGrayScale) + Add("ColorSpace", "DeviceGray"); + else + Add("ColorSpace", "DeviceRGB"); + + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_DCT_DECODE); + } + void CImageDict::LoadJpx(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight) + { + CImageFileStream* pStream = new CImageFileStream(); + if (!pStream) + return; + + pStream->OpenFile(wsFilePath); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceRGB"); + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_JPX_DECODE); + } + void CImageDict::LoadJpx(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight) + { + CMemoryStream* pStream = new CMemoryStream(); + if (!pStream) + return; + + pStream->Write(pBuffer, nBufferSize); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceRGB"); + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_JPX_DECODE); + } + void CImageDict::LoadJb2(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight) + { + CImageFileStream* pStream = new CImageFileStream(); + if (!pStream) + return; + + pStream->OpenFile(wsFilePath); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceGray"); + Add("BitsPerComponent", 1); + SetFilter(STREAM_FILTER_JBIG2_DECODE); + } + void CImageDict::LoadCCITT4(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight) + { + CImageFileStream* pStream = new CImageFileStream(); + if (!pStream) + return; + + pStream->OpenFile(wsTempFile); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceGray"); + Add("BitsPerComponent", 1); + + CArrayObject* pDecodeParams = new CArrayObject(); + CDictObject* pParams = new CDictObject(); + pDecodeParams->Add(pParams); + pParams->Add("K", 0); + pParams->Add("Columns", unWidth); + pParams->Add("EncodedByteAlign", true); + Add("DecodeParams", pDecodeParams); + + SetFilter(STREAM_FILTER_CCITT_DECODE); + + } + void CImageDict::LoadRaw(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight) + { + CMemoryStream* pStream = new CMemoryStream(3 * unWidth * unHeight); + if (!pStream) + return; + + for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) + { + pStream->Write(pBgra + unIndex, 3); + } + + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("ColorSpace", "DeviceRGB"); + Add("Width", unWidth); + Add("Height", unHeight); + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_FLATE_DECODE); + } + void CImageDict::LoadRaw(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight) + { + CMemoryStream* pStream = new CMemoryStream(unSize); + if (!pStream) + return; + pStream->Write(pBuffer, unSize); + SetStream(m_pXref, pStream); + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("ColorSpace", "DeviceRGB"); + Add("Width", unWidth); + Add("Height", unHeight); + Add("BitsPerComponent", 8); + SetFilter(STREAM_FILTER_FLATE_DECODE); + } + void CImageDict::LoadSMask(CMemoryStream* pStream, const unsigned int unWidth, const unsigned int& unHeight) + { + CImageDict* pImageSMask = new CImageDict(m_pXref, m_pDocument); + if (!pImageSMask) + return; + + pImageSMask->SetStream(m_pXref, pStream); + pImageSMask->Add("Type", "XObject"); + pImageSMask->Add("Subtype", "Image"); + pImageSMask->Add("ColorSpace", "DeviceGray"); + pImageSMask->Add("Width", unWidth); + pImageSMask->Add("Height", unHeight); + pImageSMask->Add("BitsPerComponent", 8); + +//#ifndef FILTER_FLATE_DECODE_DISABLED +// pImageSMask->SetFilter(STREAM_FILTER_LZW_DECODE | STREAM_FILTER_FLATE_DECODE); +//#else + pImageSMask->SetFilter(STREAM_FILTER_FLATE_DECODE); +//#endif + + Add("SMask", pImageSMask); + } + void CImageDict::LoadSMask(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight, unsigned char unAlpha, bool bVerFlip) + { + if (m_pDocument->IsPDFA()) + return; + + CMemoryStream* pStream = new CMemoryStream(unWidth * unHeight); + if (!pStream) + return; + + if (255 != unAlpha) + { + double dKoef = unAlpha / 255.0; + + if (!bVerFlip) + { + for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) + { + BYTE nChar = *(pBgra + unIndex + 3) * dKoef; + pStream->Write(&nChar, 1); + } + } + else + { + int nWidth = (int)unWidth; + int nHeight = (int)unHeight; + for (int nY = nHeight - 1; nY >= 0; nY--) + { + for (int nX = 0; nX < nWidth; nX++) + { + int unIndex = 4 * (nX + nY * nWidth); + BYTE nChar = *(pBgra + unIndex + 3) * dKoef; + pStream->Write(&nChar, 1); + } + } + } + } + else + { + if (!bVerFlip) + { + for (unsigned int unIndex = 0, unSize = 4 * unWidth * unHeight; unIndex < unSize; unIndex += 4) + { + pStream->Write(pBgra + unIndex + 3, 1); + } + } + else + { + int nWidth = (int)unWidth; + int nHeight = (int)unHeight; + for (int nY = nHeight - 1; nY >= 0; nY--) + { + for (int nX = 0; nX < nWidth; nX++) + { + int unIndex = 4 * (nX + nY * nWidth); + pStream->Write(pBgra + unIndex + 3, 1); + } + } + } + } + + LoadSMask(pStream, unWidth, unHeight); + } + void CImageDict::LoadSMask(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight) + { + CMemoryStream* pStream = new CMemoryStream(unSize); + if (!pStream) + return; + + pStream->Write(pBuffer, unSize); + LoadSMask(pStream, unWidth, unHeight); + } + void CImageDict::LoadSMask(const BYTE& unAlpha, const unsigned int& unWidth, const unsigned int& unHeight) + { + unsigned int unSize = unWidth * unHeight; + CMemoryStream* pStream = new CMemoryStream(unSize); + if (!pStream) + return; + + for (unsigned int unPos = 0; unPos < unSize; unPos++) + pStream->WriteChar(unAlpha); + + LoadSMask(pStream, unWidth, unHeight); + } + void CImageDict::LoadBW(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride) + { + SetStream(m_pXref, new CMemoryStream()); + CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); + pJbig2Global->AddImage(pImage, unWidth, unHeight, unStride, GetStream()); + + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceGray"); + Add("BitsPerComponent", 1); + SetFilter(STREAM_FILTER_JBIG2_DECODE); + + CArrayObject* pDecodeParams = new CArrayObject(); + CDictObject* pParams = new CDictObject(); + pDecodeParams->Add(pParams); + pParams->Add("JBIG2Globals", pJbig2Global); + Add("DecodeParms", pDecodeParams); + } + void CImageDict::LoadBW(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight) + { + SetStream(m_pXref, new CMemoryStream()); + CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); + pJbig2Global->AddImage(pPix, GetStream()); + + Add("Type", "XObject"); + Add("Subtype", "Image"); + Add("Height", unHeight); + Add("Width", unWidth); + Add("ColorSpace", "DeviceGray"); + Add("BitsPerComponent", 1); + SetFilter(STREAM_FILTER_JBIG2_DECODE); + + CArrayObject* pDecodeParams = new CArrayObject(); + CDictObject* pParams = new CDictObject(); + pDecodeParams->Add(pParams); + pParams->Add("JBIG2Globals", pJbig2Global); + Add("DecodeParms", pDecodeParams); + } + void CImageDict::LoadMask(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight) + { + CImageDict* pMask = new CImageDict(m_pXref, m_pDocument); + if (!pMask) + return; + + pMask->SetStream(m_pXref, new CMemoryStream()); + CJbig2Global* pJbig2Global = m_pDocument->GetJbig2Global(); + pJbig2Global->AddImage(pPix, pMask->GetStream()); + + pMask->Add("Type", "XObject"); + pMask->Add("Subtype", "Image"); + pMask->Add("Width", unWidth); + pMask->Add("Height", unHeight); + pMask->Add("BitsPerComponent", 1); + pMask->Add("ImageMask", true); + pMask->SetFilter(STREAM_FILTER_JBIG2_DECODE); + + CArrayObject* pDecodeParams = new CArrayObject(); + CDictObject* pParams = new CDictObject(); + pDecodeParams->Add(pParams); + pParams->Add("JBIG2Globals", pJbig2Global); + pMask->Add("DecodeParms", pDecodeParams); + + Add("Mask", pMask); + } + void CImageDict::AddTransparency(const BYTE& unAlpha) + { + if (CheckSMask()) + { + CImageDict* pSMask = (CImageDict*)Get("SMask"); + CStream* pMaskStream = pSMask->GetStream(); + + pMaskStream->Seek(0, EWhenceMode::SeekEnd); + int nSize = pMaskStream->Tell(); + if (nSize <= 0) + return; + + CMemoryStream* pStream = new CMemoryStream(nSize); + if (!pStream) + return; + + double dKoef = unAlpha / 255.0; + + pMaskStream->Seek(0, EWhenceMode::SeekSet); + while (!pMaskStream->IsEof()) + { + BYTE nChar = pMaskStream->ReadUChar(); + pStream->WriteChar((BYTE)(nChar * dKoef)); + } + + pSMask->SetStream(m_pXref, pStream); + } + else + { + LoadSMask(unAlpha, GetWidth(), GetHeight()); + } + } + unsigned int CImageDict::GetWidth() const + { + return ((unsigned int)((CNumberObject*)this->Get("Width"))->Get()); + } + unsigned int CImageDict::GetHeight() const + { + return ((unsigned int)((CNumberObject*)this->Get("Height"))->Get()); + } + bool CImageDict::CheckSMask() + { + CImageDict* pSMask = (CImageDict*)this->Get("SMask"); + if (!pSMask) + return false; + + CStream* pMaskStream = pSMask->GetStream(); + if (!pMaskStream) + return false; + + CNumberObject* pBits = (CNumberObject*)pSMask->Get("BitsPerComponent"); + if (!pBits || 8 != pBits->Get()) + return false; + + return true; + } + //---------------------------------------------------------------------------------------- + // CJbig2Global + //---------------------------------------------------------------------------------------- + CJbig2Global::CJbig2Global(CXref* pXref) : CDictObject(pXref) + { + m_pXref = pXref; + m_pContext.Init(0.85, 0.5, -1, -1, false, -1); + } + CJbig2Global::~CJbig2Global() + { + m_pContext.Destroy(); + } + void CJbig2Global::FlushStreams() + { + CStream* pStream = GetStream(); + + int nLen = 0; + BYTE* pBuffer = m_pContext.PagesComplete(&nLen); + + if (pBuffer) + { + pStream->Write(pBuffer, nLen); + free(pBuffer); + } + + for (int nIndex = 0, nCount = m_vImages.size(); nIndex < nCount; nIndex++) + { + pBuffer = m_pContext.ProducePage(nIndex, -1, -1, &nLen); + if (pBuffer) + { + pStream = m_vImages.at(nIndex); + if (pStream) + { + pStream->Write(pBuffer, nLen); + } + free(pBuffer); + } + } + + m_pContext.Destroy(); + } + void CJbig2Global::AddImage(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride, CStream* pImageStream) + { + if (!m_pContext.IsInit()) + return; + + NSImages::CPixJbig2 pPix; + if (!pPix.Create(unWidth, unHeight, 1)) + return; + + BYTE* pLine = (BYTE*)pImage; + for (unsigned int unY = 0; unY < unHeight; unY++, pLine += unStride) + { + char nBit = 0; + BYTE* pCur = pLine; + for (unsigned int unX = 0; unX < unWidth; unX++) + { + pPix.SetPixel(unX, unY, pCur[0] & (1 << nBit)); + nBit++; + + if (8 == nBit) + { + nBit = 0; + pCur++; + } + } + } + + m_pContext.AddPage(&pPix); + pPix.Destroy(); + m_vImages.push_back(pImageStream); + } + void CJbig2Global::AddImage(NSImages::CPixJbig2* pPix, CStream* pImageStream) + { + if (!m_pContext.IsInit()) + return; + + m_pContext.AddPage(pPix); + m_vImages.push_back(pImageStream); + } + int CJbig2Global::GetImagesCount() + { + return m_vImages.size(); + } +} diff --git a/PdfWriter/Src/Image.h b/PdfFile/SrcWriter/Image.h similarity index 97% rename from PdfWriter/Src/Image.h rename to PdfFile/SrcWriter/Image.h index 9e9851fc95..19cb2aa669 100644 --- a/PdfWriter/Src/Image.h +++ b/PdfFile/SrcWriter/Image.h @@ -1,109 +1,109 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_IMAGE_H -#define _PDF_WRITER_SRC_IMAGE_H - -#include "Objects.h" -#include "../../DesktopEditor/graphics/pro/Image.h" - -namespace PdfWriter -{ - class CDocument; - class CMemoryStream; - class CXObject : public CDictObject - { - public: - EDictType GetDictType() const - { - return dict_type_XOBJECT; - } - }; - //---------------------------------------------------------------------------------------- - // CImageDict - //---------------------------------------------------------------------------------------- - class CImageDict : public CXObject - { - public: - - CImageDict(CXref* pXref, CDocument* pDocument); - - void LoadJpeg(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight, bool bGrayScale = false); - void LoadJpeg(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight, bool bGrayScale = false); - void LoadJpx(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); - void LoadJpx(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight); - void LoadJb2(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); - void LoadCCITT4(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); - void LoadRaw(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight); - void LoadRaw(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight); - void LoadSMask(CMemoryStream* pStream, const unsigned int unWidth, const unsigned int& unHeight); - void LoadSMask(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight, unsigned char lAlpha = 255, bool bVerFlip = false); - void LoadSMask(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight); - void LoadSMask(const BYTE& unAlpha, const unsigned int& unWidth, const unsigned int& unHeight); - void LoadBW(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride); - void LoadBW(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight); - void LoadMask(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight); - unsigned int GetWidth() const; - unsigned int GetHeight() const; - void AddTransparency(const BYTE& unAlpha); - - private: - - bool CheckSMask(); - - private: - - CDocument* m_pDocument; - CXref* m_pXref; - }; - //---------------------------------------------------------------------------------------- - // CJbig2Global - //---------------------------------------------------------------------------------------- - class CJbig2Global : public CDictObject - { - public: - - CJbig2Global(CXref* pXref); - ~CJbig2Global(); - void AddImage(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride, CStream* pImageStream); - void AddImage(NSImages::CPixJbig2* pPix, CStream* pImageStream); - void FlushStreams(); - int GetImagesCount(); - - private: - - CXref* m_pXref; - NSImages::CJbig2Context m_pContext; - std::vector m_vImages; - }; -} - -#endif // _PDF_WRITER_SRC_IMAGE_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_IMAGE_H +#define _PDF_WRITER_SRC_IMAGE_H + +#include "Objects.h" +#include "../../DesktopEditor/graphics/pro/Image.h" + +namespace PdfWriter +{ + class CDocument; + class CMemoryStream; + class CXObject : public CDictObject + { + public: + EDictType GetDictType() const + { + return dict_type_XOBJECT; + } + }; + //---------------------------------------------------------------------------------------- + // CImageDict + //---------------------------------------------------------------------------------------- + class CImageDict : public CXObject + { + public: + + CImageDict(CXref* pXref, CDocument* pDocument); + + void LoadJpeg(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight, bool bGrayScale = false); + void LoadJpeg(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight, bool bGrayScale = false); + void LoadJpx(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); + void LoadJpx(BYTE* pBuffer, int nBufferSize, unsigned int unWidth, unsigned int unHeight); + void LoadJb2(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); + void LoadCCITT4(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight); + void LoadRaw(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight); + void LoadRaw(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight); + void LoadSMask(CMemoryStream* pStream, const unsigned int unWidth, const unsigned int& unHeight); + void LoadSMask(const BYTE* pBgra, unsigned int unWidth, unsigned int unHeight, unsigned char lAlpha = 255, bool bVerFlip = false); + void LoadSMask(const BYTE* pBuffer, unsigned int unSize, unsigned int unWidth, unsigned int unHeight); + void LoadSMask(const BYTE& unAlpha, const unsigned int& unWidth, const unsigned int& unHeight); + void LoadBW(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride); + void LoadBW(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight); + void LoadMask(NSImages::CPixJbig2* pPix, unsigned int unWidth, unsigned int unHeight); + unsigned int GetWidth() const; + unsigned int GetHeight() const; + void AddTransparency(const BYTE& unAlpha); + + private: + + bool CheckSMask(); + + private: + + CDocument* m_pDocument; + CXref* m_pXref; + }; + //---------------------------------------------------------------------------------------- + // CJbig2Global + //---------------------------------------------------------------------------------------- + class CJbig2Global : public CDictObject + { + public: + + CJbig2Global(CXref* pXref); + ~CJbig2Global(); + void AddImage(const BYTE* pImage, unsigned int unWidth, unsigned int unHeight, unsigned int unStride, CStream* pImageStream); + void AddImage(NSImages::CPixJbig2* pPix, CStream* pImageStream); + void FlushStreams(); + int GetImagesCount(); + + private: + + CXref* m_pXref; + NSImages::CJbig2Context m_pContext; + std::vector m_vImages; + }; +} + +#endif // _PDF_WRITER_SRC_IMAGE_H diff --git a/PdfWriter/Src/Info.cpp b/PdfFile/SrcWriter/Info.cpp similarity index 95% rename from PdfWriter/Src/Info.cpp rename to PdfFile/SrcWriter/Info.cpp index 28499cde8d..f2b58cdbe1 100644 --- a/PdfWriter/Src/Info.cpp +++ b/PdfFile/SrcWriter/Info.cpp @@ -1,224 +1,224 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Info.h" -#include "Utils.h" -#include "Objects.h" - -#include - -static const char *c_asInfoItemNames[] = -{ - "CreationDate", - "ModDate", - "Author", - "Creator", - "Producer", - "Title", - "Subject", - "Keywords", - NULL -}; - -namespace PdfWriter -{ - static const char* InfoTypeToName(EInfoType eType) - { - unsigned int nIndex = (unsigned int)eType; - return c_asInfoItemNames[nIndex]; - } - void TDate::AppendToString(std::string& s) const - { - s += std::to_string(nYear); - if (nMonth < 10) - s += "-0"; - else - s += "-"; - s += std::to_string(nMonth); - - if (nDay < 10) - s += "-0"; - else - s += "-"; - - s += std::to_string(nDay); - - if (nHour < 10) - s += "T0"; - else - s += "T"; - - s += std::to_string(nHour); - - if (nMinutes < 10) - s += ":0"; - else - s += ":"; - - s += std::to_string(nMinutes); - - if (nSeconds < 10) - s += ":0"; - else - s += ":"; - - s += std::to_string(nSeconds); - - s += "+00:00"; - } - //---------------------------------------------------------------------------------------- - // CInfoDict - //---------------------------------------------------------------------------------------- - CInfoDict::CInfoDict(CXref* pXref) - { - pXref->Add(this); - } - void CInfoDict::SetInfo(EInfoType eType, const char* sValue) - { - const char* sName = InfoTypeToName(eType); - - if (eType <= InfoModaDate) - return; - - Add(sName, new CStringObject(sValue, true)); - } - const char* CInfoDict::GetInfo(EInfoType eType) - { - const char* sName = InfoTypeToName(eType); - CObjectBase* pString = Get(std::string(sName)); - - if (!pString) - return NULL; - - if (object_type_STRING == pString->GetType()) - return (const char*)((CStringObject*)pString)->GetString(); - - return NULL; - } - void CInfoDict::SetInfo(EInfoType eType, const TDate& oDate) - { - char sTemp[DATE_TIME_STR_LEN + 1]; - char* pTemp = NULL; - const char* sName = InfoTypeToName(eType); - - if (eType > InfoModaDate) - return; - - MemSet(sTemp, 0, DATE_TIME_STR_LEN + 1); - - if (oDate.nMonth < 1 - || 12 < oDate.nMonth - || oDate.nDay < 1 - || 23 < oDate.nHour - || 59 < oDate.nMinutes - || 59 < oDate.nSeconds - || 23 < oDate.nOffHour - || 59 < oDate.nOffMinutes) - { - return; - } - - switch (oDate.nMonth) - { - case 1: - case 3: - case 5: - case 7: - case 8: - case 10: - case 12: - if (oDate.nDay > 31) - return; - - break; - case 4: - case 6: - case 9: - case 11: - if (oDate.nDay > 30) - return; - - break; - case 2: - if (oDate.nDay > 29 || (oDate.nDay == 29 && (oDate.nYear % 4 != 0 || (oDate.nYear % 100 == 0 && oDate.nYear % 400 != 0)))) - return; - - break; - default: - return; - } - - pTemp = (char*)MemCpy((BYTE*)sTemp, (BYTE*)"D:", 2); - *pTemp++; - *pTemp++; - pTemp = ItoA2(pTemp, oDate.nYear, 5); - pTemp = ItoA2(pTemp, oDate.nMonth, 3); - pTemp = ItoA2(pTemp, oDate.nDay, 3); - pTemp = ItoA2(pTemp, oDate.nHour, 3); - pTemp = ItoA2(pTemp, oDate.nMinutes, 3); - pTemp = ItoA2(pTemp, oDate.nSeconds, 3); - *pTemp++ = '+'; - pTemp = ItoA2(pTemp, oDate.nOffHour, 3); - *pTemp++ = '\''; - pTemp = ItoA2(pTemp, oDate.nOffMinutes, 3); - *pTemp++ = '\''; - *pTemp = 0; - - Add(sName, new CStringObject(sTemp)); - } - void CInfoDict::SetTime(EInfoType eType) - { - if (eType > InfoModaDate) - return; - - time_t oTime = time(0); - struct tm* oNow = gmtime(&oTime); - - TDate oDate; - - oDate.nYear = oNow->tm_year + 1900; - oDate.nMonth = oNow->tm_mon + 1; - oDate.nDay = oNow->tm_mday; - oDate.nHour = oNow->tm_hour; - oDate.nMinutes = oNow->tm_min; - oDate.nSeconds = oNow->tm_sec; - oDate.nOffHour = 0; - oDate.nOffMinutes = 0; - - SetInfo(eType == InfoCreationDate ? eType : InfoModaDate, oDate); - - m_oDate = oDate; - } - TDate CInfoDict::GetDate() - { - return m_oDate; - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Info.h" +#include "Utils.h" +#include "Objects.h" + +#include + +static const char *c_asInfoItemNames[] = +{ + "CreationDate", + "ModDate", + "Author", + "Creator", + "Producer", + "Title", + "Subject", + "Keywords", + NULL +}; + +namespace PdfWriter +{ + static const char* InfoTypeToName(EInfoType eType) + { + unsigned int nIndex = (unsigned int)eType; + return c_asInfoItemNames[nIndex]; + } + void TDate::AppendToString(std::string& s) const + { + s += std::to_string(nYear); + if (nMonth < 10) + s += "-0"; + else + s += "-"; + s += std::to_string(nMonth); + + if (nDay < 10) + s += "-0"; + else + s += "-"; + + s += std::to_string(nDay); + + if (nHour < 10) + s += "T0"; + else + s += "T"; + + s += std::to_string(nHour); + + if (nMinutes < 10) + s += ":0"; + else + s += ":"; + + s += std::to_string(nMinutes); + + if (nSeconds < 10) + s += ":0"; + else + s += ":"; + + s += std::to_string(nSeconds); + + s += "+00:00"; + } + //---------------------------------------------------------------------------------------- + // CInfoDict + //---------------------------------------------------------------------------------------- + CInfoDict::CInfoDict(CXref* pXref) + { + pXref->Add(this); + } + void CInfoDict::SetInfo(EInfoType eType, const char* sValue) + { + const char* sName = InfoTypeToName(eType); + + if (eType <= InfoModaDate) + return; + + Add(sName, new CStringObject(sValue, true)); + } + const char* CInfoDict::GetInfo(EInfoType eType) + { + const char* sName = InfoTypeToName(eType); + CObjectBase* pString = Get(std::string(sName)); + + if (!pString) + return NULL; + + if (object_type_STRING == pString->GetType()) + return (const char*)((CStringObject*)pString)->GetString(); + + return NULL; + } + void CInfoDict::SetInfo(EInfoType eType, const TDate& oDate) + { + char sTemp[DATE_TIME_STR_LEN + 1]; + char* pTemp = NULL; + const char* sName = InfoTypeToName(eType); + + if (eType > InfoModaDate) + return; + + MemSet(sTemp, 0, DATE_TIME_STR_LEN + 1); + + if (oDate.nMonth < 1 + || 12 < oDate.nMonth + || oDate.nDay < 1 + || 23 < oDate.nHour + || 59 < oDate.nMinutes + || 59 < oDate.nSeconds + || 23 < oDate.nOffHour + || 59 < oDate.nOffMinutes) + { + return; + } + + switch (oDate.nMonth) + { + case 1: + case 3: + case 5: + case 7: + case 8: + case 10: + case 12: + if (oDate.nDay > 31) + return; + + break; + case 4: + case 6: + case 9: + case 11: + if (oDate.nDay > 30) + return; + + break; + case 2: + if (oDate.nDay > 29 || (oDate.nDay == 29 && (oDate.nYear % 4 != 0 || (oDate.nYear % 100 == 0 && oDate.nYear % 400 != 0)))) + return; + + break; + default: + return; + } + + pTemp = (char*)MemCpy((BYTE*)sTemp, (BYTE*)"D:", 2); + *pTemp++; + *pTemp++; + pTemp = ItoA2(pTemp, oDate.nYear, 5); + pTemp = ItoA2(pTemp, oDate.nMonth, 3); + pTemp = ItoA2(pTemp, oDate.nDay, 3); + pTemp = ItoA2(pTemp, oDate.nHour, 3); + pTemp = ItoA2(pTemp, oDate.nMinutes, 3); + pTemp = ItoA2(pTemp, oDate.nSeconds, 3); + *pTemp++ = '+'; + pTemp = ItoA2(pTemp, oDate.nOffHour, 3); + *pTemp++ = '\''; + pTemp = ItoA2(pTemp, oDate.nOffMinutes, 3); + *pTemp++ = '\''; + *pTemp = 0; + + Add(sName, new CStringObject(sTemp)); + } + void CInfoDict::SetTime(EInfoType eType) + { + if (eType > InfoModaDate) + return; + + time_t oTime = time(0); + struct tm* oNow = gmtime(&oTime); + + TDate oDate; + + oDate.nYear = oNow->tm_year + 1900; + oDate.nMonth = oNow->tm_mon + 1; + oDate.nDay = oNow->tm_mday; + oDate.nHour = oNow->tm_hour; + oDate.nMinutes = oNow->tm_min; + oDate.nSeconds = oNow->tm_sec; + oDate.nOffHour = 0; + oDate.nOffMinutes = 0; + + SetInfo(eType == InfoCreationDate ? eType : InfoModaDate, oDate); + + m_oDate = oDate; + } + TDate CInfoDict::GetDate() + { + return m_oDate; + } +} diff --git a/PdfWriter/Src/Info.h b/PdfFile/SrcWriter/Info.h similarity index 100% rename from PdfWriter/Src/Info.h rename to PdfFile/SrcWriter/Info.h diff --git a/PdfWriter/Src/Metadata.cpp b/PdfFile/SrcWriter/Metadata.cpp similarity index 100% rename from PdfWriter/Src/Metadata.cpp rename to PdfFile/SrcWriter/Metadata.cpp diff --git a/PdfWriter/Src/Metadata.h b/PdfFile/SrcWriter/Metadata.h similarity index 100% rename from PdfWriter/Src/Metadata.h rename to PdfFile/SrcWriter/Metadata.h diff --git a/PdfWriter/Src/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp similarity index 96% rename from PdfWriter/Src/Objects.cpp rename to PdfFile/SrcWriter/Objects.cpp index d6d6908c54..52e2891e6b 100644 --- a/PdfWriter/Src/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -1,1097 +1,1097 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Objects.h" -#include "Utils.h" -#include "Types.h" -#include "Encrypt.h" -#include "Streams.h" -#include "Document.h" -#include "EncryptDictionary.h" - -// Если установлен бит OTYPE_DIRECT, значит данный объект принадлежит другому -// объекту. Если установлен бит OTYPE_INDIRECT, значит объект управляется таблицей xref. -#define FLAG_NONE 0x0 -#define FLAG_HIDDEN 0x1 -#define FLAG_INDIRECT 0x4 -#define FLAG_DIRECT 0x8 - -//------ Значения относящиеся к объекту xref ------------------------------------ -#define FREE_ENTRY 'f' -#define IN_USE_ENTRY 'n' - -#define RELEASE_OBJECT(pObject) \ - if (pObject && !pObject->IsIndirect())\ - delete pObject;\ - -static const BYTE UNICODE_HEADER[] ={ 0xFE, 0xFF }; - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CObjectBase - //---------------------------------------------------------------------------------------- - bool CObjectBase::IsHidden() const - { - return (m_unFlags & FLAG_HIDDEN ? true : false); - } - bool CObjectBase::IsDirect() const - { - return (m_unFlags & FLAG_DIRECT ? true : false); - } - bool CObjectBase::IsIndirect() const - { - return (m_unFlags & FLAG_INDIRECT ? true : false); - } - void CObjectBase::SetDirect() - { - m_unFlags |= FLAG_DIRECT; - } - void CObjectBase::SetIndirect() - { - m_unFlags |= FLAG_INDIRECT; - } - void CObjectBase::SetHidden() - { - m_unFlags |= FLAG_HIDDEN; - } - void CObjectBase::WriteValue(CStream* pStream, CEncrypt* pEncrypt) - { - - switch (GetType()) - { - case object_type_NAME: pStream->Write((CNameObject*)this); break; - case object_type_NUMBER: pStream->Write((CNumberObject*)this); break; - case object_type_REAL: pStream->Write((CRealObject*)this); break; - case object_type_STRING: pStream->Write((CStringObject*)this, pEncrypt); break; - case object_type_BINARY: pStream->Write((CBinaryObject*)this, pEncrypt); break; - case object_type_ARRAY: pStream->Write((CArrayObject*)this, pEncrypt); break; - case object_type_DICT: pStream->Write((CDictObject*)this, pEncrypt); break; - case object_type_BOOLEAN:pStream->Write((CBoolObject*)this); break; - case object_type_NULL: pStream->WriteStr("null"); break; - } - } - void CObjectBase::Write (CStream* pStream, CEncrypt* pEncrypt) - { - if (IsHidden()) - return; - - if (object_type_PROXY == GetType()) - { - char sBuf[SHORT_BUFFER_SIZE]; - char *pBuf = sBuf; - char *pEndPtr = sBuf + SHORT_BUFFER_SIZE - 1; - - CObjectBase* pObject = ((CProxyObject*)this)->Get(); - - pBuf = ItoA(pBuf, pObject->m_unObjId & 0x00FFFFFF, pEndPtr); - *pBuf++ = ' '; - pBuf = ItoA(pBuf, pObject->m_unGenNo, pEndPtr); - StrCpy(pBuf, " R", pEndPtr); - pStream->WriteStr(sBuf); - } - else - { - WriteValue(pStream, pEncrypt); - } - } - //---------------------------------------------------------------------------------------- - // CNameObject - //---------------------------------------------------------------------------------------- - void CNameObject::Set(const char* sValue) - { - if (!sValue || 0 == sValue[0]) - m_sValue[0] = 0; - else - { - StrCpy(m_sValue, sValue, m_sValue + LIMIT_MAX_NAME_LEN); - } - } - //---------------------------------------------------------------------------------------- - // CStringObject - //---------------------------------------------------------------------------------------- - CStringObject::CStringObject(const char* sValue, bool isUTF16, bool isDictValue) - { - m_pValue = NULL; - m_unLen = 0; - Set(sValue, isUTF16, isDictValue); - } - CStringObject::~CStringObject() - { - if (m_pValue) - delete[] m_pValue; - } - void CStringObject::Set(const char* sValue, bool isUTF16, bool isDictValue) - { - if (m_pValue) - { - delete[] m_pValue; - m_unLen = 0; - } - - unsigned int unLen = StrLen(sValue, LIMIT_MAX_STRING_LEN); - m_pValue = new BYTE[unLen + 1]; - StrCpy((char*)m_pValue, (char*)sValue, (char*)(m_pValue + unLen)); - m_unLen = unLen; - m_bUTF16 = isUTF16; - m_bDictValue = isDictValue; - } - //---------------------------------------------------------------------------------------- - // CBinaryObject - //---------------------------------------------------------------------------------------- - CBinaryObject::CBinaryObject(const BYTE* pValue, unsigned int unLen) - { - m_pValue = NULL; - m_unLen = 0; - Set(pValue, unLen); - } - CBinaryObject::~CBinaryObject() - { - if (m_pValue) - delete[] m_pValue; - } - void CBinaryObject::Set(const BYTE* pValue, unsigned int unLen) - { - unLen = std::min((unsigned int)LIMIT_MAX_STRING_LEN, unLen); - if (m_pValue) - { - delete[] m_pValue; - m_pValue = NULL; - m_unLen = 0; - } - - if (!pValue || !unLen) - return; - - m_unLen = unLen; - m_pValue = new BYTE[unLen]; - - MemCpy(m_pValue, pValue, unLen); - } - //---------------------------------------------------------------------------------------- - // CProxyObject - //---------------------------------------------------------------------------------------- - CProxyObject::CProxyObject(CObjectBase* pObject, bool bClear) - { - m_pObject = pObject; - m_bClear = bClear; - } - CProxyObject::~CProxyObject() - { - if (m_bClear) - RELEASE_OBJECT(m_pObject); - } - //---------------------------------------------------------------------------------------- - // CArrayObject - //---------------------------------------------------------------------------------------- - void CArrayObject::Add(CObjectBase* pObject, bool bPushBack) - { - if (!pObject) - return; - - // Не даем писать сложные объекты в массив не по ссылке - if (pObject->IsDirect()) - return; - - if (GetCount() >= LIMIT_MAX_ARRAY) - { - RELEASE_OBJECT(pObject); - return; - } - - if (pObject->IsIndirect()) - { - CObjectBase* pProxy = new CProxyObject(pObject); - if (!pProxy) - { - RELEASE_OBJECT(pObject); - return; - } - - pObject = pProxy; - } - - pObject->SetDirect(); - - if (bPushBack) - m_arrList.push_back(pObject); - else - m_arrList.insert(m_arrList.begin(), pObject); - } - void CArrayObject::Add(bool bValue) - { - CObjectBase* pBool = new CBoolObject(bValue); - if (pBool) - Add(pBool); - } - void CArrayObject::Add(int nValue) - { - CObjectBase* pNumber = new CNumberObject(nValue); - if (pNumber) - Add(pNumber); - } - void CArrayObject::Add(unsigned int unValue) - { - CObjectBase* pNumber = new CNumberObject((int)unValue); - if (pNumber) - Add(pNumber); - } - void CArrayObject::Add(float fValue) - { - CObjectBase* pReal = new CRealObject(fValue); - if (pReal) - Add(pReal); - } - void CArrayObject::Add(const char* sName) - { - CObjectBase* pName = new CNameObject(sName); - if (pName) - Add(pName); - } - void CArrayObject::Add(double dValue) - { - CObjectBase* pReal = new CRealObject(dValue); - if (pReal) - Add(pReal); - } - void CArrayObject::Insert(CObjectBase *pTarget, CObjectBase* pObject, bool bReplace) - { - if (!pObject) - return; - - if (pObject->IsDirect()) - return; - - if (GetCount() >= LIMIT_MAX_ARRAY) - { - RELEASE_OBJECT(pObject); - return; - } - - if (pObject->IsIndirect()) - { - CObjectBase* pProxy = new CProxyObject(pObject); - if (!pProxy) - { - RELEASE_OBJECT(pObject); - return; - } - - pObject = pProxy; - } - - pObject->SetDirect(); - - //получаем target-object из списка - //рассмотреть случай, когда указатель на содержимое списка - //может быть proxy-object. - - for (int nIndex = 0, nCount = m_arrList.size(); nIndex < nCount; nIndex++) - { - CObjectBase* pObjectItem = m_arrList.at(nIndex); - if (object_type_PROXY == pObjectItem->GetType()) - pObjectItem = ((CProxyObject*)pObjectItem)->Get(); - - if (pObjectItem == pTarget) - { - if (bReplace) - { - m_arrList.erase(m_arrList.begin() + nIndex); - RELEASE_OBJECT(pObjectItem); - } - m_arrList.insert(m_arrList.begin() + nIndex, pObject); - return; - } - } - - // Дошли до сюда, значит не вставили данный объект, поэтому удаляем его - RELEASE_OBJECT(pObject); - } - CObjectBase* CArrayObject::Get(unsigned int unIndex, bool bCheckProxy) const - { - if (unIndex >= m_arrList.size()) - return NULL; - - CObjectBase* pObject = m_arrList.at(unIndex); - if (bCheckProxy && object_type_PROXY == pObject->GetType()) - pObject = ((CProxyObject*)pObject)->Get(); - - return pObject; - } - CObjectBase* CArrayObject::Remove(unsigned int unIndex) - { - if (unIndex >= m_arrList.size()) - return NULL; - - CObjectBase* pObject = Get(unIndex); - if (pObject) - m_arrList.erase(m_arrList.begin() + unIndex); - return pObject; - } - void CArrayObject::Clear() - { - for (int nIndex = 0, nCount = m_arrList.size(); nIndex < nCount; nIndex++) - { - CObjectBase* pObject = m_arrList.at(nIndex); - RELEASE_OBJECT(pObject); - } - - m_arrList.clear(); - } - CArrayObject* CArrayObject::CreateBox(const TBox& oBox) - { - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return NULL; - - pArray->Add(oBox.fLeft); - pArray->Add(oBox.fBottom); - pArray->Add(oBox.fRight); - pArray->Add(oBox.fTop); - - return pArray; - } - CArrayObject* CArrayObject::CreateBox(double dL, double dB, double dR, double dT) - { - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return NULL; - - pArray->Add(dL); - pArray->Add(dB); - pArray->Add(dR); - pArray->Add(dT); - - return pArray; - } - CObjectBase* CArrayObject::Copy(CObjectBase* pOut) const - { - CArrayObject* pArray = pOut && pOut->GetType() == object_type_ARRAY ? (CArrayObject*)pOut : new CArrayObject(); - if (!pArray) - return NULL; - - for (unsigned int unIndex = 0, unCount = GetCount(); unIndex < unCount; ++unIndex) - { - pArray->Add(Get(unIndex, false)->Copy()); - } - - return pArray; - } - -#define AddToObject(oVal)\ -{\ - if (pObject->GetType() == object_type_DICT)\ - ((CDictObject*)pObject)->Add(sName, oVal);\ - else if (pObject->GetType() == object_type_ARRAY)\ - ((CArrayObject*)pObject)->Add(oVal);\ -} - - void ReadDict(XmlUtils::CXmlLiteReader& oCoreReader, CObjectBase* pObject) - { - int gen = 0; - std::string sType; - std::string sName = oCoreReader.GetNameA(); - - while (oCoreReader.MoveToNextAttribute()) - { - std::wstring sAName = oCoreReader.GetName(); - std::string sAText = oCoreReader.GetTextA(); - if (sAName == L"type") - sType = sAText; - else if (sAName == L"gen") - gen = std::stoi(sAText); - else if (sAName == L"num") - { - if (sType == "Bool") - AddToObject(sAText == "true") - else if (sType == "Int") - AddToObject(std::stoi(sAText)) - else if (sType == "Real") - AddToObject(std::stod(sAText)) - else if (sType == "String") - AddToObject(new CStringObject(sAText.c_str())) - else if (sType == "Name") - AddToObject(sAText.c_str()) - // Null ниже - // Array ниже - // Dict ниже - // Stream игнорируется - else if (sType == "Ref") - { - CObjectBase* pBase = new CObjectBase(); - pBase->SetRef(std::stoi(sAText), gen); - AddToObject(new CProxyObject(pBase, true)); - } - // Cmd игнорируется - else if (sType == "Cmd") - AddToObject(sAText.c_str()) - // Error игнорируется - // EOF игнорируется - // None ниже - else if (sType == "Binary") - gen = std::stoi(sAText); - } - } - oCoreReader.MoveToElement(); - - if (sType == "Array") - { - CArrayObject* pArray = new CArrayObject(); - AddToObject(pArray); - - int n2Death = oCoreReader.GetDepth(); - while (oCoreReader.ReadNextSiblingNode(n2Death)) - ReadDict(oCoreReader, pArray); - } - else if (sType == "Dict") - { - CDictObject* pDict = new CDictObject(); - AddToObject(pDict); - - int n2Death = oCoreReader.GetDepth(); - while (oCoreReader.ReadNextSiblingNode(n2Death)) - ReadDict(oCoreReader, pDict); - } - else if (sType == "None") - AddToObject("None") - else if (sType == "Null") - AddToObject(new CNullObject()) - else if (sType == "Binary") - { - BYTE* arrId = new BYTE[gen]; - int n2Death = oCoreReader.GetDepth(), i = 0; - while (oCoreReader.ReadNextSiblingNode(n2Death)) - { - std::wstring sChar = oCoreReader.GetText2(); - arrId[i++] = std::stoi(sChar); - } - AddToObject(new CBinaryObject(arrId, gen)); - RELEASEARRAYOBJECTS(arrId); - } - } - void CArrayObject::FromXml(const std::wstring& sXml) - { - XmlUtils::CXmlLiteReader oCoreReader; - oCoreReader.FromString(sXml); - oCoreReader.ReadNextNode(); - int nDeath = oCoreReader.GetDepth(); - while (oCoreReader.ReadNextSiblingNode(nDeath)) - ReadDict(oCoreReader, this); - } - //---------------------------------------------------------------------------------------- - // CDictObject - //---------------------------------------------------------------------------------------- - CDictObject::CDictObject() - { - m_unFilter = STREAM_FILTER_NONE; - m_unPredictor = STREAM_PREDICTOR_NONE; - m_pStream = NULL; - } - CDictObject::CDictObject(CXref* pXref) - { - m_unFilter = STREAM_FILTER_NONE; - m_unPredictor = STREAM_PREDICTOR_NONE; - m_pStream = NULL; - - CNumberObject* pLength = new CNumberObject(0); - - // Только stream object добавляются в таблицу xref автоматически - pXref->Add((CObjectBase*)this); - pXref->Add((CObjectBase*)pLength); - - Add("Length", (CObjectBase*)pLength); - - m_pStream = new CMemoryStream(STREAM_BUF_SIZ); - } - CDictObject::~CDictObject() - { - for (auto const &oIter : m_mList) - { - CObjectBase* pObject = oIter.second; - RELEASE_OBJECT(pObject); - } - - if (m_pStream) - delete m_pStream; - } - CObjectBase* CDictObject::Get(const std::string& sKey) const - { - std::map::const_iterator oIter = m_mList.find(sKey); - if (m_mList.end() != oIter) - { - CObjectBase* pObject = oIter->second; - if (pObject && object_type_PROXY == pObject->GetType()) - pObject = ((CProxyObject*)pObject)->Get(); - - return pObject; - } - - return NULL; - } - void CDictObject::Add(const std::string& sKey, CObjectBase* pObject) - { - if (!pObject) - return; - - if (pObject->IsDirect()) - return; - - if (m_mList.size() >= LIMIT_MAX_DICT_ELEMENT) - { - RELEASE_OBJECT(pObject); - return; - } - - // Удаляем старую запись, если она была - Remove(sKey); - - if (pObject->IsIndirect()) - { - CObjectBase* pProxy = new CProxyObject(pObject); - pObject = pProxy; - } - pObject->SetDirect(); - m_mList.insert(std::make_pair(sKey, pObject)); - } - void CDictObject::Remove(const std::string& sKey) - { - std::map::const_iterator pIter = m_mList.find(sKey); - if (m_mList.end() != pIter) - { - CObjectBase* pObject = pIter->second; - RELEASE_OBJECT(pObject); - m_mList.erase(sKey); - } - } - void CDictObject::Add(const std::string& sKey, const char* sName) - { - Add(sKey, new CNameObject(sName)); - } - void CDictObject::Add(const std::string& sKey, int nNumber) - { - Add(sKey, new CNumberObject(nNumber)); - } - void CDictObject::Add(const std::string& sKey, unsigned int unNumber) - { - Add(sKey, (int)unNumber); - } - void CDictObject::Add(const std::string& sKey, float fReal) - { - Add(sKey, new CRealObject(fReal)); - } - void CDictObject::Add(const std::string& sKey, double dReal) - { - Add(sKey, new CRealObject(dReal)); - } - void CDictObject::Add(const std::string& sKey, bool bBool) - { - Add(sKey, new CBoolObject(bBool)); - } - const char* CDictObject::GetKey(const CObjectBase* pObject) - { - for (auto const &oIter : m_mList) - { - CObjectBase* pListObject = oIter.second; - - if (pListObject && object_type_PROXY == pListObject->GetType()) - pListObject = ((CProxyObject*)pListObject)->Get(); - - if (pListObject == pObject) - return oIter.first.c_str(); - } - - return NULL; - } - void CDictObject::WriteToStream(CStream* pStream, CEncrypt* pEncrypt) - { - for (auto const &oIter : m_mList) - { - CObjectBase* pObject = oIter.second; - if (!pObject) - continue; - - if (pObject->IsHidden()) - { - // ничего не делаем - } - else - { - pStream->WriteEscapeName(oIter.first.c_str()); - pStream->WriteChar(' '); - pStream->Write(pObject, pEncrypt); - pStream->WriteStr("\012"); - } - } - } - void CDictObject::WriteSignatureToStream(CStream* pStream, CEncrypt* pEncrypt) - { - for (auto const &oIter : m_mList) - { - CObjectBase* pObject = oIter.second; - if (!pObject) - continue; - - if (pObject->IsHidden()) - { - // ничего не делаем - } - else - { - int nBegin, nEnd; - pStream->WriteEscapeName(oIter.first.c_str()); - pStream->WriteChar(' '); - nBegin = pStream->Tell(); - // Цифровая подпись не шифруется - pStream->Write(pObject, oIter.first == "Contents" ? NULL : pEncrypt); - nEnd = pStream->Tell(); - pStream->WriteStr("\012"); - if (oIter.first == "Contents") - ((CSignatureDict*)this)->SetByteRange(nBegin, nEnd); - if (oIter.first == "ByteRange") - ((CSignatureDict*)this)->ByteRangeOffset(nBegin, nEnd); - } - } - } - void CDictObject::SetStream(CXref* pXref, CStream* pStream) - { - if (m_pStream) - delete m_pStream; - - if (!Get("Length")) - { - CNumberObject* pLength = new CNumberObject(0); - - // Только stream object добавляются в таблицу xref автоматически - pXref->Add((CObjectBase*)this); - pXref->Add((CObjectBase*)pLength); - - Add("Length", (CObjectBase*)pLength); - } - - m_pStream = pStream; - } - CObjectBase* CDictObject::Copy(CObjectBase* pOut) const - { - CDictObject* pDict = pOut && pOut->GetType() == object_type_DICT ? (CDictObject*)pOut : new CDictObject(); - if (!pDict) - return NULL; - - for (auto const &oIter : m_mList) - { - pDict->Add(oIter.first, oIter.second->Copy()); - } - - return pDict; - } - void CDictObject::FromXml(const std::wstring& sXml) - { - XmlUtils::CXmlLiteReader oCoreReader; - oCoreReader.FromString(sXml); - oCoreReader.ReadNextNode(); - - int num = 0, gen = 0; - while (oCoreReader.MoveToNextAttribute()) - { - std::wstring sAName = oCoreReader.GetName(); - std::string sAText = oCoreReader.GetTextA(); - if (sAName == L"gen") - gen = std::stoi(sAText); - else if (sAName == L"num") - num = std::stoi(sAText); - } - oCoreReader.MoveToElement(); - if (num) - SetRef(num, gen); - - int nDeath = oCoreReader.GetDepth(); - while (oCoreReader.ReadNextSiblingNode(nDeath)) - ReadDict(oCoreReader, this); - } - //---------------------------------------------------------------------------------------- - // CXref - //---------------------------------------------------------------------------------------- - CXref::CXref(CDocument* pDocument, unsigned int unOffset) - { - m_pDocument = pDocument; - m_unStartOffset = unOffset; - m_unAddr = 0; - m_pPrev = NULL; - m_pTrailer = NULL; - - if (0 == m_unStartOffset) - { - // Добавляем первый элемент в таблицу xref - // он должен иметь вид 0000000000 65535 f - TXrefEntry* pEntry = new TXrefEntry; - pEntry->nEntryType = FREE_ENTRY; - pEntry->unByteOffset = 0; - pEntry->unGenNo = MAX_GENERATION_NUM; - pEntry->pObject = NULL; - m_arrEntries.push_back(pEntry); - } - - m_pTrailer = new CDictObject(); - } - CXref::CXref(CDocument* pDocument, unsigned int unRemoveId, unsigned int unRemoveGen) - { - m_pDocument = pDocument; - m_unStartOffset = unRemoveId; - m_unAddr = 0; - m_pPrev = NULL; - m_pTrailer = NULL; - - // Добавляем удаляемый элемент в таблицу xref - // он должен иметь вид 0000000000 gen+1 f - TXrefEntry* pEntry = new TXrefEntry; - pEntry->nEntryType = FREE_ENTRY; - pEntry->unByteOffset = 0; - pEntry->unGenNo = unRemoveGen + 1 > MAX_GENERATION_NUM ? MAX_GENERATION_NUM : unRemoveGen + 1; - pEntry->pObject = NULL; - m_arrEntries.push_back(pEntry); - - m_pTrailer = new CDictObject(); - } - CXref::~CXref() - { - for (int nIndex = 0, nCount = m_arrEntries.size(); nIndex < nCount; nIndex++) - { - TXrefEntry* pEntry = m_arrEntries.at(nIndex); - if (pEntry) - { - CObjectBase* pObject = pEntry->pObject; - if (pObject) - delete pObject; - } - - delete pEntry; - } - - if (m_pTrailer) - delete m_pTrailer; - - if (m_pPrev) - delete m_pPrev; - } - TXrefEntry* CXref::GetEntry(unsigned int unIndex) const - { - return m_arrEntries.at(unIndex); - } - TXrefEntry* CXref::GetEntryByObjectId(unsigned int nObjectId) const - { - const CXref* pXref = this; - - while (pXref) - { - if (pXref->m_arrEntries.size() + pXref->m_unStartOffset <= nObjectId) - return NULL; - - if (pXref->m_unStartOffset <= nObjectId) - { - for (unsigned int unIndex = 0, nCount = pXref->m_arrEntries.size(); unIndex < nCount; unIndex++) - { - if (pXref->m_unStartOffset + unIndex == nObjectId) - { - return pXref->GetEntry(unIndex); - } - } - } - - pXref = (const CXref*)pXref->m_pPrev; - } - - return NULL; - } - CXref* CXref::GetXrefByObjectId(unsigned int unObjectId) - { - CXref* pXref = this; - - while (pXref) - { - if (unObjectId >= pXref->m_unStartOffset && unObjectId < pXref->m_unStartOffset + pXref->m_arrEntries.size()) - return pXref; - pXref = pXref->m_pPrev; - } - - return NULL; - } - void CXref::Add(CObjectBase* pObject) - { - if (!pObject) - return; - - if (pObject->IsDirect() || pObject->IsIndirect()) - return; - - if (m_arrEntries.size() >= LIMIT_MAX_XREF_ELEMENT) - { - RELEASE_OBJECT(pObject); - return; - } - - - // В случае ошибки r объектe нужно применить dispose - TXrefEntry* pEntry = new TXrefEntry; - if (NULL == pEntry) - { - RELEASE_OBJECT(pObject); - return; - } - - m_arrEntries.push_back(pEntry); - - pEntry->nEntryType = IN_USE_ENTRY; - pEntry->unByteOffset = 0; - pEntry->unGenNo = 0; - pEntry->pObject = pObject; - pObject->SetRef(m_unStartOffset + m_arrEntries.size() - 1, pEntry->unGenNo); - pObject->SetIndirect(); - } - void CXref::WriteTrailer(CStream* pStream) - { - CXref* pPrev = m_pPrev; - if (m_pPrev) - while (pPrev->m_pPrev) pPrev = pPrev->m_pPrev; - unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset; - - m_pTrailer->Add("Size", unMaxObjId); - if (m_pPrev) - m_pTrailer->Add("Prev", pPrev->m_unAddr); - - pStream->WriteStr("trailer\012"); - pStream->Write(m_pTrailer, NULL); - pStream->WriteStr("\012startxref\012"); - pStream->WriteUInt(m_unAddr); - pStream->WriteStr("\012%%EOF\012"); - } - void CXref::WriteToStream(CStream* pStream, CEncrypt* pEncrypt, bool bStream) - { - char sBuf[SHORT_BUFFER_SIZE]; - char* pBuf; - char* pEndPtr = sBuf + SHORT_BUFFER_SIZE - 1; - - CXref* pXref = this; - TXrefEntry* pNextFreeObj = NULL; - while (pXref) - { - for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) - { - TXrefEntry* pEntry = pXref->m_arrEntries.at(unIndex); - if (pEntry->nEntryType == FREE_ENTRY) - { - if (pNextFreeObj) - pNextFreeObj->unByteOffset = pXref->m_unStartOffset; - pNextFreeObj = pEntry; - } - else - { - unsigned int unObjId = pXref->m_unStartOffset + unIndex; - unsigned int unGenNo = pEntry->unGenNo; - - pEntry->unByteOffset = pStream->Tell(); - - if (pEncrypt) - pEncrypt->InitKey(unObjId, unGenNo); - - pBuf = sBuf; - pBuf = ItoA(pBuf, unObjId, pEndPtr); - *pBuf++ = ' '; - pBuf = ItoA(pBuf, unGenNo, pEndPtr); - StrCpy(pBuf, " obj\012", pEndPtr); - - pStream->WriteStr(sBuf); - pEntry->pObject->WriteValue(pStream, pEncrypt); - pStream->WriteStr("\012endobj\012"); - } - } - pXref = pXref->m_pPrev; - } - if (pNextFreeObj) - pNextFreeObj->unByteOffset = 0; - - if (bStream) - { - CXref* pPrev = m_pPrev; - if (m_pPrev) - while (pPrev->m_pPrev) pPrev = pPrev->m_pPrev; - unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset; - - CDictObject* pTrailer = m_pTrailer; - pTrailer->Add("Type", "XRef"); - pTrailer->Add("Size", unMaxObjId + 1); - if (m_pPrev) - pTrailer->Add("Prev", pPrev->m_unAddr); - CArrayObject* pW = new CArrayObject(); - pTrailer->Add("W", pW); - pW->Add(1); - pW->Add(3); - pW->Add(2); - CArrayObject* pIndex = new CArrayObject(); - pTrailer->Add("Index", pIndex); - CNumberObject* pLength = new CNumberObject(0); - pTrailer->Add("Length", pLength); -#ifndef FILTER_FLATE_DECODE_DISABLED - pTrailer->SetFilter(STREAM_FILTER_FLATE_DECODE); - pTrailer->Add("Filter", "FlateDecode"); -#endif - - // Сортируем pXref, Index должен быть в порядке возрастания - pXref = this; - CXref* q, *p, *pr, *out = NULL; - while (pXref) - { - q = pXref; - pXref = pXref->m_pPrev; - for ( p = out, pr = NULL; p && (q->m_unStartOffset > p->m_unStartOffset); pr = p, p = p->m_pPrev); - if (pr) - { - q->m_pPrev = p; - pr->m_pPrev = q; - } - else - { - q->m_pPrev = out; - out = q; - } - } - - // Записываем поток - pXref = out; - int nStreamOffset = pStream->Tell(); - pXref->m_unAddr = nStreamOffset; - CStream* pTrailerStream = new CMemoryStream(); - unsigned int unEntries = 0, unEntriesSize = 0; - while (pXref) - { - unsigned int unNewEntries = pXref->m_unStartOffset; - unsigned int unNewEntriesSize = (unsigned int)pXref->m_arrEntries.size() + (pXref->m_pPrev ? 0 : 1); - if (unNewEntries == unEntries + unEntriesSize) - unEntriesSize += unNewEntriesSize; - else - { - pIndex->Add(unEntries); - pIndex->Add(unEntriesSize); - - unEntries = unNewEntries; - unEntriesSize = unNewEntriesSize; - } - - for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) - { - TXrefEntry* pEntry = pXref->GetEntry(unIndex); - - if (pEntry->nEntryType == FREE_ENTRY) - pTrailerStream->WriteChar('\000'); - else if (pEntry->nEntryType == IN_USE_ENTRY) - pTrailerStream->WriteChar('\001'); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 16)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 8)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo >> 8)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo)); - } - - pXref = pXref->m_pPrev; - } - - // Добавляем последний элемент - pIndex->Add(unEntries); - pIndex->Add(unEntriesSize); - pTrailerStream->WriteChar('\001'); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 16)); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 8)); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset)); - pTrailerStream->WriteChar('\000'); - pTrailerStream->WriteChar('\000'); - - // Фильтруем поток, pEncrypt = NULL поток перекрестных ссылок не шифруется - CStream* pFlateStream = new CMemoryStream(); - pFlateStream->WriteStream(pTrailerStream, pTrailer->GetFilter(), NULL); - pLength->Set(pFlateStream->Size()); - - pBuf = sBuf; - pBuf = ItoA(pBuf, unMaxObjId, pEndPtr); - *pBuf++ = ' '; - pBuf = ItoA(pBuf, 0, pEndPtr); - StrCpy(pBuf, " obj\012", pEndPtr); - - // Записываем cross-reference table - pStream->WriteStr(sBuf); - pTrailer->WriteValue(pStream, NULL); - pStream->WriteStr("\012stream\015\012"); - pStream->WriteStream(pFlateStream, 0, NULL); - pStream->WriteStr("\012endstream\012endobj\012startxref\012"); - pStream->WriteUInt(nStreamOffset); - pStream->WriteStr("\012%%EOF\012"); - - RELEASEOBJECT(pFlateStream); - RELEASEOBJECT(pTrailerStream); - return; - } - - // Записываем cross-reference table - pXref = this; - pXref->m_unAddr = pStream->Tell(); - pStream->WriteStr("xref\012"); - while (pXref) - { - if (pXref->m_arrEntries.size()) - { - pStream->WriteInt(pXref->m_unStartOffset); - pStream->WriteChar(' '); - pStream->WriteInt(pXref->m_arrEntries.size()); - pStream->WriteChar('\012'); - } - - for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) - { - TXrefEntry* pEntry = pXref->GetEntry(unIndex); - - pBuf = sBuf; - pBuf = ItoA2(pBuf, pEntry->unByteOffset, BYTE_OFFSET_LEN + 1); - *pBuf++ = ' '; - pBuf = ItoA2(pBuf, pEntry->unGenNo, GEN_NO_LEN + 1); - *pBuf++ = ' '; - *pBuf++ = pEntry->nEntryType; - StrCpy(pBuf, "\015\012", pEndPtr); - - pStream->WriteStr(sBuf); - } - pXref = pXref->m_pPrev; - } - - // Записываем Trailer - WriteTrailer(pStream); - } - bool CXref::IsPDFA() const - { - return m_pDocument->IsPDFA(); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Objects.h" +#include "Utils.h" +#include "Types.h" +#include "Encrypt.h" +#include "Streams.h" +#include "Document.h" +#include "EncryptDictionary.h" + +// Если установлен бит OTYPE_DIRECT, значит данный объект принадлежит другому +// объекту. Если установлен бит OTYPE_INDIRECT, значит объект управляется таблицей xref. +#define FLAG_NONE 0x0 +#define FLAG_HIDDEN 0x1 +#define FLAG_INDIRECT 0x4 +#define FLAG_DIRECT 0x8 + +//------ Значения относящиеся к объекту xref ------------------------------------ +#define FREE_ENTRY 'f' +#define IN_USE_ENTRY 'n' + +#define RELEASE_OBJECT(pObject) \ + if (pObject && !pObject->IsIndirect())\ + delete pObject;\ + +static const BYTE UNICODE_HEADER[] ={ 0xFE, 0xFF }; + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CObjectBase + //---------------------------------------------------------------------------------------- + bool CObjectBase::IsHidden() const + { + return (m_unFlags & FLAG_HIDDEN ? true : false); + } + bool CObjectBase::IsDirect() const + { + return (m_unFlags & FLAG_DIRECT ? true : false); + } + bool CObjectBase::IsIndirect() const + { + return (m_unFlags & FLAG_INDIRECT ? true : false); + } + void CObjectBase::SetDirect() + { + m_unFlags |= FLAG_DIRECT; + } + void CObjectBase::SetIndirect() + { + m_unFlags |= FLAG_INDIRECT; + } + void CObjectBase::SetHidden() + { + m_unFlags |= FLAG_HIDDEN; + } + void CObjectBase::WriteValue(CStream* pStream, CEncrypt* pEncrypt) + { + + switch (GetType()) + { + case object_type_NAME: pStream->Write((CNameObject*)this); break; + case object_type_NUMBER: pStream->Write((CNumberObject*)this); break; + case object_type_REAL: pStream->Write((CRealObject*)this); break; + case object_type_STRING: pStream->Write((CStringObject*)this, pEncrypt); break; + case object_type_BINARY: pStream->Write((CBinaryObject*)this, pEncrypt); break; + case object_type_ARRAY: pStream->Write((CArrayObject*)this, pEncrypt); break; + case object_type_DICT: pStream->Write((CDictObject*)this, pEncrypt); break; + case object_type_BOOLEAN:pStream->Write((CBoolObject*)this); break; + case object_type_NULL: pStream->WriteStr("null"); break; + } + } + void CObjectBase::Write (CStream* pStream, CEncrypt* pEncrypt) + { + if (IsHidden()) + return; + + if (object_type_PROXY == GetType()) + { + char sBuf[SHORT_BUFFER_SIZE]; + char *pBuf = sBuf; + char *pEndPtr = sBuf + SHORT_BUFFER_SIZE - 1; + + CObjectBase* pObject = ((CProxyObject*)this)->Get(); + + pBuf = ItoA(pBuf, pObject->m_unObjId & 0x00FFFFFF, pEndPtr); + *pBuf++ = ' '; + pBuf = ItoA(pBuf, pObject->m_unGenNo, pEndPtr); + StrCpy(pBuf, " R", pEndPtr); + pStream->WriteStr(sBuf); + } + else + { + WriteValue(pStream, pEncrypt); + } + } + //---------------------------------------------------------------------------------------- + // CNameObject + //---------------------------------------------------------------------------------------- + void CNameObject::Set(const char* sValue) + { + if (!sValue || 0 == sValue[0]) + m_sValue[0] = 0; + else + { + StrCpy(m_sValue, sValue, m_sValue + LIMIT_MAX_NAME_LEN); + } + } + //---------------------------------------------------------------------------------------- + // CStringObject + //---------------------------------------------------------------------------------------- + CStringObject::CStringObject(const char* sValue, bool isUTF16, bool isDictValue) + { + m_pValue = NULL; + m_unLen = 0; + Set(sValue, isUTF16, isDictValue); + } + CStringObject::~CStringObject() + { + if (m_pValue) + delete[] m_pValue; + } + void CStringObject::Set(const char* sValue, bool isUTF16, bool isDictValue) + { + if (m_pValue) + { + delete[] m_pValue; + m_unLen = 0; + } + + unsigned int unLen = StrLen(sValue, LIMIT_MAX_STRING_LEN); + m_pValue = new BYTE[unLen + 1]; + StrCpy((char*)m_pValue, (char*)sValue, (char*)(m_pValue + unLen)); + m_unLen = unLen; + m_bUTF16 = isUTF16; + m_bDictValue = isDictValue; + } + //---------------------------------------------------------------------------------------- + // CBinaryObject + //---------------------------------------------------------------------------------------- + CBinaryObject::CBinaryObject(const BYTE* pValue, unsigned int unLen) + { + m_pValue = NULL; + m_unLen = 0; + Set(pValue, unLen); + } + CBinaryObject::~CBinaryObject() + { + if (m_pValue) + delete[] m_pValue; + } + void CBinaryObject::Set(const BYTE* pValue, unsigned int unLen) + { + unLen = std::min((unsigned int)LIMIT_MAX_STRING_LEN, unLen); + if (m_pValue) + { + delete[] m_pValue; + m_pValue = NULL; + m_unLen = 0; + } + + if (!pValue || !unLen) + return; + + m_unLen = unLen; + m_pValue = new BYTE[unLen]; + + MemCpy(m_pValue, pValue, unLen); + } + //---------------------------------------------------------------------------------------- + // CProxyObject + //---------------------------------------------------------------------------------------- + CProxyObject::CProxyObject(CObjectBase* pObject, bool bClear) + { + m_pObject = pObject; + m_bClear = bClear; + } + CProxyObject::~CProxyObject() + { + if (m_bClear) + RELEASE_OBJECT(m_pObject); + } + //---------------------------------------------------------------------------------------- + // CArrayObject + //---------------------------------------------------------------------------------------- + void CArrayObject::Add(CObjectBase* pObject, bool bPushBack) + { + if (!pObject) + return; + + // Не даем писать сложные объекты в массив не по ссылке + if (pObject->IsDirect()) + return; + + if (GetCount() >= LIMIT_MAX_ARRAY) + { + RELEASE_OBJECT(pObject); + return; + } + + if (pObject->IsIndirect()) + { + CObjectBase* pProxy = new CProxyObject(pObject); + if (!pProxy) + { + RELEASE_OBJECT(pObject); + return; + } + + pObject = pProxy; + } + + pObject->SetDirect(); + + if (bPushBack) + m_arrList.push_back(pObject); + else + m_arrList.insert(m_arrList.begin(), pObject); + } + void CArrayObject::Add(bool bValue) + { + CObjectBase* pBool = new CBoolObject(bValue); + if (pBool) + Add(pBool); + } + void CArrayObject::Add(int nValue) + { + CObjectBase* pNumber = new CNumberObject(nValue); + if (pNumber) + Add(pNumber); + } + void CArrayObject::Add(unsigned int unValue) + { + CObjectBase* pNumber = new CNumberObject((int)unValue); + if (pNumber) + Add(pNumber); + } + void CArrayObject::Add(float fValue) + { + CObjectBase* pReal = new CRealObject(fValue); + if (pReal) + Add(pReal); + } + void CArrayObject::Add(const char* sName) + { + CObjectBase* pName = new CNameObject(sName); + if (pName) + Add(pName); + } + void CArrayObject::Add(double dValue) + { + CObjectBase* pReal = new CRealObject(dValue); + if (pReal) + Add(pReal); + } + void CArrayObject::Insert(CObjectBase *pTarget, CObjectBase* pObject, bool bReplace) + { + if (!pObject) + return; + + if (pObject->IsDirect()) + return; + + if (GetCount() >= LIMIT_MAX_ARRAY) + { + RELEASE_OBJECT(pObject); + return; + } + + if (pObject->IsIndirect()) + { + CObjectBase* pProxy = new CProxyObject(pObject); + if (!pProxy) + { + RELEASE_OBJECT(pObject); + return; + } + + pObject = pProxy; + } + + pObject->SetDirect(); + + //получаем target-object из списка + //рассмотреть случай, когда указатель на содержимое списка + //может быть proxy-object. + + for (int nIndex = 0, nCount = m_arrList.size(); nIndex < nCount; nIndex++) + { + CObjectBase* pObjectItem = m_arrList.at(nIndex); + if (object_type_PROXY == pObjectItem->GetType()) + pObjectItem = ((CProxyObject*)pObjectItem)->Get(); + + if (pObjectItem == pTarget) + { + if (bReplace) + { + m_arrList.erase(m_arrList.begin() + nIndex); + RELEASE_OBJECT(pObjectItem); + } + m_arrList.insert(m_arrList.begin() + nIndex, pObject); + return; + } + } + + // Дошли до сюда, значит не вставили данный объект, поэтому удаляем его + RELEASE_OBJECT(pObject); + } + CObjectBase* CArrayObject::Get(unsigned int unIndex, bool bCheckProxy) const + { + if (unIndex >= m_arrList.size()) + return NULL; + + CObjectBase* pObject = m_arrList.at(unIndex); + if (bCheckProxy && object_type_PROXY == pObject->GetType()) + pObject = ((CProxyObject*)pObject)->Get(); + + return pObject; + } + CObjectBase* CArrayObject::Remove(unsigned int unIndex) + { + if (unIndex >= m_arrList.size()) + return NULL; + + CObjectBase* pObject = Get(unIndex); + if (pObject) + m_arrList.erase(m_arrList.begin() + unIndex); + return pObject; + } + void CArrayObject::Clear() + { + for (int nIndex = 0, nCount = m_arrList.size(); nIndex < nCount; nIndex++) + { + CObjectBase* pObject = m_arrList.at(nIndex); + RELEASE_OBJECT(pObject); + } + + m_arrList.clear(); + } + CArrayObject* CArrayObject::CreateBox(const TBox& oBox) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return NULL; + + pArray->Add(oBox.fLeft); + pArray->Add(oBox.fBottom); + pArray->Add(oBox.fRight); + pArray->Add(oBox.fTop); + + return pArray; + } + CArrayObject* CArrayObject::CreateBox(double dL, double dB, double dR, double dT) + { + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return NULL; + + pArray->Add(dL); + pArray->Add(dB); + pArray->Add(dR); + pArray->Add(dT); + + return pArray; + } + CObjectBase* CArrayObject::Copy(CObjectBase* pOut) const + { + CArrayObject* pArray = pOut && pOut->GetType() == object_type_ARRAY ? (CArrayObject*)pOut : new CArrayObject(); + if (!pArray) + return NULL; + + for (unsigned int unIndex = 0, unCount = GetCount(); unIndex < unCount; ++unIndex) + { + pArray->Add(Get(unIndex, false)->Copy()); + } + + return pArray; + } + +#define AddToObject(oVal)\ +{\ + if (pObject->GetType() == object_type_DICT)\ + ((CDictObject*)pObject)->Add(sName, oVal);\ + else if (pObject->GetType() == object_type_ARRAY)\ + ((CArrayObject*)pObject)->Add(oVal);\ +} + + void ReadDict(XmlUtils::CXmlLiteReader& oCoreReader, CObjectBase* pObject) + { + int gen = 0; + std::string sType; + std::string sName = oCoreReader.GetNameA(); + + while (oCoreReader.MoveToNextAttribute()) + { + std::wstring sAName = oCoreReader.GetName(); + std::string sAText = oCoreReader.GetTextA(); + if (sAName == L"type") + sType = sAText; + else if (sAName == L"gen") + gen = std::stoi(sAText); + else if (sAName == L"num") + { + if (sType == "Bool") + AddToObject(sAText == "true") + else if (sType == "Int") + AddToObject(std::stoi(sAText)) + else if (sType == "Real") + AddToObject(std::stod(sAText)) + else if (sType == "String") + AddToObject(new CStringObject(sAText.c_str())) + else if (sType == "Name") + AddToObject(sAText.c_str()) + // Null ниже + // Array ниже + // Dict ниже + // Stream игнорируется + else if (sType == "Ref") + { + CObjectBase* pBase = new CObjectBase(); + pBase->SetRef(std::stoi(sAText), gen); + AddToObject(new CProxyObject(pBase, true)); + } + // Cmd игнорируется + else if (sType == "Cmd") + AddToObject(sAText.c_str()) + // Error игнорируется + // EOF игнорируется + // None ниже + else if (sType == "Binary") + gen = std::stoi(sAText); + } + } + oCoreReader.MoveToElement(); + + if (sType == "Array") + { + CArrayObject* pArray = new CArrayObject(); + AddToObject(pArray); + + int n2Death = oCoreReader.GetDepth(); + while (oCoreReader.ReadNextSiblingNode(n2Death)) + ReadDict(oCoreReader, pArray); + } + else if (sType == "Dict") + { + CDictObject* pDict = new CDictObject(); + AddToObject(pDict); + + int n2Death = oCoreReader.GetDepth(); + while (oCoreReader.ReadNextSiblingNode(n2Death)) + ReadDict(oCoreReader, pDict); + } + else if (sType == "None") + AddToObject("None") + else if (sType == "Null") + AddToObject(new CNullObject()) + else if (sType == "Binary") + { + BYTE* arrId = new BYTE[gen]; + int n2Death = oCoreReader.GetDepth(), i = 0; + while (oCoreReader.ReadNextSiblingNode(n2Death)) + { + std::wstring sChar = oCoreReader.GetText2(); + arrId[i++] = std::stoi(sChar); + } + AddToObject(new CBinaryObject(arrId, gen)); + RELEASEARRAYOBJECTS(arrId); + } + } + void CArrayObject::FromXml(const std::wstring& sXml) + { + XmlUtils::CXmlLiteReader oCoreReader; + oCoreReader.FromString(sXml); + oCoreReader.ReadNextNode(); + int nDeath = oCoreReader.GetDepth(); + while (oCoreReader.ReadNextSiblingNode(nDeath)) + ReadDict(oCoreReader, this); + } + //---------------------------------------------------------------------------------------- + // CDictObject + //---------------------------------------------------------------------------------------- + CDictObject::CDictObject() + { + m_unFilter = STREAM_FILTER_NONE; + m_unPredictor = STREAM_PREDICTOR_NONE; + m_pStream = NULL; + } + CDictObject::CDictObject(CXref* pXref) + { + m_unFilter = STREAM_FILTER_NONE; + m_unPredictor = STREAM_PREDICTOR_NONE; + m_pStream = NULL; + + CNumberObject* pLength = new CNumberObject(0); + + // Только stream object добавляются в таблицу xref автоматически + pXref->Add((CObjectBase*)this); + pXref->Add((CObjectBase*)pLength); + + Add("Length", (CObjectBase*)pLength); + + m_pStream = new CMemoryStream(STREAM_BUF_SIZ); + } + CDictObject::~CDictObject() + { + for (auto const &oIter : m_mList) + { + CObjectBase* pObject = oIter.second; + RELEASE_OBJECT(pObject); + } + + if (m_pStream) + delete m_pStream; + } + CObjectBase* CDictObject::Get(const std::string& sKey) const + { + std::map::const_iterator oIter = m_mList.find(sKey); + if (m_mList.end() != oIter) + { + CObjectBase* pObject = oIter->second; + if (pObject && object_type_PROXY == pObject->GetType()) + pObject = ((CProxyObject*)pObject)->Get(); + + return pObject; + } + + return NULL; + } + void CDictObject::Add(const std::string& sKey, CObjectBase* pObject) + { + if (!pObject) + return; + + if (pObject->IsDirect()) + return; + + if (m_mList.size() >= LIMIT_MAX_DICT_ELEMENT) + { + RELEASE_OBJECT(pObject); + return; + } + + // Удаляем старую запись, если она была + Remove(sKey); + + if (pObject->IsIndirect()) + { + CObjectBase* pProxy = new CProxyObject(pObject); + pObject = pProxy; + } + pObject->SetDirect(); + m_mList.insert(std::make_pair(sKey, pObject)); + } + void CDictObject::Remove(const std::string& sKey) + { + std::map::const_iterator pIter = m_mList.find(sKey); + if (m_mList.end() != pIter) + { + CObjectBase* pObject = pIter->second; + RELEASE_OBJECT(pObject); + m_mList.erase(sKey); + } + } + void CDictObject::Add(const std::string& sKey, const char* sName) + { + Add(sKey, new CNameObject(sName)); + } + void CDictObject::Add(const std::string& sKey, int nNumber) + { + Add(sKey, new CNumberObject(nNumber)); + } + void CDictObject::Add(const std::string& sKey, unsigned int unNumber) + { + Add(sKey, (int)unNumber); + } + void CDictObject::Add(const std::string& sKey, float fReal) + { + Add(sKey, new CRealObject(fReal)); + } + void CDictObject::Add(const std::string& sKey, double dReal) + { + Add(sKey, new CRealObject(dReal)); + } + void CDictObject::Add(const std::string& sKey, bool bBool) + { + Add(sKey, new CBoolObject(bBool)); + } + const char* CDictObject::GetKey(const CObjectBase* pObject) + { + for (auto const &oIter : m_mList) + { + CObjectBase* pListObject = oIter.second; + + if (pListObject && object_type_PROXY == pListObject->GetType()) + pListObject = ((CProxyObject*)pListObject)->Get(); + + if (pListObject == pObject) + return oIter.first.c_str(); + } + + return NULL; + } + void CDictObject::WriteToStream(CStream* pStream, CEncrypt* pEncrypt) + { + for (auto const &oIter : m_mList) + { + CObjectBase* pObject = oIter.second; + if (!pObject) + continue; + + if (pObject->IsHidden()) + { + // ничего не делаем + } + else + { + pStream->WriteEscapeName(oIter.first.c_str()); + pStream->WriteChar(' '); + pStream->Write(pObject, pEncrypt); + pStream->WriteStr("\012"); + } + } + } + void CDictObject::WriteSignatureToStream(CStream* pStream, CEncrypt* pEncrypt) + { + for (auto const &oIter : m_mList) + { + CObjectBase* pObject = oIter.second; + if (!pObject) + continue; + + if (pObject->IsHidden()) + { + // ничего не делаем + } + else + { + int nBegin, nEnd; + pStream->WriteEscapeName(oIter.first.c_str()); + pStream->WriteChar(' '); + nBegin = pStream->Tell(); + // Цифровая подпись не шифруется + pStream->Write(pObject, oIter.first == "Contents" ? NULL : pEncrypt); + nEnd = pStream->Tell(); + pStream->WriteStr("\012"); + if (oIter.first == "Contents") + ((CSignatureDict*)this)->SetByteRange(nBegin, nEnd); + if (oIter.first == "ByteRange") + ((CSignatureDict*)this)->ByteRangeOffset(nBegin, nEnd); + } + } + } + void CDictObject::SetStream(CXref* pXref, CStream* pStream) + { + if (m_pStream) + delete m_pStream; + + if (!Get("Length")) + { + CNumberObject* pLength = new CNumberObject(0); + + // Только stream object добавляются в таблицу xref автоматически + pXref->Add((CObjectBase*)this); + pXref->Add((CObjectBase*)pLength); + + Add("Length", (CObjectBase*)pLength); + } + + m_pStream = pStream; + } + CObjectBase* CDictObject::Copy(CObjectBase* pOut) const + { + CDictObject* pDict = pOut && pOut->GetType() == object_type_DICT ? (CDictObject*)pOut : new CDictObject(); + if (!pDict) + return NULL; + + for (auto const &oIter : m_mList) + { + pDict->Add(oIter.first, oIter.second->Copy()); + } + + return pDict; + } + void CDictObject::FromXml(const std::wstring& sXml) + { + XmlUtils::CXmlLiteReader oCoreReader; + oCoreReader.FromString(sXml); + oCoreReader.ReadNextNode(); + + int num = 0, gen = 0; + while (oCoreReader.MoveToNextAttribute()) + { + std::wstring sAName = oCoreReader.GetName(); + std::string sAText = oCoreReader.GetTextA(); + if (sAName == L"gen") + gen = std::stoi(sAText); + else if (sAName == L"num") + num = std::stoi(sAText); + } + oCoreReader.MoveToElement(); + if (num) + SetRef(num, gen); + + int nDeath = oCoreReader.GetDepth(); + while (oCoreReader.ReadNextSiblingNode(nDeath)) + ReadDict(oCoreReader, this); + } + //---------------------------------------------------------------------------------------- + // CXref + //---------------------------------------------------------------------------------------- + CXref::CXref(CDocument* pDocument, unsigned int unOffset) + { + m_pDocument = pDocument; + m_unStartOffset = unOffset; + m_unAddr = 0; + m_pPrev = NULL; + m_pTrailer = NULL; + + if (0 == m_unStartOffset) + { + // Добавляем первый элемент в таблицу xref + // он должен иметь вид 0000000000 65535 f + TXrefEntry* pEntry = new TXrefEntry; + pEntry->nEntryType = FREE_ENTRY; + pEntry->unByteOffset = 0; + pEntry->unGenNo = MAX_GENERATION_NUM; + pEntry->pObject = NULL; + m_arrEntries.push_back(pEntry); + } + + m_pTrailer = new CDictObject(); + } + CXref::CXref(CDocument* pDocument, unsigned int unRemoveId, unsigned int unRemoveGen) + { + m_pDocument = pDocument; + m_unStartOffset = unRemoveId; + m_unAddr = 0; + m_pPrev = NULL; + m_pTrailer = NULL; + + // Добавляем удаляемый элемент в таблицу xref + // он должен иметь вид 0000000000 gen+1 f + TXrefEntry* pEntry = new TXrefEntry; + pEntry->nEntryType = FREE_ENTRY; + pEntry->unByteOffset = 0; + pEntry->unGenNo = unRemoveGen + 1 > MAX_GENERATION_NUM ? MAX_GENERATION_NUM : unRemoveGen + 1; + pEntry->pObject = NULL; + m_arrEntries.push_back(pEntry); + + m_pTrailer = new CDictObject(); + } + CXref::~CXref() + { + for (int nIndex = 0, nCount = m_arrEntries.size(); nIndex < nCount; nIndex++) + { + TXrefEntry* pEntry = m_arrEntries.at(nIndex); + if (pEntry) + { + CObjectBase* pObject = pEntry->pObject; + if (pObject) + delete pObject; + } + + delete pEntry; + } + + if (m_pTrailer) + delete m_pTrailer; + + if (m_pPrev) + delete m_pPrev; + } + TXrefEntry* CXref::GetEntry(unsigned int unIndex) const + { + return m_arrEntries.at(unIndex); + } + TXrefEntry* CXref::GetEntryByObjectId(unsigned int nObjectId) const + { + const CXref* pXref = this; + + while (pXref) + { + if (pXref->m_arrEntries.size() + pXref->m_unStartOffset <= nObjectId) + return NULL; + + if (pXref->m_unStartOffset <= nObjectId) + { + for (unsigned int unIndex = 0, nCount = pXref->m_arrEntries.size(); unIndex < nCount; unIndex++) + { + if (pXref->m_unStartOffset + unIndex == nObjectId) + { + return pXref->GetEntry(unIndex); + } + } + } + + pXref = (const CXref*)pXref->m_pPrev; + } + + return NULL; + } + CXref* CXref::GetXrefByObjectId(unsigned int unObjectId) + { + CXref* pXref = this; + + while (pXref) + { + if (unObjectId >= pXref->m_unStartOffset && unObjectId < pXref->m_unStartOffset + pXref->m_arrEntries.size()) + return pXref; + pXref = pXref->m_pPrev; + } + + return NULL; + } + void CXref::Add(CObjectBase* pObject) + { + if (!pObject) + return; + + if (pObject->IsDirect() || pObject->IsIndirect()) + return; + + if (m_arrEntries.size() >= LIMIT_MAX_XREF_ELEMENT) + { + RELEASE_OBJECT(pObject); + return; + } + + + // В случае ошибки r объектe нужно применить dispose + TXrefEntry* pEntry = new TXrefEntry; + if (NULL == pEntry) + { + RELEASE_OBJECT(pObject); + return; + } + + m_arrEntries.push_back(pEntry); + + pEntry->nEntryType = IN_USE_ENTRY; + pEntry->unByteOffset = 0; + pEntry->unGenNo = 0; + pEntry->pObject = pObject; + pObject->SetRef(m_unStartOffset + m_arrEntries.size() - 1, pEntry->unGenNo); + pObject->SetIndirect(); + } + void CXref::WriteTrailer(CStream* pStream) + { + CXref* pPrev = m_pPrev; + if (m_pPrev) + while (pPrev->m_pPrev) pPrev = pPrev->m_pPrev; + unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset; + + m_pTrailer->Add("Size", unMaxObjId); + if (m_pPrev) + m_pTrailer->Add("Prev", pPrev->m_unAddr); + + pStream->WriteStr("trailer\012"); + pStream->Write(m_pTrailer, NULL); + pStream->WriteStr("\012startxref\012"); + pStream->WriteUInt(m_unAddr); + pStream->WriteStr("\012%%EOF\012"); + } + void CXref::WriteToStream(CStream* pStream, CEncrypt* pEncrypt, bool bStream) + { + char sBuf[SHORT_BUFFER_SIZE]; + char* pBuf; + char* pEndPtr = sBuf + SHORT_BUFFER_SIZE - 1; + + CXref* pXref = this; + TXrefEntry* pNextFreeObj = NULL; + while (pXref) + { + for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) + { + TXrefEntry* pEntry = pXref->m_arrEntries.at(unIndex); + if (pEntry->nEntryType == FREE_ENTRY) + { + if (pNextFreeObj) + pNextFreeObj->unByteOffset = pXref->m_unStartOffset; + pNextFreeObj = pEntry; + } + else + { + unsigned int unObjId = pXref->m_unStartOffset + unIndex; + unsigned int unGenNo = pEntry->unGenNo; + + pEntry->unByteOffset = pStream->Tell(); + + if (pEncrypt) + pEncrypt->InitKey(unObjId, unGenNo); + + pBuf = sBuf; + pBuf = ItoA(pBuf, unObjId, pEndPtr); + *pBuf++ = ' '; + pBuf = ItoA(pBuf, unGenNo, pEndPtr); + StrCpy(pBuf, " obj\012", pEndPtr); + + pStream->WriteStr(sBuf); + pEntry->pObject->WriteValue(pStream, pEncrypt); + pStream->WriteStr("\012endobj\012"); + } + } + pXref = pXref->m_pPrev; + } + if (pNextFreeObj) + pNextFreeObj->unByteOffset = 0; + + if (bStream) + { + CXref* pPrev = m_pPrev; + if (m_pPrev) + while (pPrev->m_pPrev) pPrev = pPrev->m_pPrev; + unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset; + + CDictObject* pTrailer = m_pTrailer; + pTrailer->Add("Type", "XRef"); + pTrailer->Add("Size", unMaxObjId + 1); + if (m_pPrev) + pTrailer->Add("Prev", pPrev->m_unAddr); + CArrayObject* pW = new CArrayObject(); + pTrailer->Add("W", pW); + pW->Add(1); + pW->Add(3); + pW->Add(2); + CArrayObject* pIndex = new CArrayObject(); + pTrailer->Add("Index", pIndex); + CNumberObject* pLength = new CNumberObject(0); + pTrailer->Add("Length", pLength); +#ifndef FILTER_FLATE_DECODE_DISABLED + pTrailer->SetFilter(STREAM_FILTER_FLATE_DECODE); + pTrailer->Add("Filter", "FlateDecode"); +#endif + + // Сортируем pXref, Index должен быть в порядке возрастания + pXref = this; + CXref* q, *p, *pr, *out = NULL; + while (pXref) + { + q = pXref; + pXref = pXref->m_pPrev; + for ( p = out, pr = NULL; p && (q->m_unStartOffset > p->m_unStartOffset); pr = p, p = p->m_pPrev); + if (pr) + { + q->m_pPrev = p; + pr->m_pPrev = q; + } + else + { + q->m_pPrev = out; + out = q; + } + } + + // Записываем поток + pXref = out; + int nStreamOffset = pStream->Tell(); + pXref->m_unAddr = nStreamOffset; + CStream* pTrailerStream = new CMemoryStream(); + unsigned int unEntries = 0, unEntriesSize = 0; + while (pXref) + { + unsigned int unNewEntries = pXref->m_unStartOffset; + unsigned int unNewEntriesSize = (unsigned int)pXref->m_arrEntries.size() + (pXref->m_pPrev ? 0 : 1); + if (unNewEntries == unEntries + unEntriesSize) + unEntriesSize += unNewEntriesSize; + else + { + pIndex->Add(unEntries); + pIndex->Add(unEntriesSize); + + unEntries = unNewEntries; + unEntriesSize = unNewEntriesSize; + } + + for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) + { + TXrefEntry* pEntry = pXref->GetEntry(unIndex); + + if (pEntry->nEntryType == FREE_ENTRY) + pTrailerStream->WriteChar('\000'); + else if (pEntry->nEntryType == IN_USE_ENTRY) + pTrailerStream->WriteChar('\001'); + pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 16)); + pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 8)); + pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset)); + pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo >> 8)); + pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo)); + } + + pXref = pXref->m_pPrev; + } + + // Добавляем последний элемент + pIndex->Add(unEntries); + pIndex->Add(unEntriesSize); + pTrailerStream->WriteChar('\001'); + pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 16)); + pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 8)); + pTrailerStream->WriteChar((unsigned char)(nStreamOffset)); + pTrailerStream->WriteChar('\000'); + pTrailerStream->WriteChar('\000'); + + // Фильтруем поток, pEncrypt = NULL поток перекрестных ссылок не шифруется + CStream* pFlateStream = new CMemoryStream(); + pFlateStream->WriteStream(pTrailerStream, pTrailer->GetFilter(), NULL); + pLength->Set(pFlateStream->Size()); + + pBuf = sBuf; + pBuf = ItoA(pBuf, unMaxObjId, pEndPtr); + *pBuf++ = ' '; + pBuf = ItoA(pBuf, 0, pEndPtr); + StrCpy(pBuf, " obj\012", pEndPtr); + + // Записываем cross-reference table + pStream->WriteStr(sBuf); + pTrailer->WriteValue(pStream, NULL); + pStream->WriteStr("\012stream\015\012"); + pStream->WriteStream(pFlateStream, 0, NULL); + pStream->WriteStr("\012endstream\012endobj\012startxref\012"); + pStream->WriteUInt(nStreamOffset); + pStream->WriteStr("\012%%EOF\012"); + + RELEASEOBJECT(pFlateStream); + RELEASEOBJECT(pTrailerStream); + return; + } + + // Записываем cross-reference table + pXref = this; + pXref->m_unAddr = pStream->Tell(); + pStream->WriteStr("xref\012"); + while (pXref) + { + if (pXref->m_arrEntries.size()) + { + pStream->WriteInt(pXref->m_unStartOffset); + pStream->WriteChar(' '); + pStream->WriteInt(pXref->m_arrEntries.size()); + pStream->WriteChar('\012'); + } + + for (unsigned int unIndex = 0, unCount = pXref->m_arrEntries.size(); unIndex < unCount; unIndex++) + { + TXrefEntry* pEntry = pXref->GetEntry(unIndex); + + pBuf = sBuf; + pBuf = ItoA2(pBuf, pEntry->unByteOffset, BYTE_OFFSET_LEN + 1); + *pBuf++ = ' '; + pBuf = ItoA2(pBuf, pEntry->unGenNo, GEN_NO_LEN + 1); + *pBuf++ = ' '; + *pBuf++ = pEntry->nEntryType; + StrCpy(pBuf, "\015\012", pEndPtr); + + pStream->WriteStr(sBuf); + } + pXref = pXref->m_pPrev; + } + + // Записываем Trailer + WriteTrailer(pStream); + } + bool CXref::IsPDFA() const + { + return m_pDocument->IsPDFA(); + } +} diff --git a/PdfWriter/Src/Objects.h b/PdfFile/SrcWriter/Objects.h similarity index 100% rename from PdfWriter/Src/Objects.h rename to PdfFile/SrcWriter/Objects.h diff --git a/PdfWriter/Src/Outline.cpp b/PdfFile/SrcWriter/Outline.cpp similarity index 96% rename from PdfWriter/Src/Outline.cpp rename to PdfFile/SrcWriter/Outline.cpp index ab4e8f2dcf..92c3d55c9c 100644 --- a/PdfWriter/Src/Outline.cpp +++ b/PdfFile/SrcWriter/Outline.cpp @@ -1,175 +1,175 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Outline.h" -#include "Destination.h" - -#define OUTLINE_CLOSED 0 -#define OUTLINE_OPENED 1 - -namespace PdfWriter -{ - COutline::COutline(CXref* pXref) - { - pXref->Add(this); - - CNumberObject* pOpenFlag = new CNumberObject(OUTLINE_OPENED); - if (!pOpenFlag) - return; - - pOpenFlag->SetHidden(); - - Add("_OPENED", pOpenFlag); - Add("Type", "Outline"); - } - COutline::COutline(COutline* pParent, const char* sTitle, CXref* pXref) - { - if (!pParent || !pXref) - return; - - pXref->Add(this); - - CStringObject* pString = new CStringObject(sTitle); - if (!pString) - return; - - Add("Title", pString); - - CNumberObject* pOpenFlag = new CNumberObject(OUTLINE_OPENED); - if (!pOpenFlag) - return; - - pOpenFlag->SetHidden(); - - Add("_OPENED", pOpenFlag); - Add("Type", "Outline"); - - pParent->AddChild(this); - } - void COutline::BeforeWrite() - { - CNumberObject* pNumber = (CNumberObject*)Get("Count"); - unsigned int unCount = CountChild(); - - if (0 == unCount && pNumber) - return Remove("Count"); - - if (!GetOpened()) - unCount *= -1; - - if (pNumber) - pNumber->Set(unCount); - else if (unCount) - Add("Count", unCount); - } - void COutline::AddChild(COutline* pItem) - { - COutline* pFirst = (COutline*)Get("First"); - COutline* pLast = (COutline*)Get("Last"); - - if (!pFirst) - Add("First", pItem); - - if (pLast) - { - pLast->Add("Next", pItem); - pItem->Add("Prev", pLast); - } - - Add("Last", pItem); - pItem->Add("Parent", this); - } - unsigned int COutline::CountChild() - { - COutline* pOutline = GetFirst(); - unsigned int unCount = 0; - - while (pOutline) - { - unCount++; - - if (pOutline->GetOpened()) - unCount += pOutline->CountChild(); - - pOutline = pOutline->GetNext(); - } - - return unCount; - } - COutline* COutline::GetFirst() - { - return (COutline*)Get("First"); - } - COutline* COutline::GetLast () - { - return (COutline*)Get("Last"); - } - COutline* COutline::GetPrev () - { - return (COutline*)Get("Prev"); - } - COutline* COutline::GetNext () - { - return (COutline*)Get("Next"); - } - COutline* COutline::GetParent() - { - return (COutline*)Get("Parent"); - } - bool COutline::GetOpened() - { - CNumberObject* pNumber = (CNumberObject*)Get("_OPENED"); - - if (!pNumber) - return false; - - return (pNumber->Get() == OUTLINE_OPENED ? true : false); - } - void COutline::SetDestination(CDestination* pDestination) - { - if (NULL == pDestination) - Remove("Dest"); - else - Add("Dest", pDestination); - } - void COutline::SetOpened(bool bOpened) - { - CNumberObject* pNumber = (CNumberObject*)Get("_OPENED"); - if (!pNumber) - { - pNumber = new CNumberObject(bOpened ? OUTLINE_OPENED : OUTLINE_CLOSED); - if (pNumber) - Add("_OPENED", pNumber); - } - else - pNumber->Set(bOpened ? OUTLINE_OPENED : OUTLINE_CLOSED); - } +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Outline.h" +#include "Destination.h" + +#define OUTLINE_CLOSED 0 +#define OUTLINE_OPENED 1 + +namespace PdfWriter +{ + COutline::COutline(CXref* pXref) + { + pXref->Add(this); + + CNumberObject* pOpenFlag = new CNumberObject(OUTLINE_OPENED); + if (!pOpenFlag) + return; + + pOpenFlag->SetHidden(); + + Add("_OPENED", pOpenFlag); + Add("Type", "Outline"); + } + COutline::COutline(COutline* pParent, const char* sTitle, CXref* pXref) + { + if (!pParent || !pXref) + return; + + pXref->Add(this); + + CStringObject* pString = new CStringObject(sTitle); + if (!pString) + return; + + Add("Title", pString); + + CNumberObject* pOpenFlag = new CNumberObject(OUTLINE_OPENED); + if (!pOpenFlag) + return; + + pOpenFlag->SetHidden(); + + Add("_OPENED", pOpenFlag); + Add("Type", "Outline"); + + pParent->AddChild(this); + } + void COutline::BeforeWrite() + { + CNumberObject* pNumber = (CNumberObject*)Get("Count"); + unsigned int unCount = CountChild(); + + if (0 == unCount && pNumber) + return Remove("Count"); + + if (!GetOpened()) + unCount *= -1; + + if (pNumber) + pNumber->Set(unCount); + else if (unCount) + Add("Count", unCount); + } + void COutline::AddChild(COutline* pItem) + { + COutline* pFirst = (COutline*)Get("First"); + COutline* pLast = (COutline*)Get("Last"); + + if (!pFirst) + Add("First", pItem); + + if (pLast) + { + pLast->Add("Next", pItem); + pItem->Add("Prev", pLast); + } + + Add("Last", pItem); + pItem->Add("Parent", this); + } + unsigned int COutline::CountChild() + { + COutline* pOutline = GetFirst(); + unsigned int unCount = 0; + + while (pOutline) + { + unCount++; + + if (pOutline->GetOpened()) + unCount += pOutline->CountChild(); + + pOutline = pOutline->GetNext(); + } + + return unCount; + } + COutline* COutline::GetFirst() + { + return (COutline*)Get("First"); + } + COutline* COutline::GetLast () + { + return (COutline*)Get("Last"); + } + COutline* COutline::GetPrev () + { + return (COutline*)Get("Prev"); + } + COutline* COutline::GetNext () + { + return (COutline*)Get("Next"); + } + COutline* COutline::GetParent() + { + return (COutline*)Get("Parent"); + } + bool COutline::GetOpened() + { + CNumberObject* pNumber = (CNumberObject*)Get("_OPENED"); + + if (!pNumber) + return false; + + return (pNumber->Get() == OUTLINE_OPENED ? true : false); + } + void COutline::SetDestination(CDestination* pDestination) + { + if (NULL == pDestination) + Remove("Dest"); + else + Add("Dest", pDestination); + } + void COutline::SetOpened(bool bOpened) + { + CNumberObject* pNumber = (CNumberObject*)Get("_OPENED"); + if (!pNumber) + { + pNumber = new CNumberObject(bOpened ? OUTLINE_OPENED : OUTLINE_CLOSED); + if (pNumber) + Add("_OPENED", pNumber); + } + else + pNumber->Set(bOpened ? OUTLINE_OPENED : OUTLINE_CLOSED); + } } \ No newline at end of file diff --git a/PdfWriter/Src/Outline.h b/PdfFile/SrcWriter/Outline.h similarity index 97% rename from PdfWriter/Src/Outline.h rename to PdfFile/SrcWriter/Outline.h index a529725b0e..6275570a51 100644 --- a/PdfWriter/Src/Outline.h +++ b/PdfFile/SrcWriter/Outline.h @@ -1,69 +1,69 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_OUTLINE_H -#define _PDF_WRITER_SRC_OUTLINE_H - -#include "Objects.h" - -namespace PdfWriter -{ - class CDestination; - - class COutline : public CDictObject - { - public: - COutline(CXref* pXref); - COutline(COutline* pParent, const char* sTitle, CXref* pXref); - - void SetDestination(CDestination* pDestination); - void SetOpened(bool bOpened); - void BeforeWrite(); - EDictType GetDictType() const - { - return dict_type_OUTLINE; - } - COutline* GetFirst(); - COutline* GetLast(); - COutline* GetPrev(); - COutline* GetNext(); - COutline* GetParent(); - bool GetOpened(); - - private: - - void AddChild(COutline* pItem); - unsigned int CountChild(); - }; -} - -#endif // _PDF_WRITER_SRC_OUTLINE_H - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_OUTLINE_H +#define _PDF_WRITER_SRC_OUTLINE_H + +#include "Objects.h" + +namespace PdfWriter +{ + class CDestination; + + class COutline : public CDictObject + { + public: + COutline(CXref* pXref); + COutline(COutline* pParent, const char* sTitle, CXref* pXref); + + void SetDestination(CDestination* pDestination); + void SetOpened(bool bOpened); + void BeforeWrite(); + EDictType GetDictType() const + { + return dict_type_OUTLINE; + } + COutline* GetFirst(); + COutline* GetLast(); + COutline* GetPrev(); + COutline* GetNext(); + COutline* GetParent(); + bool GetOpened(); + + private: + + void AddChild(COutline* pItem); + unsigned int CountChild(); + }; +} + +#endif // _PDF_WRITER_SRC_OUTLINE_H + diff --git a/PdfWriter/Src/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp similarity index 96% rename from PdfWriter/Src/Pages.cpp rename to PdfFile/SrcWriter/Pages.cpp index 41b75d337a..823407c975 100644 --- a/PdfWriter/Src/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1,1674 +1,1674 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Objects.h" -#include "Pages.h" -#include "Utils.h" -#include "GState.h" -#include "Streams.h" -#include "Annotation.h" -#include "Font.h" -#include "Image.h" -#include "Shading.h" -#include "Pattern.h" -#include "Document.h" -#include "Field.h" - -#ifdef DrawText -#undef DrawText -#endif - -#define MIN_HORIZONTALSCALING 0.01 -#define MAX_HORIZONTALSCALING 1000 -#define MIN_CHARSPACE -30 -#define MAX_CHARSPACE 300 -#define MAX_FONTSIZE 1000 - -#define STR_BUF 200 - -namespace PdfWriter -{ - static const double c_dKappa = 0.552; - static void QuarterEllipseA(CStream* pStream, double dX, double dY, double dXRad, double dYRad) - { - pStream->WriteReal(dX - dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY + dYRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dX - dXRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dY + dYRad); - pStream->WriteChar(' '); - pStream->WriteReal(dX); - pStream->WriteChar(' '); - pStream->WriteReal(dY + dYRad); - pStream->WriteStr(" c\012"); - } - static void QuarterEllipseB(CStream* pStream, double dX, double dY, double dXRad, double dYRad) - { - pStream->WriteReal(dX + dXRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dY + dYRad); - pStream->WriteChar(' '); - pStream->WriteReal(dX + dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY + dYRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dX + dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY); - pStream->WriteStr(" c\012"); - } - static void QuarterEllipseC(CStream* pStream, double dX, double dY, double dXRad, double dYRad) - { - pStream->WriteReal(dX + dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY - dYRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dX + dXRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dY - dYRad); - pStream->WriteChar(' '); - pStream->WriteReal(dX); - pStream->WriteChar(' '); - pStream->WriteReal(dY - dYRad); - pStream->WriteStr(" c\012"); - } - static void QuarterEllipseD(CStream* pStream, double dX, double dY, double dXRad, double dYRad) - { - pStream->WriteReal(dX - dXRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dY - dYRad); - pStream->WriteChar(' '); - pStream->WriteReal(dX - dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY - dYRad * c_dKappa); - pStream->WriteChar(' '); - pStream->WriteReal(dX - dXRad); - pStream->WriteChar(' '); - pStream->WriteReal(dY); - pStream->WriteStr(" c\012"); - } - static double AngToEllPrm(double dAngle, double dXRad, double dYRad) - { - // Функция для перевода реального угла в параметрическое задание эллписа - // т.е. x= a cos(t) y = b sin(t) - параметрическое задание эллписа. - // x = r cos(p), y = r sin(p) => t = atan2( sin(p) / b, cos(p) / a ); - return atan2(sin(dAngle) / dYRad, cos(dAngle) / dXRad); - } - static void WriteEllipseArc(CStream* pStream, double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, double& dXCur, double& dYCur, bool bClockDirection = false) - { - // Рассчитаем начальную, конечную и контрольные точки - double dX1 = 0.0, dX2 = 0.0, dY1 = 0.0, dY2 = 0.0; - double dCX1 = 0.0, dCX2 = 0.0, dCY1 = 0.0, dCY2 = 0.0; - - double dAlpha = sin(dAngle2 - dAngle1) * (sqrt(4.0 + 3.0 * tan((dAngle2 - dAngle1) / 2.0) * tan((dAngle2 - dAngle1) / 2.0)) - 1.0) / 3.0; - - dX1 = dX + dXRad * cos(dAngle1); - dY1 = dY + dYRad * sin(dAngle1); - - dX2 = dX + dXRad * cos(dAngle2); - dY2 = dY + dYRad * sin(dAngle2); - - dCX1 = dX1 - dAlpha * dXRad * sin(dAngle1); - dCY1 = dY1 + dAlpha * dYRad * cos(dAngle1); - - dCX2 = dX2 + dAlpha * dXRad * sin(dAngle2); - dCY2 = dY2 - dAlpha * dYRad * cos(dAngle2); - - if ( !bClockDirection ) - { - pStream->WriteReal(dCX1); - pStream->WriteChar(' '); - pStream->WriteReal(dCY1); - pStream->WriteChar(' '); - pStream->WriteReal(dCX2); - pStream->WriteChar(' '); - pStream->WriteReal(dCY2); - pStream->WriteChar(' '); - pStream->WriteReal(dX2); - pStream->WriteChar(' '); - pStream->WriteReal(dY2); - dXCur = dX2; - dYCur = dY2; - } - else - { - pStream->WriteReal(dCX2); - pStream->WriteChar(' '); - pStream->WriteReal(dCY2); - pStream->WriteChar(' '); - pStream->WriteReal(dCX1); - pStream->WriteChar(' '); - pStream->WriteReal(dCY1); - pStream->WriteChar(' '); - pStream->WriteReal(dX1); - pStream->WriteChar(' '); - pStream->WriteReal(dY1); - dXCur = dX1; - dYCur = dY1; - } - pStream->WriteStr(" c\012"); - } - //---------------------------------------------------------------------------------------- - // CPageTree - //---------------------------------------------------------------------------------------- - CPageTree::CPageTree(CXref* pXref) - { - m_pXref = pXref; - pXref->Add(this); - - m_pPages = new CArrayObject(); - m_pCount = new CNumberObject(0); - - Add("Type", "Pages"); - Add("Kids", m_pPages); - Add("Count", m_pCount); - } - CPageTree::CPageTree(CXref* pXref, bool bEmpty) - { - m_pXref = pXref; - pXref->Add(this); - - m_pPages = NULL; - m_pCount = NULL; - } - void CPageTree::Fix() - { - // Инициализация текущего m_pPages - CObjectBase* pPages = Get("Kids"); - if (pPages && pPages->GetType() == object_type_ARRAY) - m_pPages = (CArrayObject*)pPages; - else - { - m_pPages = new CArrayObject(); - Add("Kids", m_pPages); - } - - // Инициализация текущего m_pCount - CObjectBase* pCount = Get("Count"); - if (pCount && pCount->GetType() == object_type_NUMBER) - m_pCount = (CNumberObject*)pCount; - else - { - m_pCount = new CNumberObject(0); - Add("Count", m_pCount); - } - } - void CPageTree::AddPage(CDictObject* pPage) - { - m_pPages->Add(pPage); - (*m_pCount)++; - } - CObjectBase* CPageTree::GetObj(int nPageIndex) - { - int nI = 0; - return GetFromPageTree(nPageIndex, nI); - } - CPage* CPageTree::GetPage(int nPageIndex) - { - int nI = 0; - CObjectBase* pObj = GetFromPageTree(nPageIndex, nI); - if (pObj && pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) - return (CPage*)pObj; - return NULL; - } - CObjectBase* CPageTree::RemovePage(int nPageIndex) - { - int nI = 0; - return GetFromPageTree(nPageIndex, nI, true); - } - bool CPageTree::InsertPage(int nPageIndex, CPage* pPage) - { - if (nPageIndex >= m_pCount->Get()) - { - AddPage(pPage); - pPage->Add("Parent", this); - return true; - } - int nI = 0; - CObjectBase* pObj = GetFromPageTree(nPageIndex, nI, false, true, pPage); - if (pObj) - return true; - return false; - } - CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CPage* pPage) - { - for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) - { - CObjectBase* pObj = m_pPages->Get(i); - CObjectBase* pRes = NULL; - if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGES) - pRes = ((CPageTree*)pObj)->GetFromPageTree(nPageIndex, nI, bRemove, bInsert, pPage); - else - { - if (nPageIndex == nI) - { - pRes = pObj; - if (bRemove) - pRes = m_pPages->Remove(i); - if (bInsert) - { - m_pPages->Insert(pObj, pPage); - pPage->Add("Parent", this); - } - } - nI++; - } - if (pRes) - { - if (bRemove) - (*m_pCount)--; - if (bInsert) - (*m_pCount)++; - return pRes; - } - } - return NULL; - } - bool CPageTree::Join(CPageTree* pPageTree) - { - unsigned int nObjId = pPageTree->GetObjId(); - unsigned int nGenNo = pPageTree->GetGenNo(); - for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) - { - CObjectBase* pObj = m_pPages->Get(i); - if (pObj->GetObjId() == nObjId && pObj->GetGenNo() == nGenNo) - { - m_pPages->Insert(pObj, pPageTree, true); - return true; - } - if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGES && ((CPageTree*)pObj)->Join(pPageTree)) - return true; - } - return false; - } - //---------------------------------------------------------------------------------------- - // CPage - //---------------------------------------------------------------------------------------- - CPage::CPage(CXref* pXref, CDocument* pDocument) - { - Init(pXref, pDocument); - } - void CPage::Fix() - { - // Инициализация текущего contents - CObjectBase* pContents = Get("Contents"); - if (pContents) - { - if (pContents->GetType() == object_type_ARRAY) - m_pContents = (CArrayObject*)pContents; - else if (pContents->GetType() == object_type_UNKNOWN) - { - CProxyObject* pNewContents = new CProxyObject(pContents->Copy(), true); - pNewContents->Get()->SetRef(pContents->GetObjId(), pContents->GetGenNo()); - m_pContents = new CArrayObject(); - m_pContents->Add(pNewContents); - Add("Contents", m_pContents); - } - } - else - { - m_pContents = new CArrayObject(); - Add("Contents", m_pContents); - } - - // Инициализация текущего MediaBox - CObjectBase* pMediaBox = Get("MediaBox"); - if (pMediaBox && pMediaBox->GetType() == object_type_ARRAY) - { - double dL = 0.0, dB = 0.0, dR = DEF_PAGE_WIDTH, dT = DEF_PAGE_HEIGHT; - - CObjectBase* val = ((CArrayObject*)pMediaBox)->Get(0); - if (val && val->GetType() == object_type_NUMBER) - dL = ((CNumberObject*)val)->Get(); - else if (val && val->GetType() == object_type_REAL) - dL = ((CRealObject*)val)->Get(); - - val = ((CArrayObject*)pMediaBox)->Get(1); - if (val && val->GetType() == object_type_NUMBER) - dB = ((CNumberObject*)val)->Get(); - else if (val && val->GetType() == object_type_REAL) - dB = ((CRealObject*)val)->Get(); - - val = ((CArrayObject*)pMediaBox)->Get(2); - if (val && val->GetType() == object_type_NUMBER) - dR = ((CNumberObject*)val)->Get(); - else if (val && val->GetType() == object_type_REAL) - dR = ((CRealObject*)val)->Get(); - - val = ((CArrayObject*)pMediaBox)->Get(3); - if (val && val->GetType() == object_type_NUMBER) - dT = ((CNumberObject*)val)->Get(); - else if (val && val->GetType() == object_type_REAL) - dT = ((CRealObject*)val)->Get(); - - Add("MediaBox", CArrayObject::CreateBox(dL, dB, dR, dT)); - } - else - Add("MediaBox", CArrayObject::CreateBox(0, 0, DEF_PAGE_WIDTH, DEF_PAGE_HEIGHT)); - - // Инициализация текущего Rotate - CObjectBase* pRotate = GetRotateItem(); - if (pRotate && pRotate->GetType() == object_type_NUMBER) - Add("Rotate", ((CNumberObject*)pRotate)->Get() % 360); - - CDictObject* pResources = GetResourcesItem(); - if (pResources) - { - // Инициализация текущего fonts - CObjectBase* pFonts = pResources->Get("Font"); - if (pFonts && pFonts->GetType() == object_type_DICT) - { - m_pFonts = (CDictObject*)pFonts; - m_unFontsCount = 0; - } - - // Инициализация текущего ExtGStates - CObjectBase* pExtGStates = pResources->Get("ExtGState"); - if (pExtGStates && pExtGStates->GetType() == object_type_DICT) - { - m_pExtGStates = (CDictObject*)pExtGStates; - m_unExtGStatesCount = m_pExtGStates->GetSize(); - } - - // Инициализация текущего XObject - CObjectBase* pXObject = pResources->Get("XObject"); - if (pXObject && pXObject->GetType() == object_type_DICT) - { - m_pXObjects = (CDictObject*)pXObject; - m_unXObjectsCount = m_pXObjects->GetSize(); - } - - // Инициализация текущего Shading - CObjectBase* pShading = pResources->Get("Shading"); - if (pShading && pShading->GetType() == object_type_DICT) - { - m_pShadings = (CDictObject*)pShading; - m_unShadingsCount = m_pShadings->GetSize(); - } - - // Инициализация текущего Pattern - CObjectBase* pPattern = pResources->Get("Pattern"); - if (pPattern && pPattern->GetType() == object_type_DICT) - { - m_pPatterns = (CDictObject*)pPattern; - m_unPatternsCount = m_pPatterns->GetSize(); - } - } - else - Add("Resources", new CDictObject()); - - m_pStream = NULL; - } - CPage::CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument) - { - Init(pXref, pDocument); - - m_pContents = new CArrayObject(); - CDictObject* pContent = new CDictObject(pXref); - m_pContents->Add(pContent); - m_pStream = pContent->GetStream(); - - Add("Parent", pParent); - Add("MediaBox", CArrayObject::CreateBox(0, 0, DEF_PAGE_WIDTH, DEF_PAGE_HEIGHT)); - Add("Type", "Page"); - Add("Contents", m_pContents); - AddResource(); - } - CPage::~CPage() - { - CGrState* pGrState = m_pGrState, *pPrev = NULL; - while (pGrState) - { - pPrev = m_pGrState->GetPrev(); - delete pGrState; - pGrState = pPrev; - } - } - void CPage::Init(CXref* pXref, CDocument* pDocument) - { - pXref->Add(this); - - m_pXref = pXref; - m_pDocument = pDocument; - m_eGrMode = grmode_PAGE; - m_pGrState = new CGrState(NULL); - - m_pExtGStates = NULL; - m_unExtGStatesCount = 0; - m_pFonts = NULL; - m_pFont = NULL; - m_unFontsCount = 0; - m_pXObjects = NULL; - m_unXObjectsCount = 0; - m_pShadings = NULL; - m_unShadingsCount = 0; - m_pPatterns = NULL; - m_unPatternsCount = 0; - } - void CPage::SetWidth(double dValue) - { - dValue = std::min(std::max(dValue, 1.0), 14400.0); - SetMediaBoxValue(2, dValue); - } - double CPage::GetWidth() - { - return GetMediaBox().fRight; - } - void CPage::SetHeight(double dValue) - { - dValue = std::min(std::max(dValue, 1.0), 14400.0); - SetMediaBoxValue(3, dValue); - } - double CPage::GetHeight() - { - return GetMediaBox().fTop; - } - TBox CPage::GetMediaBox() - { - TBox oMediaBox = TRect( 0, 0, 0, 0 ); - - CArrayObject* pArray = GetMediaBoxItem(); - - if (pArray) - { - CRealObject* pReal; - - pReal = (CRealObject*)pArray->Get(0); - if (pReal) - oMediaBox.fLeft = pReal->Get(); - - pReal = (CRealObject*)pArray->Get(1); - if (pReal) - oMediaBox.fBottom = pReal->Get(); - - pReal = (CRealObject*)pArray->Get(2); - if (pReal) - oMediaBox.fRight = pReal->Get(); - - pReal = (CRealObject*)pArray->Get(3); - if (pReal) - oMediaBox.fTop = pReal->Get(); - } - - return oMediaBox; - } - void CPage::SetMediaBoxValue(unsigned int unIndex, double dValue) - { - CArrayObject* pArray = GetMediaBoxItem(); - if (!pArray) - return; - - CRealObject* pReal = (CRealObject*)pArray->Get(unIndex); - if (!pReal) - return; - - pReal->Set(dValue); - } - CArrayObject* CPage::GetMediaBoxItem() - { - return (CArrayObject*)Get("MediaBox"); - } - CDictObject* CPage::GetResourcesItem() - { - CObjectBase* pObject = Get("Resources"); - - // Если объект Resources нулевой, тогда ищем Resources у родительского объекта рекурсивно - if (!pObject) - { - CPageTree* pPageTree = (CPageTree*)Get("Parent"); - while (pPageTree) - { - pObject = Get("Resources"); - - if (pObject) - break; - - pPageTree = (CPageTree*)pPageTree->Get("Parent"); - } - } - - return (CDictObject*)pObject; - } - CObjectBase* CPage::GetCropBoxItem() - { - return Get("CropBox"); - } - CObjectBase* CPage::GetRotateItem() - { - return Get("Rotate"); - } - void CPage::AddResource() - { - // TODO: Переделать на ResourcesDict - CDictObject* pResource = new CDictObject(); - if (!pResource) - return; - - // Не смотря на то, что ProcSet - устаревший объект, добавляем - // его для совместимости - Add("Resources", pResource); - - CArrayObject* pProcset = new CArrayObject(); - if (!pProcset) - return; - - pResource->Add("ProcSet", pProcset); - pProcset->Add(new CNameObject("PDF")); - pProcset->Add(new CNameObject("Text")); - pProcset->Add(new CNameObject("ImageB")); - pProcset->Add(new CNameObject("ImageC")); - pProcset->Add(new CNameObject("ImageI")); - } - void CPage::BeforeWrite() - { - if (grmode_PATH == m_eGrMode) - EndPath(); - - if (grmode_TEXT == m_eGrMode) - EndText(); - - while (m_pGrState->GetPrev()) - { - GrRestore(); - } - } - void CPage::SetGrMode(EGrMode eMode) - { - m_eGrMode = eMode; - // TODO: Сделать проверку плохих ситуаций - } - void CPage::CheckGrMode(EGrMode eMode) - { - // TODO: Сделать проверку плохих ситуаций - } - void CPage::MoveTo (double dX, double dY) - { - // Operator : m - // Description: Начинаем новый subpath, передвигая текущий указатель в точку (x, y)(она же стартовая). - - SetGrMode(grmode_PATH); - m_pStream->WriteReal(dX); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" m\012"); - - m_oCurPos.Set(dX, dY); - m_oStartPos = m_oCurPos; - } - void CPage::LineTo (double dX, double dY) - { - // Operator : l - // Description: Добавляем линию от текущей точки до точки (x, y). Текущую точку выставляем (х, у). - CheckGrMode(grmode_PATH); - - m_pStream->WriteReal(dX); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" l\012"); - - m_oCurPos.Set(dX, dY); - } - void CPage::CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3) - { - // Operator : c - // Description: Добавляем кривую Безье(кубическую). Начинается кривая в текущей позиции, заканчивается - // в точке (x3, y3). (x1, y1) и (x2, y2) - контрольные точки. Текущую точку устанавливаем - // в (х3, у3). - CheckGrMode(grmode_PATH); - - m_pStream->WriteReal(dX1); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY1); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dX2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY2); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dX3); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY3); - m_pStream->WriteStr(" c\012"); - - m_oCurPos.Set(dX3, dY3); - } - void CPage::Ellipse(double dX, double dY, double dXRay, double dYRay) - { - SetGrMode(grmode_PATH); - - m_pStream->WriteReal(dX - dXRay); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" m\012"); - - QuarterEllipseA(m_pStream, dX, dY, dXRay, dYRay); - QuarterEllipseB(m_pStream, dX, dY, dXRay, dYRay); - QuarterEllipseC(m_pStream, dX, dY, dXRay, dYRay); - QuarterEllipseD(m_pStream, dX, dY, dXRay, dYRay); - - m_oCurPos.Set(dX - dXRay, dY); - m_oStartPos = m_oCurPos; - } - void CPage::EllipseArc(double dX, double dY, double dXRad, double dYRad, double _dAngle1, double _dAngle2, bool bClockDirection) - { - CheckGrMode(grmode_PATH); - - // переведем углы в радианы - double dAngle1 = _dAngle1 * 3.141592f / 180; - double dAngle2 = _dAngle2 * 3.141592f / 180; - - // Выясним в каких четвертях находятся начальная и конечная точки - int nFirstPointQuard = int(_dAngle1) / 90 + 1; - int nSecondPointQuard = int(_dAngle2) / 90 + 1; - - nSecondPointQuard = std::min(4, std::max(1, nSecondPointQuard)); - nFirstPointQuard = std::min(4, std::max(1, nFirstPointQuard)); - - // Проведем линию в начальную точку дуги - double dStartX = 0.0, dStartY = 0.0, dEndX = 0.0, dEndY = 0.0; - - dStartX = dX + dXRad * cos(AngToEllPrm(dAngle1, dXRad, dYRad)); - dStartY = dY + dYRad * sin(AngToEllPrm(dAngle1, dXRad, dYRad)); - - //m_pStream->WriteReal(dStartX); - //m_pStream->WriteChar(' '); - //m_pStream->WriteReal(dStartY); - //m_pStream->WriteStr(" m\012"); - - // Дальше рисуем по четверям - double dCurX = dStartX, dCurY = dStartY; - double dStartAngle = dAngle1; - double dEndAngle = 0; - - if ( !bClockDirection ) - { - for (unsigned int nIndex = nFirstPointQuard; nIndex <= nSecondPointQuard; nIndex++) - { - if (nIndex == nSecondPointQuard) - dEndAngle = dAngle2; - else - dEndAngle = (90 * (nIndex)) * 3.141592f / 180; - if (!(nIndex == nFirstPointQuard)) - dStartAngle = (90 * (nIndex - 1)) * 3.141592f / 180; - - WriteEllipseArc(m_pStream, dX, dY, dXRad, dYRad, AngToEllPrm(dStartAngle, dXRad, dYRad), AngToEllPrm(dEndAngle, dXRad, dYRad), dEndX, dEndY, false); - } - } - else - { - for( unsigned int nIndex = nFirstPointQuard; nIndex >= nSecondPointQuard; nIndex-- ) - { - if ( nIndex == nFirstPointQuard ) - dStartAngle = dAngle1; - else - dStartAngle = (90 * (nIndex ) ) * 3.141592f / 180; - if ( !( nIndex == nSecondPointQuard ) ) - dEndAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180; - else - dEndAngle = dAngle2; - - WriteEllipseArc(m_pStream, dX, dY, dXRad, dYRad, AngToEllPrm(dStartAngle, dXRad, dYRad), AngToEllPrm(dEndAngle, dXRad, dYRad), dEndX, dEndY, false); - } - } - - m_oCurPos.Set(dEndX, dEndY); - m_oStartPos = m_oCurPos; - } - void CPage::EllipseArcTo(double dX, double dY, double dXRad, double dYRad, double _dAngle1, double _dAngle2, bool bClockDirection) - { - // Проверяем эллипс на невырожденность - if (dXRad < 0.001 || dYRad < 0.001) - { - double dAngle1 = _dAngle1 * 3.141592f / 180; - double dAngle2 = _dAngle2 * 3.141592f / 180; - - if (dXRad < 0.001 && dYRad < 0.001) - LineTo(dX, dY); - else if (dXRad < 0.001) - { - LineTo(dX, dY + sin(dAngle1) * dYRad); - LineTo(dX, dY + sin(dAngle2) * dYRad); - } - else // if (dYRad < 0.001) - { - LineTo(dX + cos(dAngle1) * dXRad, dY); - LineTo(dX + cos(dAngle2) * dXRad, dY); - } - return; - } - - - while (_dAngle1 < 0) - _dAngle1 += 360; - - while (_dAngle1 > 360) - _dAngle1 -= 360; - - while (_dAngle2 < 0) - _dAngle2 += 360; - - while (_dAngle2 > 360) - _dAngle2 -= 360; - - if (!bClockDirection) - { - if (_dAngle1 <= _dAngle2) - EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, _dAngle2, false); - else - { - EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, 360, false); - EllipseArc(dX, dY, dXRad, dYRad, 0, _dAngle2, false); - } - } - else - { - if (_dAngle1 >= _dAngle2) - EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, _dAngle2, true); - else - { - EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, 0, true); - EllipseArc(dX, dY, dXRad, dYRad, 360, _dAngle2, true); - } - } - } - void CPage::ClosePath() - { - // Operator : h - // Description: Закрываем subpath, соединяя текущую точку с начальной прямой линией. Если subpath - // уже закрыт, тогда ничего не делаем - CheckGrMode(grmode_PATH); - m_pStream->WriteStr("h\012"); - m_oCurPos = m_oStartPos; - } - void CPage::Stroke() - { - // Operator : S - // Description: Обводим path. - - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("S\012"); - m_oCurPos.Reset(); - } - void CPage::Fill() - { - // Operator : f - // Description: Заливка path по правилу Nonzero Winding Number Rule(см. спецификацию PDF Part1: PDF 1.7 - // стр. 136, закладка 8.5.3.3.2). - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("f\012"); - m_oCurPos.Reset(); - } - void CPage::EoFill() - { - // Operator : f* - // Description: Заливка path по правилу Even-Odd Rule(см. спецификацию PDF Part1: PDF 1.7 стр. 137, - // закладка 8.5.3.3.3). - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("f*\012"); - m_oCurPos.Reset(); - } - void CPage::FillStroke() - { - // Operator : B - // Description: Заливка и обоводка path, используя правило для заливки Nonzero Winding Number Rule(см. - // спецификацию PDF Part1: PDF 1.7 стр. 136, закладка 8.5.3.3.2). Этот оператор должен - // привести к тому же самому результату как строительство двух идентичных объектов path, - // применяя к первому оператор f и ко второму - S. - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("B\012"); - m_oCurPos.Reset(); - } - void CPage::EoFillStroke() - { - // Operator : B* - // Description: Заливка и обоводка path, используя правило для заливки Even-Odd Rule(см. - // спецификацию PDF Part1: PDF 1.7 стр. 137, закладка 8.5.3.3.3). Этот оператор должен - // привести к тому же самому результату как строительство двух идентичных объектов path, - // применяя к первому оператор f* и ко второму - S. - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("B*\012"); - m_oCurPos.Reset(); - } - void CPage::EndPath() - { - // Operator : n - // Description: Закрываем path, не заливая и не обводя его. Этот оператор используется прежде всего для - // изменения текущего path. - SetGrMode(grmode_PAGE); - m_pStream->WriteStr("n\012"); - m_oCurPos.Reset(); - } - void CPage::SetLineWidth(double dLineWidth) - { - // Operator : w - // Descriprion: устанавливаем толщину линии - - dLineWidth = std::max(dLineWidth, 0.0); - m_pStream->WriteReal(dLineWidth); - m_pStream->WriteStr(" w\012"); - m_pGrState->m_dLineWidth = dLineWidth; - } - void CPage::SetLineCap(ELineCapStyle eLineCap) - { - // Operator : J - // Descriprion: устанавливаем вид окончания линии (LineCapStyle) - - eLineCap = std::max(linecap_Min, std::min(linecap_Max, eLineCap)); - m_pStream->WriteInt((unsigned int)eLineCap); - m_pStream->WriteStr(" J\012"); - m_pGrState->m_eLineCap = eLineCap; - } - void CPage::SetLineJoin(ELineJoinStyle eLineJoin) - { - // Operator : j - // Descriprion: устанавливаем вид соединения линий (LineJoinStyle) - eLineJoin = std::max(linejoin_Min, std::min(linejoin_Max, eLineJoin)); - m_pStream->WriteInt((unsigned int)eLineJoin); - m_pStream->WriteStr(" j\012"); - m_pGrState->m_eLineJoin = eLineJoin; - } - void CPage::SetMiterLimit(double dMiterLimit) - { - // Operator : M - // Descriprion: устанавливаем MiterLimit - константа, относящаяся к виду соединения линий - dMiterLimit = std::max(1.0, dMiterLimit); - m_pStream->WriteReal(dMiterLimit); - m_pStream->WriteStr(" M\012"); - m_pGrState->m_dMiterLimit = dMiterLimit; - } - void CPage::SetDash(const double* pPattern, unsigned int unCount, double dPhase) - { - // Operator : d - // Descriprion: устанавливаем вид линий (DashMode) - - if (0 == unCount || !pPattern) - return; - - bool bFalseDash = true; - for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) - { - if (0 != pPattern[unIndex]) - { - bFalseDash = false; - break; - } - } - - if (bFalseDash) - return; - - m_pStream->WriteChar('['); - for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) - { - m_pStream->WriteReal(pPattern[unIndex]); - m_pStream->WriteChar(' '); - } - m_pStream->WriteStr("] "); - m_pStream->WriteReal(dPhase); - m_pStream->WriteStr(" d\012"); - - m_pGrState->m_oDashMode.Set(pPattern, unCount, dPhase); - } - void CPage::SetFlat(double dFlatness) - { - // Operator : i - // Descriprion: устанавливаем порог ошибки линии (Flatness tolerance) - dFlatness = std::min(100.0, std::max(0.0, dFlatness)); - m_pStream->WriteReal(dFlatness); - m_pStream->WriteStr(" i\012"); - m_pGrState->m_dFlatness = dFlatness; - } - void CPage::GrSave() - { - // Operator : q - // Description: сохраняем текущий GState в графическом стеке - CheckGrMode(grmode_PAGE); - CGrState* pState = new CGrState(m_pGrState); - if (!pState) - return; - - m_pStream->WriteStr("q\012"); - m_pGrState = pState; - } - void CPage::GrRestore() - { - // Operator : Q - // Description: Восстанавливаем GState, удаляя самый последний GState, и делаем данный GState текущим - CheckGrMode(grmode_PAGE); - - if (!m_pGrState->m_pPrev) - return; - - CGrState* pPrev = m_pGrState->m_pPrev; - delete m_pGrState; - m_pGrState = pPrev; - - m_pStream->WriteStr("Q\012"); - } - void CPage::SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB) - { - // Operator : RG - // Description: Устанавливаем цветовое пространтсво для обводки в DeviceRGB и устанавливаем цвет для - // операций связанных с обведением фигур. - - double dR = unR / 255.0; - double dG = unG / 255.0; - double dB = unB / 255.0; - - m_pStream->WriteReal(dR); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dG); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dB); - m_pStream->WriteStr(" RG\012"); - - m_pGrState->m_oStrokeColor.r = dR; - m_pGrState->m_oStrokeColor.g = dG; - m_pGrState->m_oStrokeColor.b = dB; - } - void CPage::SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB) - { - // Operator : rg - // Description: Устанавливаем цветовое пространтсво для заливки в DeviceRGB и устанавливаем цвет для - // операций связанных с заливкой фигур. - - double dR = unR / 255.0; - double dG = unG / 255.0; - double dB = unB / 255.0; - - m_pStream->WriteReal(dR); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dG); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dB); - m_pStream->WriteStr(" rg\012"); - - m_pGrState->m_oFillColor.r = dR; - m_pGrState->m_oFillColor.g = dG; - m_pGrState->m_oFillColor.b = dB; - } - void CPage::Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY) - { - // Operator : cm - // Description: меняем матрицу преобразований (CTM - Current Transformation Matrix) - - m_pStream->WriteReal(dM11); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM12); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM21); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM22); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dX); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" cm\012"); - - CMatrix oCTM = m_pGrState->m_oMatrix; - - // перемножаем матрицы oCTM(новая)= oCTM(преобразования(которая параметрами задана)) x oCTM(старая) - m_pGrState->m_oMatrix.m11 = dM11 * oCTM.m11 + dM12 * oCTM.m21; - m_pGrState->m_oMatrix.m12 = dM11 * oCTM.m12 + dM12 * oCTM.m22; - m_pGrState->m_oMatrix.m21 = dM21 * oCTM.m11 + dM22 * oCTM.m21; - m_pGrState->m_oMatrix.m22 = dM21 * oCTM.m12 + dM22 * oCTM.m22; - m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; - m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; - } - void CPage::SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) - { - CMatrix oInverse = m_pGrState->m_oMatrix.Inverse(); - - CMatrix oResult; - oResult.m11 = dM11 * oInverse.m11 + dM12 * oInverse.m21; - oResult.m12 = dM11 * oInverse.m12 + dM12 * oInverse.m22; - oResult.m21 = dM21 * oInverse.m11 + dM22 * oInverse.m21; - oResult.m22 = dM21 * oInverse.m12 + dM22 * oInverse.m22; - oResult.x = dX * oInverse.m11 + dY * oInverse.m21 + oInverse.x; - oResult.y = dX * oInverse.m12 + dY * oInverse.m22 + oInverse.y; - - if (!oResult.IsIdentity()) - Concat(oResult.m11, oResult.m12, oResult.m21, oResult.m22, oResult.x, oResult.y); - } - void CPage::Clip() - { - // Operator : W - // Description: Изменяем текущий clipping path, пересакая его с текущим path, ипользуя правило Nonzero - // Winding Number Rule, для определения какие регионы лежат внутри clipping path. - SetGrMode(grmode_CLIP); - m_pStream->WriteStr("W\012"); - } - void CPage::Eoclip() - { - // Operator : W* - // Description: Изменяем текущий clipping path, пересакая его с текущим path, ипользуя правило Even-Odd - // Rule, для определения какие регионы лежат внутри clipping path. - SetGrMode(grmode_CLIP); - m_pStream->WriteStr("W*\012"); - } - void CPage::SetExtGrState(CExtGrState* pState) - { - if (!pState) - return; - - // Operator : gs - // Description: устанавливаем сразу все настройки данного графического состояния(ExtGState) - - const char* sGsName = GetExtGrStateName(pState); - if (!sGsName) - return; - - m_pStream->WriteEscapeName(sGsName); - m_pStream->WriteStr(" gs\012"); - } - const char* CPage::GetExtGrStateName(CExtGrState* pState) - { - const char *sKey; - - if (!m_pExtGStates) - { - CDictObject* pResources = (CDictObject*)GetResourcesItem(); - if (!pResources) - return NULL; - - m_pExtGStates = new CDictObject(); - if (!m_pExtGStates) - return NULL; - - pResources->Add("ExtGState", m_pExtGStates); - } - - sKey = m_pExtGStates->GetKey(pState); - if (!sKey) - { - // Если ExtGState не зарегистрирован в Resource, регистрируем. - char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); - ItoA(pPointer, ++m_unExtGStatesCount, pEndPointer); - m_pExtGStates->Add(sExtGrStateName, pState); - sKey = m_pExtGStates->GetKey(pState); - } - - return sKey; - } - void CPage::AddAnnotation(CDictObject* pAnnot) - { - CArrayObject* pArray = (CArrayObject*)Get("Annots"); - if (!pArray) - { - pArray = new CArrayObject(); - if (!pArray) - return; - - Add("Annots", pArray); - } - - return pArray->Add(pAnnot); - } - void CPage::BeginText() - { - // Operator : BT - // Description: Начало текста - SetGrMode(grmode_TEXT); - m_pStream->WriteStr("BT\012"); - - m_oTextPos.Reset(); - m_oTextMatrix.Reset(); - } - void CPage::EndText() - { - // Operator : ET - // Description: Окончание текста - CheckGrMode(grmode_TEXT); - m_pStream->WriteStr("ET\012"); - SetGrMode(grmode_PAGE); - } - void CPage::MoveTextPos(double dX, double dY) - { - // Operator : Td - // Description: Переходим к началу следующей линии, сдвигаясь от начала текущей на ( fX, fY ). - CheckGrMode(grmode_TEXT); - - m_pStream->WriteReal(dX); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" Td\012"); - - m_oTextMatrix.x += dX * m_oTextMatrix.m11 + dY * m_oTextMatrix.m21; - m_oTextMatrix.y += dX * m_oTextMatrix.m12 + dY * m_oTextMatrix.m22; - m_oTextPos.Set(m_oTextMatrix.x, m_oTextMatrix.y); - } - void CPage::ShowText(const BYTE* sText, unsigned int unLen) - { - // Operator : Tj - // Description: Показать текстовую строку. - CheckGrMode(grmode_TEXT); - WriteText(sText, unLen); - m_pStream->WriteStr(" Tj\012"); - } - void CPage::WriteText(const BYTE* sText, unsigned int unLen) - { - EFontType eType = m_pFont->GetFontType(); - if (fontCIDType0 == eType || fontCIDType0C == eType || fontCIDType0COT == eType || fontCIDType2 == eType || fontCIDType2OT == eType) - { - m_pStream->WriteChar('<'); - m_pStream->WriteBinary(sText, unLen, NULL); - m_pStream->WriteChar('>'); - } - else - { - m_pStream->WriteEscapeText(sText, unLen); - } - } - void CPage::DrawText(double dXpos, double dYpos, const BYTE* sText, unsigned int unLen) - { - CheckGrMode(grmode_TEXT); - - double dX = 0.0; - double dY = 0.0; - - if (0 == m_oTextMatrix.m11) - { - dY = (dXpos - m_oTextMatrix.x) / m_oTextMatrix.m21; - dX = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m22 / m_oTextMatrix.m21) / m_oTextMatrix.m12; - } - else - { - dY = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m12 / m_oTextMatrix.m11) / (m_oTextMatrix.m22 - m_oTextMatrix.m21 * m_oTextMatrix.m12 / m_oTextMatrix.m11); - dX = (dXpos - m_oTextMatrix.x - dY * m_oTextMatrix.m21) / m_oTextMatrix.m11; - } - - MoveTextPos(dX, dY); - ShowText(sText, unLen); - } - void CPage::DrawTextLine(const CTextLine* pTextLine) - { - if (!pTextLine) - return; - - int nCount = pTextLine->m_vWords.size(); - if (nCount <= 0) - return; - - CheckGrMode(grmode_TEXT); - - double dXpos = pTextLine->m_dX; - double dYpos = pTextLine->m_dY; - - double dX = 0.0; - double dY = 0.0; - - if (0 == m_oTextMatrix.m11) - { - dY = (dXpos - m_oTextMatrix.x) / m_oTextMatrix.m21; - dX = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m22 / m_oTextMatrix.m21) / m_oTextMatrix.m12; - } - else - { - dY = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m12 / m_oTextMatrix.m11) / (m_oTextMatrix.m22 - m_oTextMatrix.m21 * m_oTextMatrix.m12 / m_oTextMatrix.m11); - dX = (dXpos - m_oTextMatrix.x - dY * m_oTextMatrix.m21) / m_oTextMatrix.m11; - } - MoveTextPos(dX, dY); - - if (1 == nCount) - { - CTextWord* pWord = pTextLine->m_vWords.at(0); - ShowText(pWord->m_pText, pWord->m_nIndex * 2); - } - else - { - CTextWord* pWord = NULL; - double dShift = 0; - m_pStream->WriteChar('['); - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - pWord = pTextLine->m_vWords.at(nIndex); - WriteText(pWord->m_pText, pWord->m_nIndex * 2); - if (nIndex != nCount - 1) - { - dShift = pTextLine->m_vShifts.at(nIndex); - m_pStream->WriteReal(dShift); - } - } - m_pStream->WriteStr("]TJ\012"); - } - } - void CPage::SetCharSpace(double dValue) - { - // Operator : Tc - // Description: Устанавливаем расстояние между буквами - CheckGrMode(grmode_TEXT); - - dValue = std::min((double)MAX_CHARSPACE, std::max((double)MIN_CHARSPACE, dValue)); - m_pStream->WriteReal(dValue); - m_pStream->WriteStr(" Tc\012"); - } - void CPage::SetHorizontalScalling(double dValue) - { - // Operator : Tz - // Description: Устанавливаем горизонтальное растяжение/сжатие - CheckGrMode(grmode_TEXT); - - dValue = std::min((double)MAX_HORIZONTALSCALING, std::max((double)MIN_HORIZONTALSCALING, dValue)); - m_pStream->WriteReal(dValue); - m_pStream->WriteStr(" Tz\012"); - } - void CPage::SetFontAndSize(CFontDict* pFont, double dSize) - { - // Operator : Tf - // Description: Устанавливаем фонт и размер фонта - - dSize = std::min((double)MAX_FONTSIZE, std::max(0.0, dSize)); - const char* sFontName = GetLocalFontName(pFont); - if (!sFontName) - return; - - m_pStream->WriteEscapeName(sFontName); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dSize); - m_pStream->WriteStr(" Tf\012"); - - m_pFont = pFont; - } - const char* CPage::GetLocalFontName(CFontDict* pFont) - { - if (!m_pFonts) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pFonts = new CDictObject(); - if (!m_pFonts) - return NULL; - - pResources->Add("Font", m_pFonts); - } - - const char *sKey = m_pFonts->GetKey(pFont); - if (!sKey) - { - // если фонт не зарегистрирован в ресурсах, тогда регистрируем его - char sFontName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer = NULL; - char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; - - ++m_unFontsCount; - while (m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) - { - if (m_pFonts->Get("F" + std::to_string(m_unFontsCount))) - ++m_unFontsCount; - else - break; - } - - pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); - ItoA(pPointer, m_unFontsCount, pEndPointer); - m_pFonts->Add(sFontName, pFont); - sKey = m_pFonts->GetKey(pFont); - } - - return sKey; - } - void CPage::SetTextRenderingMode(ETextRenderingMode eMode) - { - // Operator : Tr - // Description: Устанавливаем тип закрашивания символов (TextRenderingMode) - CheckGrMode(grmode_TEXT); - m_pStream->WriteInt((int)eMode); - m_pStream->WriteStr(" Tr\012"); - } - void CPage::SetTextMatrix(double dM11, double dM12, double dM21, double dM22, double dX, double dY) - { - // Operator : Tm - // Description: Устанавливаем матрицу преобразования для текста. - CheckGrMode(grmode_TEXT); - - m_pStream->WriteReal(dM11); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM12); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM21); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dM22); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dX); - m_pStream->WriteChar(' '); - m_pStream->WriteReal(dY); - m_pStream->WriteStr(" Tm\012"); - - m_oTextMatrix.m11 = dM11; - m_oTextMatrix.m12 = dM12; - m_oTextMatrix.m21 = dM21; - m_oTextMatrix.m22 = dM22; - m_oTextMatrix.x = dX; - m_oTextMatrix.y = dY; - m_oTextPos.Set(m_oTextMatrix.x, m_oTextMatrix.y); - } - void CPage::ExecuteXObject(CXObject* pXObject) - { - const char* sXObjectName = GetXObjectName(pXObject); - - if (!sXObjectName) - return; - - m_pStream->WriteEscapeName(sXObjectName); - m_pStream->WriteStr(" Do\012"); - } - void CPage::DrawImage(CImageDict* pImage, double dX, double dY, double dWidth, double dHeight) - { - GrSave(); - Concat(dWidth, 0, 0, dHeight, dX, dY); - ExecuteXObject(pImage); - GrRestore(); - } - const char* CPage::GetXObjectName(CXObject* pObject) - { - if (!m_pXObjects) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pXObjects = new CDictObject(); - if (!m_pXObjects) - return NULL; - - pResources->Add("XObject", m_pXObjects); - } - - const char* sKey = m_pXObjects->GetKey(pObject); - if (!sKey) - { - char sXObjName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); - ItoA(pPointer, ++m_unXObjectsCount, pEndPointer); - m_pXObjects->Add(sXObjName, pObject); - sKey = m_pXObjects->GetKey(pObject); - } - - return sKey; - } - void CPage::DrawShading(CShading* pShading) - { - // Operator : sh - // Description: отрисовываем градиент - - const char* sShadingName = GetLocalShadingName(pShading); - if (!sShadingName) - return; - - m_pStream->WriteEscapeName(sShadingName); - m_pStream->WriteStr(" sh\012"); - } - void CPage::SetStrokeAlpha(unsigned char unAlpha) - { - CExtGrState* pExtGrState = m_pDocument->GetStrokeAlpha((double)(unAlpha / 255.0)); - if (pExtGrState) - SetExtGrState(pExtGrState); - } - void CPage::SetFillAlpha(unsigned char unAlpha) - { - CExtGrState* pExtGrState = m_pDocument->GetFillAlpha((double)(unAlpha / 255.0)); - if (pExtGrState) - SetExtGrState(pExtGrState); - } - const char* CPage::GetLocalShadingName(CShading* pShading) - { - if (!m_pShadings) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pShadings = new CDictObject(); - if (!m_pShadings) - return NULL; - - pResources->Add("Shading", m_pShadings); - } - - const char* sKey = m_pShadings->GetKey(pShading); - if (!sKey) - { - char sShadingName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sShadingName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sShadingName, "S", pEndPointer); - ItoA(pPointer, ++m_unShadingsCount, pEndPointer); - m_pShadings->Add(sShadingName, pShading); - sKey = m_pShadings->GetKey(pShading); - } - - return sKey; - } - const char* CPage::GetLocalPatternName(CImageTilePattern* pPattern) - { - if (!m_pPatterns) - { - CDictObject* pResources = GetResourcesItem(); - if (!pResources) - return NULL; - - m_pPatterns = new CDictObject(); - if (!m_pPatterns) - return NULL; - - pResources->Add("Pattern", m_pPatterns); - } - - const char* sKey = m_pPatterns->GetKey(pPattern); - if (!sKey) - { - char sPatternName[LIMIT_MAX_NAME_LEN + 1]; - char *pPointer; - char *pEndPointer = sPatternName + LIMIT_MAX_NAME_LEN; - - pPointer = (char*)StrCpy(sPatternName, "P", pEndPointer); - ItoA(pPointer, m_unPatternsCount + 1, pEndPointer); - m_unPatternsCount++; - m_pPatterns->Add(sPatternName, pPattern); - sKey = m_pPatterns->GetKey(pPattern); - } - - return sKey; - } - void CPage::SetPatternColorSpace(CImageTilePattern* pPattern) - { - // Operator : csn - // Description: задаем паттерн для рисования - - const char* sPatternName = GetLocalPatternName(pPattern); - if (!sPatternName) - return; - - m_pStream->WriteStr("/Pattern cs\012"); - m_pStream->WriteEscapeName(sPatternName); - m_pStream->WriteStr(" scn\012"); - } - void CPage::SetFilter(unsigned int unFiler) - { - if (m_pContents) - { - for (unsigned int unKidIndex = 0, unKidsCount = m_pContents->GetCount(); unKidIndex < unKidsCount; ++unKidIndex) - { - CObjectBase* pKid = m_pContents->Get(unKidIndex); - if (pKid->GetType() == object_type_DICT) - ((CDictObject*)pKid)->SetFilter(unFiler); - } - } - } - CMatrix* CPage::GetTransform() - { - return &m_pGrState->m_oMatrix; - } - void CPage::AddGroup(CDictObject* pDict) - { - Add("Group", pDict); - } - void CPage::AddContents(CXref* pXref) - { - CDictObject* pContent = new CDictObject(pXref); - m_pContents->Add(pContent); - m_pStream = pContent->GetStream(); - } - void CPage::SetRotate(int nRotate) - { - // The value shall be a multiple of 90 - if (nRotate > 0 && nRotate % 90 == 0) - { - CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); - if (pRotate) - Add("Rotate", (nRotate + pRotate->Get()) % 360); - else - Add("Rotate", nRotate % 360); - } - } - //---------------------------------------------------------------------------------------- - // CTextWord - //---------------------------------------------------------------------------------------- - CTextWord::CTextWord() - { - m_nIndex = 0; - m_pText = (unsigned char*)malloc(STR_BUF); - m_nSize = STR_BUF; - } - CTextWord::~CTextWord() - { - if (m_pText) - free(m_pText); - } - void CTextWord::CheckBuffer() - { - if (2 * m_nIndex >= m_nSize) - { - m_nSize += STR_BUF; - m_pText = (unsigned char*)realloc(m_pText, m_nSize); - } - } - bool CTextWord::Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth) - { - if (2 != unLen) - return false; - - CheckBuffer(); - - if (0 == m_nIndex) - { - m_pText[0] = pCodes[0]; - m_pText[1] = pCodes[1]; - m_nIndex++; - m_dStartX = dX; - m_dStartY = dY; - - m_dCurX = dX + dWidth; - } - else - { - if (fabs(dY - m_dStartY) > 0.001 || fabs(dX - m_dCurX) > 0.01) - return false; - - m_pText[m_nIndex * 2 + 0] = pCodes[0]; - m_pText[m_nIndex * 2 + 1] = pCodes[1]; - m_nIndex++; - - m_dCurX = dX + dWidth; - } - - return true; - } - //---------------------------------------------------------------------------------------- - // CTextLine - //---------------------------------------------------------------------------------------- - CTextLine::CTextLine() - { - } - CTextLine::~CTextLine() - { - Clear(); - } - bool CTextLine::Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth, double dSize) - { - if (2 != unLen) - return false; - - if (0 == m_vWords.size()) - { - CTextWord* pText = new CTextWord(); - if (!pText || !pText->Add(pCodes, unLen, dX, dY, dWidth)) - return false; - - m_vWords.push_back(pText); - m_dX = dX; - m_dY = dY; - return true; - } - - if (fabs(dY - m_dY) > 0.001) - return false; - - CTextWord* pLastText = m_vWords.at(m_vWords.size() - 1); - if (pLastText->Add(pCodes, unLen, dX, dY, dWidth)) - return true; - - CTextWord* pText = new CTextWord(); - if (!pText || !pText->Add(pCodes, unLen, dX, dY, dWidth)) - return false; - - m_vWords.push_back(pText); - double dShift = (pLastText->m_dCurX - dX) * 1000 / dSize; - m_vShifts.push_back(dShift); - return true; - } - void CTextLine::Flush(CPage* pPage) - { - pPage->DrawTextLine(this); - Clear(); - } - void CTextLine::Clear() - { - for (int nIndex = 0, nCount = m_vWords.size(); nIndex < nCount; nIndex++) - { - CTextWord* pText = m_vWords.at(nIndex); - RELEASEOBJECT(pText); - } - m_vWords.clear(); - m_vShifts.clear(); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Objects.h" +#include "Pages.h" +#include "Utils.h" +#include "GState.h" +#include "Streams.h" +#include "Annotation.h" +#include "Font.h" +#include "Image.h" +#include "Shading.h" +#include "Pattern.h" +#include "Document.h" +#include "Field.h" + +#ifdef DrawText +#undef DrawText +#endif + +#define MIN_HORIZONTALSCALING 0.01 +#define MAX_HORIZONTALSCALING 1000 +#define MIN_CHARSPACE -30 +#define MAX_CHARSPACE 300 +#define MAX_FONTSIZE 1000 + +#define STR_BUF 200 + +namespace PdfWriter +{ + static const double c_dKappa = 0.552; + static void QuarterEllipseA(CStream* pStream, double dX, double dY, double dXRad, double dYRad) + { + pStream->WriteReal(dX - dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY + dYRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dX - dXRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dY + dYRad); + pStream->WriteChar(' '); + pStream->WriteReal(dX); + pStream->WriteChar(' '); + pStream->WriteReal(dY + dYRad); + pStream->WriteStr(" c\012"); + } + static void QuarterEllipseB(CStream* pStream, double dX, double dY, double dXRad, double dYRad) + { + pStream->WriteReal(dX + dXRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dY + dYRad); + pStream->WriteChar(' '); + pStream->WriteReal(dX + dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY + dYRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dX + dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY); + pStream->WriteStr(" c\012"); + } + static void QuarterEllipseC(CStream* pStream, double dX, double dY, double dXRad, double dYRad) + { + pStream->WriteReal(dX + dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY - dYRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dX + dXRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dY - dYRad); + pStream->WriteChar(' '); + pStream->WriteReal(dX); + pStream->WriteChar(' '); + pStream->WriteReal(dY - dYRad); + pStream->WriteStr(" c\012"); + } + static void QuarterEllipseD(CStream* pStream, double dX, double dY, double dXRad, double dYRad) + { + pStream->WriteReal(dX - dXRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dY - dYRad); + pStream->WriteChar(' '); + pStream->WriteReal(dX - dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY - dYRad * c_dKappa); + pStream->WriteChar(' '); + pStream->WriteReal(dX - dXRad); + pStream->WriteChar(' '); + pStream->WriteReal(dY); + pStream->WriteStr(" c\012"); + } + static double AngToEllPrm(double dAngle, double dXRad, double dYRad) + { + // Функция для перевода реального угла в параметрическое задание эллписа + // т.е. x= a cos(t) y = b sin(t) - параметрическое задание эллписа. + // x = r cos(p), y = r sin(p) => t = atan2( sin(p) / b, cos(p) / a ); + return atan2(sin(dAngle) / dYRad, cos(dAngle) / dXRad); + } + static void WriteEllipseArc(CStream* pStream, double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, double& dXCur, double& dYCur, bool bClockDirection = false) + { + // Рассчитаем начальную, конечную и контрольные точки + double dX1 = 0.0, dX2 = 0.0, dY1 = 0.0, dY2 = 0.0; + double dCX1 = 0.0, dCX2 = 0.0, dCY1 = 0.0, dCY2 = 0.0; + + double dAlpha = sin(dAngle2 - dAngle1) * (sqrt(4.0 + 3.0 * tan((dAngle2 - dAngle1) / 2.0) * tan((dAngle2 - dAngle1) / 2.0)) - 1.0) / 3.0; + + dX1 = dX + dXRad * cos(dAngle1); + dY1 = dY + dYRad * sin(dAngle1); + + dX2 = dX + dXRad * cos(dAngle2); + dY2 = dY + dYRad * sin(dAngle2); + + dCX1 = dX1 - dAlpha * dXRad * sin(dAngle1); + dCY1 = dY1 + dAlpha * dYRad * cos(dAngle1); + + dCX2 = dX2 + dAlpha * dXRad * sin(dAngle2); + dCY2 = dY2 - dAlpha * dYRad * cos(dAngle2); + + if ( !bClockDirection ) + { + pStream->WriteReal(dCX1); + pStream->WriteChar(' '); + pStream->WriteReal(dCY1); + pStream->WriteChar(' '); + pStream->WriteReal(dCX2); + pStream->WriteChar(' '); + pStream->WriteReal(dCY2); + pStream->WriteChar(' '); + pStream->WriteReal(dX2); + pStream->WriteChar(' '); + pStream->WriteReal(dY2); + dXCur = dX2; + dYCur = dY2; + } + else + { + pStream->WriteReal(dCX2); + pStream->WriteChar(' '); + pStream->WriteReal(dCY2); + pStream->WriteChar(' '); + pStream->WriteReal(dCX1); + pStream->WriteChar(' '); + pStream->WriteReal(dCY1); + pStream->WriteChar(' '); + pStream->WriteReal(dX1); + pStream->WriteChar(' '); + pStream->WriteReal(dY1); + dXCur = dX1; + dYCur = dY1; + } + pStream->WriteStr(" c\012"); + } + //---------------------------------------------------------------------------------------- + // CPageTree + //---------------------------------------------------------------------------------------- + CPageTree::CPageTree(CXref* pXref) + { + m_pXref = pXref; + pXref->Add(this); + + m_pPages = new CArrayObject(); + m_pCount = new CNumberObject(0); + + Add("Type", "Pages"); + Add("Kids", m_pPages); + Add("Count", m_pCount); + } + CPageTree::CPageTree(CXref* pXref, bool bEmpty) + { + m_pXref = pXref; + pXref->Add(this); + + m_pPages = NULL; + m_pCount = NULL; + } + void CPageTree::Fix() + { + // Инициализация текущего m_pPages + CObjectBase* pPages = Get("Kids"); + if (pPages && pPages->GetType() == object_type_ARRAY) + m_pPages = (CArrayObject*)pPages; + else + { + m_pPages = new CArrayObject(); + Add("Kids", m_pPages); + } + + // Инициализация текущего m_pCount + CObjectBase* pCount = Get("Count"); + if (pCount && pCount->GetType() == object_type_NUMBER) + m_pCount = (CNumberObject*)pCount; + else + { + m_pCount = new CNumberObject(0); + Add("Count", m_pCount); + } + } + void CPageTree::AddPage(CDictObject* pPage) + { + m_pPages->Add(pPage); + (*m_pCount)++; + } + CObjectBase* CPageTree::GetObj(int nPageIndex) + { + int nI = 0; + return GetFromPageTree(nPageIndex, nI); + } + CPage* CPageTree::GetPage(int nPageIndex) + { + int nI = 0; + CObjectBase* pObj = GetFromPageTree(nPageIndex, nI); + if (pObj && pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) + return (CPage*)pObj; + return NULL; + } + CObjectBase* CPageTree::RemovePage(int nPageIndex) + { + int nI = 0; + return GetFromPageTree(nPageIndex, nI, true); + } + bool CPageTree::InsertPage(int nPageIndex, CPage* pPage) + { + if (nPageIndex >= m_pCount->Get()) + { + AddPage(pPage); + pPage->Add("Parent", this); + return true; + } + int nI = 0; + CObjectBase* pObj = GetFromPageTree(nPageIndex, nI, false, true, pPage); + if (pObj) + return true; + return false; + } + CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CPage* pPage) + { + for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) + { + CObjectBase* pObj = m_pPages->Get(i); + CObjectBase* pRes = NULL; + if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGES) + pRes = ((CPageTree*)pObj)->GetFromPageTree(nPageIndex, nI, bRemove, bInsert, pPage); + else + { + if (nPageIndex == nI) + { + pRes = pObj; + if (bRemove) + pRes = m_pPages->Remove(i); + if (bInsert) + { + m_pPages->Insert(pObj, pPage); + pPage->Add("Parent", this); + } + } + nI++; + } + if (pRes) + { + if (bRemove) + (*m_pCount)--; + if (bInsert) + (*m_pCount)++; + return pRes; + } + } + return NULL; + } + bool CPageTree::Join(CPageTree* pPageTree) + { + unsigned int nObjId = pPageTree->GetObjId(); + unsigned int nGenNo = pPageTree->GetGenNo(); + for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) + { + CObjectBase* pObj = m_pPages->Get(i); + if (pObj->GetObjId() == nObjId && pObj->GetGenNo() == nGenNo) + { + m_pPages->Insert(pObj, pPageTree, true); + return true; + } + if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGES && ((CPageTree*)pObj)->Join(pPageTree)) + return true; + } + return false; + } + //---------------------------------------------------------------------------------------- + // CPage + //---------------------------------------------------------------------------------------- + CPage::CPage(CXref* pXref, CDocument* pDocument) + { + Init(pXref, pDocument); + } + void CPage::Fix() + { + // Инициализация текущего contents + CObjectBase* pContents = Get("Contents"); + if (pContents) + { + if (pContents->GetType() == object_type_ARRAY) + m_pContents = (CArrayObject*)pContents; + else if (pContents->GetType() == object_type_UNKNOWN) + { + CProxyObject* pNewContents = new CProxyObject(pContents->Copy(), true); + pNewContents->Get()->SetRef(pContents->GetObjId(), pContents->GetGenNo()); + m_pContents = new CArrayObject(); + m_pContents->Add(pNewContents); + Add("Contents", m_pContents); + } + } + else + { + m_pContents = new CArrayObject(); + Add("Contents", m_pContents); + } + + // Инициализация текущего MediaBox + CObjectBase* pMediaBox = Get("MediaBox"); + if (pMediaBox && pMediaBox->GetType() == object_type_ARRAY) + { + double dL = 0.0, dB = 0.0, dR = DEF_PAGE_WIDTH, dT = DEF_PAGE_HEIGHT; + + CObjectBase* val = ((CArrayObject*)pMediaBox)->Get(0); + if (val && val->GetType() == object_type_NUMBER) + dL = ((CNumberObject*)val)->Get(); + else if (val && val->GetType() == object_type_REAL) + dL = ((CRealObject*)val)->Get(); + + val = ((CArrayObject*)pMediaBox)->Get(1); + if (val && val->GetType() == object_type_NUMBER) + dB = ((CNumberObject*)val)->Get(); + else if (val && val->GetType() == object_type_REAL) + dB = ((CRealObject*)val)->Get(); + + val = ((CArrayObject*)pMediaBox)->Get(2); + if (val && val->GetType() == object_type_NUMBER) + dR = ((CNumberObject*)val)->Get(); + else if (val && val->GetType() == object_type_REAL) + dR = ((CRealObject*)val)->Get(); + + val = ((CArrayObject*)pMediaBox)->Get(3); + if (val && val->GetType() == object_type_NUMBER) + dT = ((CNumberObject*)val)->Get(); + else if (val && val->GetType() == object_type_REAL) + dT = ((CRealObject*)val)->Get(); + + Add("MediaBox", CArrayObject::CreateBox(dL, dB, dR, dT)); + } + else + Add("MediaBox", CArrayObject::CreateBox(0, 0, DEF_PAGE_WIDTH, DEF_PAGE_HEIGHT)); + + // Инициализация текущего Rotate + CObjectBase* pRotate = GetRotateItem(); + if (pRotate && pRotate->GetType() == object_type_NUMBER) + Add("Rotate", ((CNumberObject*)pRotate)->Get() % 360); + + CDictObject* pResources = GetResourcesItem(); + if (pResources) + { + // Инициализация текущего fonts + CObjectBase* pFonts = pResources->Get("Font"); + if (pFonts && pFonts->GetType() == object_type_DICT) + { + m_pFonts = (CDictObject*)pFonts; + m_unFontsCount = 0; + } + + // Инициализация текущего ExtGStates + CObjectBase* pExtGStates = pResources->Get("ExtGState"); + if (pExtGStates && pExtGStates->GetType() == object_type_DICT) + { + m_pExtGStates = (CDictObject*)pExtGStates; + m_unExtGStatesCount = m_pExtGStates->GetSize(); + } + + // Инициализация текущего XObject + CObjectBase* pXObject = pResources->Get("XObject"); + if (pXObject && pXObject->GetType() == object_type_DICT) + { + m_pXObjects = (CDictObject*)pXObject; + m_unXObjectsCount = m_pXObjects->GetSize(); + } + + // Инициализация текущего Shading + CObjectBase* pShading = pResources->Get("Shading"); + if (pShading && pShading->GetType() == object_type_DICT) + { + m_pShadings = (CDictObject*)pShading; + m_unShadingsCount = m_pShadings->GetSize(); + } + + // Инициализация текущего Pattern + CObjectBase* pPattern = pResources->Get("Pattern"); + if (pPattern && pPattern->GetType() == object_type_DICT) + { + m_pPatterns = (CDictObject*)pPattern; + m_unPatternsCount = m_pPatterns->GetSize(); + } + } + else + Add("Resources", new CDictObject()); + + m_pStream = NULL; + } + CPage::CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument) + { + Init(pXref, pDocument); + + m_pContents = new CArrayObject(); + CDictObject* pContent = new CDictObject(pXref); + m_pContents->Add(pContent); + m_pStream = pContent->GetStream(); + + Add("Parent", pParent); + Add("MediaBox", CArrayObject::CreateBox(0, 0, DEF_PAGE_WIDTH, DEF_PAGE_HEIGHT)); + Add("Type", "Page"); + Add("Contents", m_pContents); + AddResource(); + } + CPage::~CPage() + { + CGrState* pGrState = m_pGrState, *pPrev = NULL; + while (pGrState) + { + pPrev = m_pGrState->GetPrev(); + delete pGrState; + pGrState = pPrev; + } + } + void CPage::Init(CXref* pXref, CDocument* pDocument) + { + pXref->Add(this); + + m_pXref = pXref; + m_pDocument = pDocument; + m_eGrMode = grmode_PAGE; + m_pGrState = new CGrState(NULL); + + m_pExtGStates = NULL; + m_unExtGStatesCount = 0; + m_pFonts = NULL; + m_pFont = NULL; + m_unFontsCount = 0; + m_pXObjects = NULL; + m_unXObjectsCount = 0; + m_pShadings = NULL; + m_unShadingsCount = 0; + m_pPatterns = NULL; + m_unPatternsCount = 0; + } + void CPage::SetWidth(double dValue) + { + dValue = std::min(std::max(dValue, 1.0), 14400.0); + SetMediaBoxValue(2, dValue); + } + double CPage::GetWidth() + { + return GetMediaBox().fRight; + } + void CPage::SetHeight(double dValue) + { + dValue = std::min(std::max(dValue, 1.0), 14400.0); + SetMediaBoxValue(3, dValue); + } + double CPage::GetHeight() + { + return GetMediaBox().fTop; + } + TBox CPage::GetMediaBox() + { + TBox oMediaBox = TRect( 0, 0, 0, 0 ); + + CArrayObject* pArray = GetMediaBoxItem(); + + if (pArray) + { + CRealObject* pReal; + + pReal = (CRealObject*)pArray->Get(0); + if (pReal) + oMediaBox.fLeft = pReal->Get(); + + pReal = (CRealObject*)pArray->Get(1); + if (pReal) + oMediaBox.fBottom = pReal->Get(); + + pReal = (CRealObject*)pArray->Get(2); + if (pReal) + oMediaBox.fRight = pReal->Get(); + + pReal = (CRealObject*)pArray->Get(3); + if (pReal) + oMediaBox.fTop = pReal->Get(); + } + + return oMediaBox; + } + void CPage::SetMediaBoxValue(unsigned int unIndex, double dValue) + { + CArrayObject* pArray = GetMediaBoxItem(); + if (!pArray) + return; + + CRealObject* pReal = (CRealObject*)pArray->Get(unIndex); + if (!pReal) + return; + + pReal->Set(dValue); + } + CArrayObject* CPage::GetMediaBoxItem() + { + return (CArrayObject*)Get("MediaBox"); + } + CDictObject* CPage::GetResourcesItem() + { + CObjectBase* pObject = Get("Resources"); + + // Если объект Resources нулевой, тогда ищем Resources у родительского объекта рекурсивно + if (!pObject) + { + CPageTree* pPageTree = (CPageTree*)Get("Parent"); + while (pPageTree) + { + pObject = Get("Resources"); + + if (pObject) + break; + + pPageTree = (CPageTree*)pPageTree->Get("Parent"); + } + } + + return (CDictObject*)pObject; + } + CObjectBase* CPage::GetCropBoxItem() + { + return Get("CropBox"); + } + CObjectBase* CPage::GetRotateItem() + { + return Get("Rotate"); + } + void CPage::AddResource() + { + // TODO: Переделать на ResourcesDict + CDictObject* pResource = new CDictObject(); + if (!pResource) + return; + + // Не смотря на то, что ProcSet - устаревший объект, добавляем + // его для совместимости + Add("Resources", pResource); + + CArrayObject* pProcset = new CArrayObject(); + if (!pProcset) + return; + + pResource->Add("ProcSet", pProcset); + pProcset->Add(new CNameObject("PDF")); + pProcset->Add(new CNameObject("Text")); + pProcset->Add(new CNameObject("ImageB")); + pProcset->Add(new CNameObject("ImageC")); + pProcset->Add(new CNameObject("ImageI")); + } + void CPage::BeforeWrite() + { + if (grmode_PATH == m_eGrMode) + EndPath(); + + if (grmode_TEXT == m_eGrMode) + EndText(); + + while (m_pGrState->GetPrev()) + { + GrRestore(); + } + } + void CPage::SetGrMode(EGrMode eMode) + { + m_eGrMode = eMode; + // TODO: Сделать проверку плохих ситуаций + } + void CPage::CheckGrMode(EGrMode eMode) + { + // TODO: Сделать проверку плохих ситуаций + } + void CPage::MoveTo (double dX, double dY) + { + // Operator : m + // Description: Начинаем новый subpath, передвигая текущий указатель в точку (x, y)(она же стартовая). + + SetGrMode(grmode_PATH); + m_pStream->WriteReal(dX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" m\012"); + + m_oCurPos.Set(dX, dY); + m_oStartPos = m_oCurPos; + } + void CPage::LineTo (double dX, double dY) + { + // Operator : l + // Description: Добавляем линию от текущей точки до точки (x, y). Текущую точку выставляем (х, у). + CheckGrMode(grmode_PATH); + + m_pStream->WriteReal(dX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" l\012"); + + m_oCurPos.Set(dX, dY); + } + void CPage::CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3) + { + // Operator : c + // Description: Добавляем кривую Безье(кубическую). Начинается кривая в текущей позиции, заканчивается + // в точке (x3, y3). (x1, y1) и (x2, y2) - контрольные точки. Текущую точку устанавливаем + // в (х3, у3). + CheckGrMode(grmode_PATH); + + m_pStream->WriteReal(dX1); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY1); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dX2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY2); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dX3); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY3); + m_pStream->WriteStr(" c\012"); + + m_oCurPos.Set(dX3, dY3); + } + void CPage::Ellipse(double dX, double dY, double dXRay, double dYRay) + { + SetGrMode(grmode_PATH); + + m_pStream->WriteReal(dX - dXRay); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" m\012"); + + QuarterEllipseA(m_pStream, dX, dY, dXRay, dYRay); + QuarterEllipseB(m_pStream, dX, dY, dXRay, dYRay); + QuarterEllipseC(m_pStream, dX, dY, dXRay, dYRay); + QuarterEllipseD(m_pStream, dX, dY, dXRay, dYRay); + + m_oCurPos.Set(dX - dXRay, dY); + m_oStartPos = m_oCurPos; + } + void CPage::EllipseArc(double dX, double dY, double dXRad, double dYRad, double _dAngle1, double _dAngle2, bool bClockDirection) + { + CheckGrMode(grmode_PATH); + + // переведем углы в радианы + double dAngle1 = _dAngle1 * 3.141592f / 180; + double dAngle2 = _dAngle2 * 3.141592f / 180; + + // Выясним в каких четвертях находятся начальная и конечная точки + int nFirstPointQuard = int(_dAngle1) / 90 + 1; + int nSecondPointQuard = int(_dAngle2) / 90 + 1; + + nSecondPointQuard = std::min(4, std::max(1, nSecondPointQuard)); + nFirstPointQuard = std::min(4, std::max(1, nFirstPointQuard)); + + // Проведем линию в начальную точку дуги + double dStartX = 0.0, dStartY = 0.0, dEndX = 0.0, dEndY = 0.0; + + dStartX = dX + dXRad * cos(AngToEllPrm(dAngle1, dXRad, dYRad)); + dStartY = dY + dYRad * sin(AngToEllPrm(dAngle1, dXRad, dYRad)); + + //m_pStream->WriteReal(dStartX); + //m_pStream->WriteChar(' '); + //m_pStream->WriteReal(dStartY); + //m_pStream->WriteStr(" m\012"); + + // Дальше рисуем по четверям + double dCurX = dStartX, dCurY = dStartY; + double dStartAngle = dAngle1; + double dEndAngle = 0; + + if ( !bClockDirection ) + { + for (unsigned int nIndex = nFirstPointQuard; nIndex <= nSecondPointQuard; nIndex++) + { + if (nIndex == nSecondPointQuard) + dEndAngle = dAngle2; + else + dEndAngle = (90 * (nIndex)) * 3.141592f / 180; + if (!(nIndex == nFirstPointQuard)) + dStartAngle = (90 * (nIndex - 1)) * 3.141592f / 180; + + WriteEllipseArc(m_pStream, dX, dY, dXRad, dYRad, AngToEllPrm(dStartAngle, dXRad, dYRad), AngToEllPrm(dEndAngle, dXRad, dYRad), dEndX, dEndY, false); + } + } + else + { + for( unsigned int nIndex = nFirstPointQuard; nIndex >= nSecondPointQuard; nIndex-- ) + { + if ( nIndex == nFirstPointQuard ) + dStartAngle = dAngle1; + else + dStartAngle = (90 * (nIndex ) ) * 3.141592f / 180; + if ( !( nIndex == nSecondPointQuard ) ) + dEndAngle = (90 * (nIndex - 1 ) ) * 3.141592f / 180; + else + dEndAngle = dAngle2; + + WriteEllipseArc(m_pStream, dX, dY, dXRad, dYRad, AngToEllPrm(dStartAngle, dXRad, dYRad), AngToEllPrm(dEndAngle, dXRad, dYRad), dEndX, dEndY, false); + } + } + + m_oCurPos.Set(dEndX, dEndY); + m_oStartPos = m_oCurPos; + } + void CPage::EllipseArcTo(double dX, double dY, double dXRad, double dYRad, double _dAngle1, double _dAngle2, bool bClockDirection) + { + // Проверяем эллипс на невырожденность + if (dXRad < 0.001 || dYRad < 0.001) + { + double dAngle1 = _dAngle1 * 3.141592f / 180; + double dAngle2 = _dAngle2 * 3.141592f / 180; + + if (dXRad < 0.001 && dYRad < 0.001) + LineTo(dX, dY); + else if (dXRad < 0.001) + { + LineTo(dX, dY + sin(dAngle1) * dYRad); + LineTo(dX, dY + sin(dAngle2) * dYRad); + } + else // if (dYRad < 0.001) + { + LineTo(dX + cos(dAngle1) * dXRad, dY); + LineTo(dX + cos(dAngle2) * dXRad, dY); + } + return; + } + + + while (_dAngle1 < 0) + _dAngle1 += 360; + + while (_dAngle1 > 360) + _dAngle1 -= 360; + + while (_dAngle2 < 0) + _dAngle2 += 360; + + while (_dAngle2 > 360) + _dAngle2 -= 360; + + if (!bClockDirection) + { + if (_dAngle1 <= _dAngle2) + EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, _dAngle2, false); + else + { + EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, 360, false); + EllipseArc(dX, dY, dXRad, dYRad, 0, _dAngle2, false); + } + } + else + { + if (_dAngle1 >= _dAngle2) + EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, _dAngle2, true); + else + { + EllipseArc(dX, dY, dXRad, dYRad, _dAngle1, 0, true); + EllipseArc(dX, dY, dXRad, dYRad, 360, _dAngle2, true); + } + } + } + void CPage::ClosePath() + { + // Operator : h + // Description: Закрываем subpath, соединяя текущую точку с начальной прямой линией. Если subpath + // уже закрыт, тогда ничего не делаем + CheckGrMode(grmode_PATH); + m_pStream->WriteStr("h\012"); + m_oCurPos = m_oStartPos; + } + void CPage::Stroke() + { + // Operator : S + // Description: Обводим path. + + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("S\012"); + m_oCurPos.Reset(); + } + void CPage::Fill() + { + // Operator : f + // Description: Заливка path по правилу Nonzero Winding Number Rule(см. спецификацию PDF Part1: PDF 1.7 + // стр. 136, закладка 8.5.3.3.2). + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("f\012"); + m_oCurPos.Reset(); + } + void CPage::EoFill() + { + // Operator : f* + // Description: Заливка path по правилу Even-Odd Rule(см. спецификацию PDF Part1: PDF 1.7 стр. 137, + // закладка 8.5.3.3.3). + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("f*\012"); + m_oCurPos.Reset(); + } + void CPage::FillStroke() + { + // Operator : B + // Description: Заливка и обоводка path, используя правило для заливки Nonzero Winding Number Rule(см. + // спецификацию PDF Part1: PDF 1.7 стр. 136, закладка 8.5.3.3.2). Этот оператор должен + // привести к тому же самому результату как строительство двух идентичных объектов path, + // применяя к первому оператор f и ко второму - S. + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("B\012"); + m_oCurPos.Reset(); + } + void CPage::EoFillStroke() + { + // Operator : B* + // Description: Заливка и обоводка path, используя правило для заливки Even-Odd Rule(см. + // спецификацию PDF Part1: PDF 1.7 стр. 137, закладка 8.5.3.3.3). Этот оператор должен + // привести к тому же самому результату как строительство двух идентичных объектов path, + // применяя к первому оператор f* и ко второму - S. + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("B*\012"); + m_oCurPos.Reset(); + } + void CPage::EndPath() + { + // Operator : n + // Description: Закрываем path, не заливая и не обводя его. Этот оператор используется прежде всего для + // изменения текущего path. + SetGrMode(grmode_PAGE); + m_pStream->WriteStr("n\012"); + m_oCurPos.Reset(); + } + void CPage::SetLineWidth(double dLineWidth) + { + // Operator : w + // Descriprion: устанавливаем толщину линии + + dLineWidth = std::max(dLineWidth, 0.0); + m_pStream->WriteReal(dLineWidth); + m_pStream->WriteStr(" w\012"); + m_pGrState->m_dLineWidth = dLineWidth; + } + void CPage::SetLineCap(ELineCapStyle eLineCap) + { + // Operator : J + // Descriprion: устанавливаем вид окончания линии (LineCapStyle) + + eLineCap = std::max(linecap_Min, std::min(linecap_Max, eLineCap)); + m_pStream->WriteInt((unsigned int)eLineCap); + m_pStream->WriteStr(" J\012"); + m_pGrState->m_eLineCap = eLineCap; + } + void CPage::SetLineJoin(ELineJoinStyle eLineJoin) + { + // Operator : j + // Descriprion: устанавливаем вид соединения линий (LineJoinStyle) + eLineJoin = std::max(linejoin_Min, std::min(linejoin_Max, eLineJoin)); + m_pStream->WriteInt((unsigned int)eLineJoin); + m_pStream->WriteStr(" j\012"); + m_pGrState->m_eLineJoin = eLineJoin; + } + void CPage::SetMiterLimit(double dMiterLimit) + { + // Operator : M + // Descriprion: устанавливаем MiterLimit - константа, относящаяся к виду соединения линий + dMiterLimit = std::max(1.0, dMiterLimit); + m_pStream->WriteReal(dMiterLimit); + m_pStream->WriteStr(" M\012"); + m_pGrState->m_dMiterLimit = dMiterLimit; + } + void CPage::SetDash(const double* pPattern, unsigned int unCount, double dPhase) + { + // Operator : d + // Descriprion: устанавливаем вид линий (DashMode) + + if (0 == unCount || !pPattern) + return; + + bool bFalseDash = true; + for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) + { + if (0 != pPattern[unIndex]) + { + bFalseDash = false; + break; + } + } + + if (bFalseDash) + return; + + m_pStream->WriteChar('['); + for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) + { + m_pStream->WriteReal(pPattern[unIndex]); + m_pStream->WriteChar(' '); + } + m_pStream->WriteStr("] "); + m_pStream->WriteReal(dPhase); + m_pStream->WriteStr(" d\012"); + + m_pGrState->m_oDashMode.Set(pPattern, unCount, dPhase); + } + void CPage::SetFlat(double dFlatness) + { + // Operator : i + // Descriprion: устанавливаем порог ошибки линии (Flatness tolerance) + dFlatness = std::min(100.0, std::max(0.0, dFlatness)); + m_pStream->WriteReal(dFlatness); + m_pStream->WriteStr(" i\012"); + m_pGrState->m_dFlatness = dFlatness; + } + void CPage::GrSave() + { + // Operator : q + // Description: сохраняем текущий GState в графическом стеке + CheckGrMode(grmode_PAGE); + CGrState* pState = new CGrState(m_pGrState); + if (!pState) + return; + + m_pStream->WriteStr("q\012"); + m_pGrState = pState; + } + void CPage::GrRestore() + { + // Operator : Q + // Description: Восстанавливаем GState, удаляя самый последний GState, и делаем данный GState текущим + CheckGrMode(grmode_PAGE); + + if (!m_pGrState->m_pPrev) + return; + + CGrState* pPrev = m_pGrState->m_pPrev; + delete m_pGrState; + m_pGrState = pPrev; + + m_pStream->WriteStr("Q\012"); + } + void CPage::SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB) + { + // Operator : RG + // Description: Устанавливаем цветовое пространтсво для обводки в DeviceRGB и устанавливаем цвет для + // операций связанных с обведением фигур. + + double dR = unR / 255.0; + double dG = unG / 255.0; + double dB = unB / 255.0; + + m_pStream->WriteReal(dR); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dG); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dB); + m_pStream->WriteStr(" RG\012"); + + m_pGrState->m_oStrokeColor.r = dR; + m_pGrState->m_oStrokeColor.g = dG; + m_pGrState->m_oStrokeColor.b = dB; + } + void CPage::SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB) + { + // Operator : rg + // Description: Устанавливаем цветовое пространтсво для заливки в DeviceRGB и устанавливаем цвет для + // операций связанных с заливкой фигур. + + double dR = unR / 255.0; + double dG = unG / 255.0; + double dB = unB / 255.0; + + m_pStream->WriteReal(dR); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dG); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dB); + m_pStream->WriteStr(" rg\012"); + + m_pGrState->m_oFillColor.r = dR; + m_pGrState->m_oFillColor.g = dG; + m_pGrState->m_oFillColor.b = dB; + } + void CPage::Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { + // Operator : cm + // Description: меняем матрицу преобразований (CTM - Current Transformation Matrix) + + m_pStream->WriteReal(dM11); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM12); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM21); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM22); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" cm\012"); + + CMatrix oCTM = m_pGrState->m_oMatrix; + + // перемножаем матрицы oCTM(новая)= oCTM(преобразования(которая параметрами задана)) x oCTM(старая) + m_pGrState->m_oMatrix.m11 = dM11 * oCTM.m11 + dM12 * oCTM.m21; + m_pGrState->m_oMatrix.m12 = dM11 * oCTM.m12 + dM12 * oCTM.m22; + m_pGrState->m_oMatrix.m21 = dM21 * oCTM.m11 + dM22 * oCTM.m21; + m_pGrState->m_oMatrix.m22 = dM21 * oCTM.m12 + dM22 * oCTM.m22; + m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x; + m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y; + } + void CPage::SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { + CMatrix oInverse = m_pGrState->m_oMatrix.Inverse(); + + CMatrix oResult; + oResult.m11 = dM11 * oInverse.m11 + dM12 * oInverse.m21; + oResult.m12 = dM11 * oInverse.m12 + dM12 * oInverse.m22; + oResult.m21 = dM21 * oInverse.m11 + dM22 * oInverse.m21; + oResult.m22 = dM21 * oInverse.m12 + dM22 * oInverse.m22; + oResult.x = dX * oInverse.m11 + dY * oInverse.m21 + oInverse.x; + oResult.y = dX * oInverse.m12 + dY * oInverse.m22 + oInverse.y; + + if (!oResult.IsIdentity()) + Concat(oResult.m11, oResult.m12, oResult.m21, oResult.m22, oResult.x, oResult.y); + } + void CPage::Clip() + { + // Operator : W + // Description: Изменяем текущий clipping path, пересакая его с текущим path, ипользуя правило Nonzero + // Winding Number Rule, для определения какие регионы лежат внутри clipping path. + SetGrMode(grmode_CLIP); + m_pStream->WriteStr("W\012"); + } + void CPage::Eoclip() + { + // Operator : W* + // Description: Изменяем текущий clipping path, пересакая его с текущим path, ипользуя правило Even-Odd + // Rule, для определения какие регионы лежат внутри clipping path. + SetGrMode(grmode_CLIP); + m_pStream->WriteStr("W*\012"); + } + void CPage::SetExtGrState(CExtGrState* pState) + { + if (!pState) + return; + + // Operator : gs + // Description: устанавливаем сразу все настройки данного графического состояния(ExtGState) + + const char* sGsName = GetExtGrStateName(pState); + if (!sGsName) + return; + + m_pStream->WriteEscapeName(sGsName); + m_pStream->WriteStr(" gs\012"); + } + const char* CPage::GetExtGrStateName(CExtGrState* pState) + { + const char *sKey; + + if (!m_pExtGStates) + { + CDictObject* pResources = (CDictObject*)GetResourcesItem(); + if (!pResources) + return NULL; + + m_pExtGStates = new CDictObject(); + if (!m_pExtGStates) + return NULL; + + pResources->Add("ExtGState", m_pExtGStates); + } + + sKey = m_pExtGStates->GetKey(pState); + if (!sKey) + { + // Если ExtGState не зарегистрирован в Resource, регистрируем. + char sExtGrStateName[LIMIT_MAX_NAME_LEN + 1]; + char *pPointer; + char *pEndPointer = sExtGrStateName + LIMIT_MAX_NAME_LEN; + + pPointer = (char*)StrCpy(sExtGrStateName, "E", pEndPointer); + ItoA(pPointer, ++m_unExtGStatesCount, pEndPointer); + m_pExtGStates->Add(sExtGrStateName, pState); + sKey = m_pExtGStates->GetKey(pState); + } + + return sKey; + } + void CPage::AddAnnotation(CDictObject* pAnnot) + { + CArrayObject* pArray = (CArrayObject*)Get("Annots"); + if (!pArray) + { + pArray = new CArrayObject(); + if (!pArray) + return; + + Add("Annots", pArray); + } + + return pArray->Add(pAnnot); + } + void CPage::BeginText() + { + // Operator : BT + // Description: Начало текста + SetGrMode(grmode_TEXT); + m_pStream->WriteStr("BT\012"); + + m_oTextPos.Reset(); + m_oTextMatrix.Reset(); + } + void CPage::EndText() + { + // Operator : ET + // Description: Окончание текста + CheckGrMode(grmode_TEXT); + m_pStream->WriteStr("ET\012"); + SetGrMode(grmode_PAGE); + } + void CPage::MoveTextPos(double dX, double dY) + { + // Operator : Td + // Description: Переходим к началу следующей линии, сдвигаясь от начала текущей на ( fX, fY ). + CheckGrMode(grmode_TEXT); + + m_pStream->WriteReal(dX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" Td\012"); + + m_oTextMatrix.x += dX * m_oTextMatrix.m11 + dY * m_oTextMatrix.m21; + m_oTextMatrix.y += dX * m_oTextMatrix.m12 + dY * m_oTextMatrix.m22; + m_oTextPos.Set(m_oTextMatrix.x, m_oTextMatrix.y); + } + void CPage::ShowText(const BYTE* sText, unsigned int unLen) + { + // Operator : Tj + // Description: Показать текстовую строку. + CheckGrMode(grmode_TEXT); + WriteText(sText, unLen); + m_pStream->WriteStr(" Tj\012"); + } + void CPage::WriteText(const BYTE* sText, unsigned int unLen) + { + EFontType eType = m_pFont->GetFontType(); + if (fontCIDType0 == eType || fontCIDType0C == eType || fontCIDType0COT == eType || fontCIDType2 == eType || fontCIDType2OT == eType) + { + m_pStream->WriteChar('<'); + m_pStream->WriteBinary(sText, unLen, NULL); + m_pStream->WriteChar('>'); + } + else + { + m_pStream->WriteEscapeText(sText, unLen); + } + } + void CPage::DrawText(double dXpos, double dYpos, const BYTE* sText, unsigned int unLen) + { + CheckGrMode(grmode_TEXT); + + double dX = 0.0; + double dY = 0.0; + + if (0 == m_oTextMatrix.m11) + { + dY = (dXpos - m_oTextMatrix.x) / m_oTextMatrix.m21; + dX = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m22 / m_oTextMatrix.m21) / m_oTextMatrix.m12; + } + else + { + dY = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m12 / m_oTextMatrix.m11) / (m_oTextMatrix.m22 - m_oTextMatrix.m21 * m_oTextMatrix.m12 / m_oTextMatrix.m11); + dX = (dXpos - m_oTextMatrix.x - dY * m_oTextMatrix.m21) / m_oTextMatrix.m11; + } + + MoveTextPos(dX, dY); + ShowText(sText, unLen); + } + void CPage::DrawTextLine(const CTextLine* pTextLine) + { + if (!pTextLine) + return; + + int nCount = pTextLine->m_vWords.size(); + if (nCount <= 0) + return; + + CheckGrMode(grmode_TEXT); + + double dXpos = pTextLine->m_dX; + double dYpos = pTextLine->m_dY; + + double dX = 0.0; + double dY = 0.0; + + if (0 == m_oTextMatrix.m11) + { + dY = (dXpos - m_oTextMatrix.x) / m_oTextMatrix.m21; + dX = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m22 / m_oTextMatrix.m21) / m_oTextMatrix.m12; + } + else + { + dY = (dYpos - m_oTextMatrix.y - (dXpos - m_oTextMatrix.x) * m_oTextMatrix.m12 / m_oTextMatrix.m11) / (m_oTextMatrix.m22 - m_oTextMatrix.m21 * m_oTextMatrix.m12 / m_oTextMatrix.m11); + dX = (dXpos - m_oTextMatrix.x - dY * m_oTextMatrix.m21) / m_oTextMatrix.m11; + } + MoveTextPos(dX, dY); + + if (1 == nCount) + { + CTextWord* pWord = pTextLine->m_vWords.at(0); + ShowText(pWord->m_pText, pWord->m_nIndex * 2); + } + else + { + CTextWord* pWord = NULL; + double dShift = 0; + m_pStream->WriteChar('['); + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + pWord = pTextLine->m_vWords.at(nIndex); + WriteText(pWord->m_pText, pWord->m_nIndex * 2); + if (nIndex != nCount - 1) + { + dShift = pTextLine->m_vShifts.at(nIndex); + m_pStream->WriteReal(dShift); + } + } + m_pStream->WriteStr("]TJ\012"); + } + } + void CPage::SetCharSpace(double dValue) + { + // Operator : Tc + // Description: Устанавливаем расстояние между буквами + CheckGrMode(grmode_TEXT); + + dValue = std::min((double)MAX_CHARSPACE, std::max((double)MIN_CHARSPACE, dValue)); + m_pStream->WriteReal(dValue); + m_pStream->WriteStr(" Tc\012"); + } + void CPage::SetHorizontalScalling(double dValue) + { + // Operator : Tz + // Description: Устанавливаем горизонтальное растяжение/сжатие + CheckGrMode(grmode_TEXT); + + dValue = std::min((double)MAX_HORIZONTALSCALING, std::max((double)MIN_HORIZONTALSCALING, dValue)); + m_pStream->WriteReal(dValue); + m_pStream->WriteStr(" Tz\012"); + } + void CPage::SetFontAndSize(CFontDict* pFont, double dSize) + { + // Operator : Tf + // Description: Устанавливаем фонт и размер фонта + + dSize = std::min((double)MAX_FONTSIZE, std::max(0.0, dSize)); + const char* sFontName = GetLocalFontName(pFont); + if (!sFontName) + return; + + m_pStream->WriteEscapeName(sFontName); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dSize); + m_pStream->WriteStr(" Tf\012"); + + m_pFont = pFont; + } + const char* CPage::GetLocalFontName(CFontDict* pFont) + { + if (!m_pFonts) + { + CDictObject* pResources = GetResourcesItem(); + if (!pResources) + return NULL; + + m_pFonts = new CDictObject(); + if (!m_pFonts) + return NULL; + + pResources->Add("Font", m_pFonts); + } + + const char *sKey = m_pFonts->GetKey(pFont); + if (!sKey) + { + // если фонт не зарегистрирован в ресурсах, тогда регистрируем его + char sFontName[LIMIT_MAX_NAME_LEN + 1]; + char *pPointer = NULL; + char *pEndPointer = sFontName + LIMIT_MAX_NAME_LEN; + + ++m_unFontsCount; + while (m_unFontsCount < LIMIT_MAX_DICT_ELEMENT) + { + if (m_pFonts->Get("F" + std::to_string(m_unFontsCount))) + ++m_unFontsCount; + else + break; + } + + pPointer = (char*)StrCpy(sFontName, "F", pEndPointer); + ItoA(pPointer, m_unFontsCount, pEndPointer); + m_pFonts->Add(sFontName, pFont); + sKey = m_pFonts->GetKey(pFont); + } + + return sKey; + } + void CPage::SetTextRenderingMode(ETextRenderingMode eMode) + { + // Operator : Tr + // Description: Устанавливаем тип закрашивания символов (TextRenderingMode) + CheckGrMode(grmode_TEXT); + m_pStream->WriteInt((int)eMode); + m_pStream->WriteStr(" Tr\012"); + } + void CPage::SetTextMatrix(double dM11, double dM12, double dM21, double dM22, double dX, double dY) + { + // Operator : Tm + // Description: Устанавливаем матрицу преобразования для текста. + CheckGrMode(grmode_TEXT); + + m_pStream->WriteReal(dM11); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM12); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM21); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dM22); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dY); + m_pStream->WriteStr(" Tm\012"); + + m_oTextMatrix.m11 = dM11; + m_oTextMatrix.m12 = dM12; + m_oTextMatrix.m21 = dM21; + m_oTextMatrix.m22 = dM22; + m_oTextMatrix.x = dX; + m_oTextMatrix.y = dY; + m_oTextPos.Set(m_oTextMatrix.x, m_oTextMatrix.y); + } + void CPage::ExecuteXObject(CXObject* pXObject) + { + const char* sXObjectName = GetXObjectName(pXObject); + + if (!sXObjectName) + return; + + m_pStream->WriteEscapeName(sXObjectName); + m_pStream->WriteStr(" Do\012"); + } + void CPage::DrawImage(CImageDict* pImage, double dX, double dY, double dWidth, double dHeight) + { + GrSave(); + Concat(dWidth, 0, 0, dHeight, dX, dY); + ExecuteXObject(pImage); + GrRestore(); + } + const char* CPage::GetXObjectName(CXObject* pObject) + { + if (!m_pXObjects) + { + CDictObject* pResources = GetResourcesItem(); + if (!pResources) + return NULL; + + m_pXObjects = new CDictObject(); + if (!m_pXObjects) + return NULL; + + pResources->Add("XObject", m_pXObjects); + } + + const char* sKey = m_pXObjects->GetKey(pObject); + if (!sKey) + { + char sXObjName[LIMIT_MAX_NAME_LEN + 1]; + char *pPointer; + char *pEndPointer = sXObjName + LIMIT_MAX_NAME_LEN; + + pPointer = (char*)StrCpy(sXObjName, "X", pEndPointer); + ItoA(pPointer, ++m_unXObjectsCount, pEndPointer); + m_pXObjects->Add(sXObjName, pObject); + sKey = m_pXObjects->GetKey(pObject); + } + + return sKey; + } + void CPage::DrawShading(CShading* pShading) + { + // Operator : sh + // Description: отрисовываем градиент + + const char* sShadingName = GetLocalShadingName(pShading); + if (!sShadingName) + return; + + m_pStream->WriteEscapeName(sShadingName); + m_pStream->WriteStr(" sh\012"); + } + void CPage::SetStrokeAlpha(unsigned char unAlpha) + { + CExtGrState* pExtGrState = m_pDocument->GetStrokeAlpha((double)(unAlpha / 255.0)); + if (pExtGrState) + SetExtGrState(pExtGrState); + } + void CPage::SetFillAlpha(unsigned char unAlpha) + { + CExtGrState* pExtGrState = m_pDocument->GetFillAlpha((double)(unAlpha / 255.0)); + if (pExtGrState) + SetExtGrState(pExtGrState); + } + const char* CPage::GetLocalShadingName(CShading* pShading) + { + if (!m_pShadings) + { + CDictObject* pResources = GetResourcesItem(); + if (!pResources) + return NULL; + + m_pShadings = new CDictObject(); + if (!m_pShadings) + return NULL; + + pResources->Add("Shading", m_pShadings); + } + + const char* sKey = m_pShadings->GetKey(pShading); + if (!sKey) + { + char sShadingName[LIMIT_MAX_NAME_LEN + 1]; + char *pPointer; + char *pEndPointer = sShadingName + LIMIT_MAX_NAME_LEN; + + pPointer = (char*)StrCpy(sShadingName, "S", pEndPointer); + ItoA(pPointer, ++m_unShadingsCount, pEndPointer); + m_pShadings->Add(sShadingName, pShading); + sKey = m_pShadings->GetKey(pShading); + } + + return sKey; + } + const char* CPage::GetLocalPatternName(CImageTilePattern* pPattern) + { + if (!m_pPatterns) + { + CDictObject* pResources = GetResourcesItem(); + if (!pResources) + return NULL; + + m_pPatterns = new CDictObject(); + if (!m_pPatterns) + return NULL; + + pResources->Add("Pattern", m_pPatterns); + } + + const char* sKey = m_pPatterns->GetKey(pPattern); + if (!sKey) + { + char sPatternName[LIMIT_MAX_NAME_LEN + 1]; + char *pPointer; + char *pEndPointer = sPatternName + LIMIT_MAX_NAME_LEN; + + pPointer = (char*)StrCpy(sPatternName, "P", pEndPointer); + ItoA(pPointer, m_unPatternsCount + 1, pEndPointer); + m_unPatternsCount++; + m_pPatterns->Add(sPatternName, pPattern); + sKey = m_pPatterns->GetKey(pPattern); + } + + return sKey; + } + void CPage::SetPatternColorSpace(CImageTilePattern* pPattern) + { + // Operator : csn + // Description: задаем паттерн для рисования + + const char* sPatternName = GetLocalPatternName(pPattern); + if (!sPatternName) + return; + + m_pStream->WriteStr("/Pattern cs\012"); + m_pStream->WriteEscapeName(sPatternName); + m_pStream->WriteStr(" scn\012"); + } + void CPage::SetFilter(unsigned int unFiler) + { + if (m_pContents) + { + for (unsigned int unKidIndex = 0, unKidsCount = m_pContents->GetCount(); unKidIndex < unKidsCount; ++unKidIndex) + { + CObjectBase* pKid = m_pContents->Get(unKidIndex); + if (pKid->GetType() == object_type_DICT) + ((CDictObject*)pKid)->SetFilter(unFiler); + } + } + } + CMatrix* CPage::GetTransform() + { + return &m_pGrState->m_oMatrix; + } + void CPage::AddGroup(CDictObject* pDict) + { + Add("Group", pDict); + } + void CPage::AddContents(CXref* pXref) + { + CDictObject* pContent = new CDictObject(pXref); + m_pContents->Add(pContent); + m_pStream = pContent->GetStream(); + } + void CPage::SetRotate(int nRotate) + { + // The value shall be a multiple of 90 + if (nRotate > 0 && nRotate % 90 == 0) + { + CNumberObject* pRotate = (CNumberObject*)GetRotateItem(); + if (pRotate) + Add("Rotate", (nRotate + pRotate->Get()) % 360); + else + Add("Rotate", nRotate % 360); + } + } + //---------------------------------------------------------------------------------------- + // CTextWord + //---------------------------------------------------------------------------------------- + CTextWord::CTextWord() + { + m_nIndex = 0; + m_pText = (unsigned char*)malloc(STR_BUF); + m_nSize = STR_BUF; + } + CTextWord::~CTextWord() + { + if (m_pText) + free(m_pText); + } + void CTextWord::CheckBuffer() + { + if (2 * m_nIndex >= m_nSize) + { + m_nSize += STR_BUF; + m_pText = (unsigned char*)realloc(m_pText, m_nSize); + } + } + bool CTextWord::Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth) + { + if (2 != unLen) + return false; + + CheckBuffer(); + + if (0 == m_nIndex) + { + m_pText[0] = pCodes[0]; + m_pText[1] = pCodes[1]; + m_nIndex++; + m_dStartX = dX; + m_dStartY = dY; + + m_dCurX = dX + dWidth; + } + else + { + if (fabs(dY - m_dStartY) > 0.001 || fabs(dX - m_dCurX) > 0.01) + return false; + + m_pText[m_nIndex * 2 + 0] = pCodes[0]; + m_pText[m_nIndex * 2 + 1] = pCodes[1]; + m_nIndex++; + + m_dCurX = dX + dWidth; + } + + return true; + } + //---------------------------------------------------------------------------------------- + // CTextLine + //---------------------------------------------------------------------------------------- + CTextLine::CTextLine() + { + } + CTextLine::~CTextLine() + { + Clear(); + } + bool CTextLine::Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth, double dSize) + { + if (2 != unLen) + return false; + + if (0 == m_vWords.size()) + { + CTextWord* pText = new CTextWord(); + if (!pText || !pText->Add(pCodes, unLen, dX, dY, dWidth)) + return false; + + m_vWords.push_back(pText); + m_dX = dX; + m_dY = dY; + return true; + } + + if (fabs(dY - m_dY) > 0.001) + return false; + + CTextWord* pLastText = m_vWords.at(m_vWords.size() - 1); + if (pLastText->Add(pCodes, unLen, dX, dY, dWidth)) + return true; + + CTextWord* pText = new CTextWord(); + if (!pText || !pText->Add(pCodes, unLen, dX, dY, dWidth)) + return false; + + m_vWords.push_back(pText); + double dShift = (pLastText->m_dCurX - dX) * 1000 / dSize; + m_vShifts.push_back(dShift); + return true; + } + void CTextLine::Flush(CPage* pPage) + { + pPage->DrawTextLine(this); + Clear(); + } + void CTextLine::Clear() + { + for (int nIndex = 0, nCount = m_vWords.size(); nIndex < nCount; nIndex++) + { + CTextWord* pText = m_vWords.at(nIndex); + RELEASEOBJECT(pText); + } + m_vWords.clear(); + m_vShifts.clear(); + } +} diff --git a/PdfWriter/Src/Pages.h b/PdfFile/SrcWriter/Pages.h similarity index 97% rename from PdfWriter/Src/Pages.h rename to PdfFile/SrcWriter/Pages.h index b96e0b1ec5..a550fd996f 100644 --- a/PdfWriter/Src/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -1,266 +1,266 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_PAGES_H -#define _PDF_WRITER_SRC_PAGES_H - -#include "Objects.h" -#include - -#ifdef DrawText -#undef DrawText -#endif - -namespace PdfWriter -{ - class CXref; - class CGrState; - class CExtGrState; - class CAnnotation; - class CFontDict; - class CXObject; - class CImageDict; - class CShading; - class CImageTilePattern; - class CDocument; - class CTextLine; - class CTextWord; - class CFieldBase; - class CPage; - //---------------------------------------------------------------------------------------- - // CPageTree - //---------------------------------------------------------------------------------------- - class CPageTree : public CDictObject - { - public: - CPageTree(CXref* pXref); - CPageTree(CXref* pXref, bool bEmpty); - void Fix(); - void AddPage(CDictObject* pPage); - CObjectBase* GetObj(int nPageIndex); - CPage* GetPage(int nPageIndex); - CObjectBase* RemovePage(int nPageIndex); - bool InsertPage(int nPageIndex, CPage* pPage); - bool Join(CPageTree* pPageTree); - unsigned int GetCount() - { - return m_pCount ? m_pCount->Get() : 0; - } - EDictType GetDictType() const - { - return dict_type_PAGES; - } - private: - CObjectBase* GetFromPageTree(int nPageIndex, int& nI, bool bRemove = false, bool bInsert = false, CPage* pPage = NULL); - - CNumberObject* m_pCount; - CArrayObject* m_pPages; - CXref* m_pXref; - }; - //---------------------------------------------------------------------------------------- - // CPage - //---------------------------------------------------------------------------------------- - class CPage : public CDictObject - { - public: - CPage(CXref* pXref, CDocument* pDocument); - CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument); - ~CPage(); - - void Fix(); - void SetHeight(double dHeight); - void SetWidth(double dWidth); - double GetWidth(); - double GetHeight(); - - EDictType GetDictType() const - { - return dict_type_PAGE; - } - void BeforeWrite(); - - void MoveTo(double dX, double dY); - void LineTo(double dX, double dY); - void CurveTo(double dX1, double dY1, double dX2, double dY2, double dXe, double dYe); - void Ellipse(double dX, double dY, double dXRay, double dYRay); - void EllipseArcTo(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection = false); - void ClosePath(); - void Stroke(); - void Fill(); - void EoFill(); - void FillStroke(); - void EoFillStroke(); - void EndPath(); - void Clip(); - void Eoclip(); - void SetLineWidth(double dLineWidth); - void SetLineCap(ELineCapStyle eLineCap); - void SetLineJoin(ELineJoinStyle eLineJoin); - void SetMiterLimit(double dMiterLimit); - void SetDash(const double* pPattern, unsigned int unCount, double dPhase); - void SetFlat(double dFlatness); - void GrSave(); - void GrRestore(); - void SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB); - void SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB); - void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY); - void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); - void SetExtGrState(CExtGrState* pExtGrState); - void AddAnnotation(CDictObject* pAnnot); - void DrawShading(CShading* pShading); - void SetStrokeAlpha(unsigned char unAlpha); - void SetFillAlpha(unsigned char unAlpha); - - void BeginText(); - void EndText(); - void MoveTextPos(double dX, double dY); - void ShowText(const BYTE* sText, unsigned int unLen); - void DrawText(double dX, double dY, const BYTE* sText, unsigned int unLen); - void SetCharSpace(double dValue); - void SetHorizontalScalling(double dValue); - void SetFontAndSize(CFontDict* pFont, double dSize); - void SetTextRenderingMode(ETextRenderingMode eMode); - void SetTextMatrix(double dM11, double dM12, double dM21, double dM22, double dX, double dY); - void DrawTextLine(const CTextLine* pTextLine); - - void ExecuteXObject(CXObject* pXObject); - void DrawImage(CImageDict* pImage, double dX, double dY, double dWidth, double dHeight); - void SetPatternColorSpace(CImageTilePattern* pPattern); - void SetFilter(unsigned int unFiler); - CMatrix* GetTransform(); - void AddGroup(CDictObject* pDict); - - void AddContents(CXref* pXref); - void SetRotate(int nRotate); - - private: - - void Init(CXref* pXref, CDocument* pDocument); - void EllipseArc(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection); - CArrayObject* GetMediaBoxItem(); - CDictObject* GetResourcesItem(); - CObjectBase* GetCropBoxItem(); - CObjectBase* GetRotateItem(); - TBox GetMediaBox(); - void SetMediaBoxValue(unsigned int unIndex, double dValue); - void AddResource(); - void SetGrMode(EGrMode eMode); - void CheckGrMode(EGrMode eMode); - void WriteText(const BYTE* sText, unsigned int unLen); - const char* GetExtGrStateName(CExtGrState* pState); - const char* GetLocalFontName(CFontDict* pFont); - const char* GetXObjectName(CXObject* pObject); - const char* GetLocalShadingName(CShading* pShading); - const char* GetLocalPatternName(CImageTilePattern* pPattern); - - private: - - CDocument* m_pDocument; - CPageTree* m_pParent; - CXref* m_pXref; - CPoint m_oStartPos; // Позиция начала текущего пата - CPoint m_oCurPos; // Текущая позиция пата - CPoint m_oTextPos; // Текущая позиция текста - CMatrix m_oTextMatrix; - CArrayObject* m_pContents; - CStream* m_pStream; - unsigned int m_unCompressionMode; - CDictObject* m_pExtGStates; - unsigned int m_unExtGStatesCount; - EGrMode m_eGrMode; - CGrState* m_pGrState; - CDictObject* m_pFonts; - unsigned int m_unFontsCount; - CFontDict* m_pFont; // Текущий шрифт - CDictObject* m_pXObjects; - unsigned int m_unXObjectsCount; - CDictObject* m_pShadings; - unsigned int m_unShadingsCount; - CDictObject* m_pPatterns; - unsigned int m_unPatternsCount; - }; - //---------------------------------------------------------------------------------------- - // CTextWord - //---------------------------------------------------------------------------------------- - class CTextWord - { - public: - - CTextWord(); - ~CTextWord(); - bool Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth); - - private: - - void CheckBuffer(); - - private: - - unsigned char*m_pText; - int m_nSize; - int m_nIndex; - double m_dStartX; - double m_dStartY; - - double m_dCurX; - - friend class CTextLine; - friend class CPage; - }; - //---------------------------------------------------------------------------------------- - // CTextLine - //---------------------------------------------------------------------------------------- - class CTextLine - { - public: - - CTextLine(); - ~CTextLine(); - bool Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth, double dFontSize); - void Flush(CPage* pPage); - - private: - - void Clear(); - - private: - - std::vector m_vWords; - std::vector m_vShifts; - double m_dX; - double m_dY; - - friend class CPage; - }; -} - -#endif // _PDF_WRITER_SRC_PAGES_H - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_PAGES_H +#define _PDF_WRITER_SRC_PAGES_H + +#include "Objects.h" +#include + +#ifdef DrawText +#undef DrawText +#endif + +namespace PdfWriter +{ + class CXref; + class CGrState; + class CExtGrState; + class CAnnotation; + class CFontDict; + class CXObject; + class CImageDict; + class CShading; + class CImageTilePattern; + class CDocument; + class CTextLine; + class CTextWord; + class CFieldBase; + class CPage; + //---------------------------------------------------------------------------------------- + // CPageTree + //---------------------------------------------------------------------------------------- + class CPageTree : public CDictObject + { + public: + CPageTree(CXref* pXref); + CPageTree(CXref* pXref, bool bEmpty); + void Fix(); + void AddPage(CDictObject* pPage); + CObjectBase* GetObj(int nPageIndex); + CPage* GetPage(int nPageIndex); + CObjectBase* RemovePage(int nPageIndex); + bool InsertPage(int nPageIndex, CPage* pPage); + bool Join(CPageTree* pPageTree); + unsigned int GetCount() + { + return m_pCount ? m_pCount->Get() : 0; + } + EDictType GetDictType() const + { + return dict_type_PAGES; + } + private: + CObjectBase* GetFromPageTree(int nPageIndex, int& nI, bool bRemove = false, bool bInsert = false, CPage* pPage = NULL); + + CNumberObject* m_pCount; + CArrayObject* m_pPages; + CXref* m_pXref; + }; + //---------------------------------------------------------------------------------------- + // CPage + //---------------------------------------------------------------------------------------- + class CPage : public CDictObject + { + public: + CPage(CXref* pXref, CDocument* pDocument); + CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument); + ~CPage(); + + void Fix(); + void SetHeight(double dHeight); + void SetWidth(double dWidth); + double GetWidth(); + double GetHeight(); + + EDictType GetDictType() const + { + return dict_type_PAGE; + } + void BeforeWrite(); + + void MoveTo(double dX, double dY); + void LineTo(double dX, double dY); + void CurveTo(double dX1, double dY1, double dX2, double dY2, double dXe, double dYe); + void Ellipse(double dX, double dY, double dXRay, double dYRay); + void EllipseArcTo(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection = false); + void ClosePath(); + void Stroke(); + void Fill(); + void EoFill(); + void FillStroke(); + void EoFillStroke(); + void EndPath(); + void Clip(); + void Eoclip(); + void SetLineWidth(double dLineWidth); + void SetLineCap(ELineCapStyle eLineCap); + void SetLineJoin(ELineJoinStyle eLineJoin); + void SetMiterLimit(double dMiterLimit); + void SetDash(const double* pPattern, unsigned int unCount, double dPhase); + void SetFlat(double dFlatness); + void GrSave(); + void GrRestore(); + void SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB); + void SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB); + void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void SetExtGrState(CExtGrState* pExtGrState); + void AddAnnotation(CDictObject* pAnnot); + void DrawShading(CShading* pShading); + void SetStrokeAlpha(unsigned char unAlpha); + void SetFillAlpha(unsigned char unAlpha); + + void BeginText(); + void EndText(); + void MoveTextPos(double dX, double dY); + void ShowText(const BYTE* sText, unsigned int unLen); + void DrawText(double dX, double dY, const BYTE* sText, unsigned int unLen); + void SetCharSpace(double dValue); + void SetHorizontalScalling(double dValue); + void SetFontAndSize(CFontDict* pFont, double dSize); + void SetTextRenderingMode(ETextRenderingMode eMode); + void SetTextMatrix(double dM11, double dM12, double dM21, double dM22, double dX, double dY); + void DrawTextLine(const CTextLine* pTextLine); + + void ExecuteXObject(CXObject* pXObject); + void DrawImage(CImageDict* pImage, double dX, double dY, double dWidth, double dHeight); + void SetPatternColorSpace(CImageTilePattern* pPattern); + void SetFilter(unsigned int unFiler); + CMatrix* GetTransform(); + void AddGroup(CDictObject* pDict); + + void AddContents(CXref* pXref); + void SetRotate(int nRotate); + + private: + + void Init(CXref* pXref, CDocument* pDocument); + void EllipseArc(double dX, double dY, double dXRad, double dYRad, double dAngle1, double dAngle2, bool bClockDirection); + CArrayObject* GetMediaBoxItem(); + CDictObject* GetResourcesItem(); + CObjectBase* GetCropBoxItem(); + CObjectBase* GetRotateItem(); + TBox GetMediaBox(); + void SetMediaBoxValue(unsigned int unIndex, double dValue); + void AddResource(); + void SetGrMode(EGrMode eMode); + void CheckGrMode(EGrMode eMode); + void WriteText(const BYTE* sText, unsigned int unLen); + const char* GetExtGrStateName(CExtGrState* pState); + const char* GetLocalFontName(CFontDict* pFont); + const char* GetXObjectName(CXObject* pObject); + const char* GetLocalShadingName(CShading* pShading); + const char* GetLocalPatternName(CImageTilePattern* pPattern); + + private: + + CDocument* m_pDocument; + CPageTree* m_pParent; + CXref* m_pXref; + CPoint m_oStartPos; // Позиция начала текущего пата + CPoint m_oCurPos; // Текущая позиция пата + CPoint m_oTextPos; // Текущая позиция текста + CMatrix m_oTextMatrix; + CArrayObject* m_pContents; + CStream* m_pStream; + unsigned int m_unCompressionMode; + CDictObject* m_pExtGStates; + unsigned int m_unExtGStatesCount; + EGrMode m_eGrMode; + CGrState* m_pGrState; + CDictObject* m_pFonts; + unsigned int m_unFontsCount; + CFontDict* m_pFont; // Текущий шрифт + CDictObject* m_pXObjects; + unsigned int m_unXObjectsCount; + CDictObject* m_pShadings; + unsigned int m_unShadingsCount; + CDictObject* m_pPatterns; + unsigned int m_unPatternsCount; + }; + //---------------------------------------------------------------------------------------- + // CTextWord + //---------------------------------------------------------------------------------------- + class CTextWord + { + public: + + CTextWord(); + ~CTextWord(); + bool Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth); + + private: + + void CheckBuffer(); + + private: + + unsigned char*m_pText; + int m_nSize; + int m_nIndex; + double m_dStartX; + double m_dStartY; + + double m_dCurX; + + friend class CTextLine; + friend class CPage; + }; + //---------------------------------------------------------------------------------------- + // CTextLine + //---------------------------------------------------------------------------------------- + class CTextLine + { + public: + + CTextLine(); + ~CTextLine(); + bool Add(unsigned char* pCodes, unsigned int unLen, double dX, double dY, double dWidth, double dFontSize); + void Flush(CPage* pPage); + + private: + + void Clear(); + + private: + + std::vector m_vWords; + std::vector m_vShifts; + double m_dX; + double m_dY; + + friend class CPage; + }; +} + +#endif // _PDF_WRITER_SRC_PAGES_H + diff --git a/PdfWriter/Src/Pattern.cpp b/PdfFile/SrcWriter/Pattern.cpp similarity index 97% rename from PdfWriter/Src/Pattern.cpp rename to PdfFile/SrcWriter/Pattern.cpp index c7eb106f2a..b5000125c4 100644 --- a/PdfWriter/Src/Pattern.cpp +++ b/PdfFile/SrcWriter/Pattern.cpp @@ -1,190 +1,190 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Pattern.h" -#include "Image.h" -#include "Streams.h" - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CPattern - //---------------------------------------------------------------------------------------- - CPattern::CPattern(CXref* pXref) : CDictObject(pXref) - { - } - //---------------------------------------------------------------------------------------- - // CImageTilePattern - //---------------------------------------------------------------------------------------- - CImageTilePattern::CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType, double dXStepSpacing, double dYStepSpacing) : CPattern(pXref) - { - Add("Type", "Pattern"); - Add("PatternType", 1); - Add("PaintType", 1); // Uncolored - Add("TilingType", 1); // No distortion - - if (pMatrix) - { - CArrayObject* pMatrixArray = new CArrayObject(); - if (!pMatrixArray) - return; - - pMatrixArray->Add(pMatrix->m11); - pMatrixArray->Add(pMatrix->m12); - pMatrixArray->Add(pMatrix->m21); - pMatrixArray->Add(pMatrix->m22); - pMatrixArray->Add(pMatrix->x); - pMatrixArray->Add(pMatrix->y); - Add("Matrix", pMatrixArray); - } - - CDictObject* pResources = new CDictObject(); - if (!pResources) - return; - - Add("Resources", pResources); - CDictObject* pXObject = new CDictObject(); - if (!pXObject) - return; - - pResources->Add("XObject", pXObject); - pXObject->Add("X1", pImageDict); - - CStream* pStream = GetStream(); - if (!pStream) - return; - - if (imagetilepatterntype_Default == eType) - { - if (dXStepSpacing > 0.01 && dYStepSpacing > 0.01) - Add("BBox", CArrayObject::CreateBox(-dXStepSpacing / 2, -dYStepSpacing / 2, dW + dXStepSpacing / 2, dH + dYStepSpacing / 2)); - else - Add("BBox", CArrayObject::CreateBox(0, 0, dW, dH)); - - Add("XStep", dW + dXStepSpacing); - Add("YStep", dH + dYStepSpacing); - - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" 0 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - } - else if (imagetilepatterntype_InverseX == eType) - { - Add("BBox", CArrayObject::CreateBox(0, 0, 2 * dW, dH)); - Add("XStep", 2 * dW + dXStepSpacing); - Add("YStep", dH + dYStepSpacing); - - pStream->WriteStr("q\12"); - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" 0 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - pStream->WriteStr("Q\12"); - - pStream->WriteReal(-dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" "); - pStream->WriteReal(2 * dW); - pStream->WriteStr(" 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - } - else if (imagetilepatterntype_InverseY == eType) - { - Add("BBox", CArrayObject::CreateBox(0, 0, dW, 2 * dH)); - Add("XStep", dW + dXStepSpacing); - Add("YStep", 2 * dH + dYStepSpacing); - - pStream->WriteStr("q\12"); - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" 0 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - pStream->WriteStr("Q\12"); - - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(-dH); - pStream->WriteStr(" 0 "); - pStream->WriteReal(2 * dH); - pStream->WriteStr(" cm\12"); - pStream->WriteStr("/X1 Do\12"); - } - else if (imagetilepatterntype_InverseXY == eType) - { - Add("BBox", CArrayObject::CreateBox(0, 0, 2 * dW, 2 * dH)); - Add("XStep", 2 * dW + dXStepSpacing); - Add("YStep", 2 * dH + dYStepSpacing); - - pStream->WriteStr("q\12"); - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" 0 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - pStream->WriteStr("Q\12"); - - pStream->WriteStr("q\12"); - pStream->WriteReal(dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(-dH); - pStream->WriteStr(" 0 "); - pStream->WriteReal(2 * dH); - pStream->WriteStr(" cm\12"); - pStream->WriteStr("/X1 Do\12"); - pStream->WriteStr("Q\12"); - - pStream->WriteStr("q\12"); - pStream->WriteReal(-dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(dH); - pStream->WriteStr(" "); - pStream->WriteReal(2 * dW); - pStream->WriteStr(" 0 cm\12"); - pStream->WriteStr("/X1 Do\12"); - pStream->WriteStr("Q\12"); - - pStream->WriteReal(-dW); - pStream->WriteStr(" 0 0 "); - pStream->WriteReal(-dH); - pStream->WriteStr(" "); - pStream->WriteReal(2 * dW); - pStream->WriteStr(" "); - pStream->WriteReal(2 * dH); - pStream->WriteStr(" cm\12"); - pStream->WriteStr("/X1 Do\12"); - } - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Pattern.h" +#include "Image.h" +#include "Streams.h" + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CPattern + //---------------------------------------------------------------------------------------- + CPattern::CPattern(CXref* pXref) : CDictObject(pXref) + { + } + //---------------------------------------------------------------------------------------- + // CImageTilePattern + //---------------------------------------------------------------------------------------- + CImageTilePattern::CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType, double dXStepSpacing, double dYStepSpacing) : CPattern(pXref) + { + Add("Type", "Pattern"); + Add("PatternType", 1); + Add("PaintType", 1); // Uncolored + Add("TilingType", 1); // No distortion + + if (pMatrix) + { + CArrayObject* pMatrixArray = new CArrayObject(); + if (!pMatrixArray) + return; + + pMatrixArray->Add(pMatrix->m11); + pMatrixArray->Add(pMatrix->m12); + pMatrixArray->Add(pMatrix->m21); + pMatrixArray->Add(pMatrix->m22); + pMatrixArray->Add(pMatrix->x); + pMatrixArray->Add(pMatrix->y); + Add("Matrix", pMatrixArray); + } + + CDictObject* pResources = new CDictObject(); + if (!pResources) + return; + + Add("Resources", pResources); + CDictObject* pXObject = new CDictObject(); + if (!pXObject) + return; + + pResources->Add("XObject", pXObject); + pXObject->Add("X1", pImageDict); + + CStream* pStream = GetStream(); + if (!pStream) + return; + + if (imagetilepatterntype_Default == eType) + { + if (dXStepSpacing > 0.01 && dYStepSpacing > 0.01) + Add("BBox", CArrayObject::CreateBox(-dXStepSpacing / 2, -dYStepSpacing / 2, dW + dXStepSpacing / 2, dH + dYStepSpacing / 2)); + else + Add("BBox", CArrayObject::CreateBox(0, 0, dW, dH)); + + Add("XStep", dW + dXStepSpacing); + Add("YStep", dH + dYStepSpacing); + + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" 0 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + } + else if (imagetilepatterntype_InverseX == eType) + { + Add("BBox", CArrayObject::CreateBox(0, 0, 2 * dW, dH)); + Add("XStep", 2 * dW + dXStepSpacing); + Add("YStep", dH + dYStepSpacing); + + pStream->WriteStr("q\12"); + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" 0 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + pStream->WriteStr("Q\12"); + + pStream->WriteReal(-dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" "); + pStream->WriteReal(2 * dW); + pStream->WriteStr(" 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + } + else if (imagetilepatterntype_InverseY == eType) + { + Add("BBox", CArrayObject::CreateBox(0, 0, dW, 2 * dH)); + Add("XStep", dW + dXStepSpacing); + Add("YStep", 2 * dH + dYStepSpacing); + + pStream->WriteStr("q\12"); + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" 0 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + pStream->WriteStr("Q\12"); + + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(-dH); + pStream->WriteStr(" 0 "); + pStream->WriteReal(2 * dH); + pStream->WriteStr(" cm\12"); + pStream->WriteStr("/X1 Do\12"); + } + else if (imagetilepatterntype_InverseXY == eType) + { + Add("BBox", CArrayObject::CreateBox(0, 0, 2 * dW, 2 * dH)); + Add("XStep", 2 * dW + dXStepSpacing); + Add("YStep", 2 * dH + dYStepSpacing); + + pStream->WriteStr("q\12"); + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" 0 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + pStream->WriteStr("Q\12"); + + pStream->WriteStr("q\12"); + pStream->WriteReal(dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(-dH); + pStream->WriteStr(" 0 "); + pStream->WriteReal(2 * dH); + pStream->WriteStr(" cm\12"); + pStream->WriteStr("/X1 Do\12"); + pStream->WriteStr("Q\12"); + + pStream->WriteStr("q\12"); + pStream->WriteReal(-dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(dH); + pStream->WriteStr(" "); + pStream->WriteReal(2 * dW); + pStream->WriteStr(" 0 cm\12"); + pStream->WriteStr("/X1 Do\12"); + pStream->WriteStr("Q\12"); + + pStream->WriteReal(-dW); + pStream->WriteStr(" 0 0 "); + pStream->WriteReal(-dH); + pStream->WriteStr(" "); + pStream->WriteReal(2 * dW); + pStream->WriteStr(" "); + pStream->WriteReal(2 * dH); + pStream->WriteStr(" cm\12"); + pStream->WriteStr("/X1 Do\12"); + } + } +} diff --git a/PdfWriter/Src/Pattern.h b/PdfFile/SrcWriter/Pattern.h similarity index 97% rename from PdfWriter/Src/Pattern.h rename to PdfFile/SrcWriter/Pattern.h index ea47341419..9c7abb41e2 100644 --- a/PdfWriter/Src/Pattern.h +++ b/PdfFile/SrcWriter/Pattern.h @@ -1,58 +1,58 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_PATTERN_H -#define _PDF_WRITER_SRC_PATTERN_H - -#include "Objects.h" - -namespace PdfWriter -{ - class CImageDict; - //---------------------------------------------------------------------------------------- - // CPattern - //---------------------------------------------------------------------------------------- - class CPattern : public CDictObject - { - public: - CPattern(CXref* pXref); - }; - //---------------------------------------------------------------------------------------- - // CImageTilePattern - //---------------------------------------------------------------------------------------- - class CImageTilePattern : public CPattern - { - public: - CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default, double dXStepSpacing = 0, double dYStepSpacing = 0); - }; -} - -#endif // _PDF_WRITER_SRC_PATTERN_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_PATTERN_H +#define _PDF_WRITER_SRC_PATTERN_H + +#include "Objects.h" + +namespace PdfWriter +{ + class CImageDict; + //---------------------------------------------------------------------------------------- + // CPattern + //---------------------------------------------------------------------------------------- + class CPattern : public CDictObject + { + public: + CPattern(CXref* pXref); + }; + //---------------------------------------------------------------------------------------- + // CImageTilePattern + //---------------------------------------------------------------------------------------- + class CImageTilePattern : public CPattern + { + public: + CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default, double dXStepSpacing = 0, double dYStepSpacing = 0); + }; +} + +#endif // _PDF_WRITER_SRC_PATTERN_H diff --git a/PdfWriter/Src/ResourcesDictionary.cpp b/PdfFile/SrcWriter/ResourcesDictionary.cpp similarity index 100% rename from PdfWriter/Src/ResourcesDictionary.cpp rename to PdfFile/SrcWriter/ResourcesDictionary.cpp diff --git a/PdfWriter/Src/ResourcesDictionary.h b/PdfFile/SrcWriter/ResourcesDictionary.h similarity index 100% rename from PdfWriter/Src/ResourcesDictionary.h rename to PdfFile/SrcWriter/ResourcesDictionary.h diff --git a/PdfWriter/Src/Shading.cpp b/PdfFile/SrcWriter/Shading.cpp similarity index 96% rename from PdfWriter/Src/Shading.cpp rename to PdfFile/SrcWriter/Shading.cpp index 57851aac1c..7f4a5bfd40 100644 --- a/PdfWriter/Src/Shading.cpp +++ b/PdfFile/SrcWriter/Shading.cpp @@ -1,402 +1,402 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Shading.h" - -namespace PdfWriter -{ - //---------------------------------------------------------------------------------------- - // CLinearFuntion - //---------------------------------------------------------------------------------------- - class CLinearFuntion : public CDictObject - { - public: - CLinearFuntion(CXref* pXref, double* pC0Values, double* pC1Values, int nCount) - { - if (!nCount || !pC0Values || !pC1Values) - return; - - pXref->Add(this); - - Add("FunctionType", 2); - - CArrayObject* pDomain = new CArrayObject(); - if (!pDomain) - return; - - pDomain->Add(0.0); - pDomain->Add(1.0); - - Add("Domain", pDomain); - - CArrayObject* pC0Array = new CArrayObject(); - if (!pC0Array) - return; - - Add("C0", pC0Array); - - CArrayObject* pC1Array = new CArrayObject(); - if (!pC1Array) - return; - - Add("C1", pC1Array); - - Add("N", 1); - - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - pC0Array->Add(pC0Values[nIndex]); - pC1Array->Add(pC1Values[nIndex]); - } - - } - }; - //---------------------------------------------------------------------------------------- - // CLineSegmentFuntion - //---------------------------------------------------------------------------------------- - class CLineSegmentFuntion : public CDictObject - { - public: - CLineSegmentFuntion(CXref* pXref, double** ppValues, double* pPoints, int nFunctionsCount, int nOutputDimension) - { - pXref->Add(this); - - Add("FunctionType", 3); - - CArrayObject* pDomain = new CArrayObject(); - if (!pDomain) - return; - pDomain->Add(0.0); - pDomain->Add(1.0); - Add("Domain", pDomain); - - CArrayObject* pFunctions = new CArrayObject(); - if (!pFunctions) - return; - - Add("Functions", pFunctions); - - CArrayObject* pBounds = new CArrayObject(); - if (!pBounds) - return; - - Add("Bounds", pBounds); - - CArrayObject* pEncode = new CArrayObject(); - if (!pEncode) - return; - - Add("Encode", pEncode); - - for (int nFunctionIndex = 0; nFunctionIndex < nFunctionsCount; nFunctionIndex++) - { - CLinearFuntion* pFunc = new CLinearFuntion(pXref, ppValues[2 * nFunctionIndex], ppValues[2 * nFunctionIndex + 1], nOutputDimension); - pFunctions->Add(pFunc); - pEncode->Add(0.0); - pEncode->Add(1.0); - - if (nFunctionIndex != nFunctionsCount - 1) - pBounds->Add(pPoints[nFunctionIndex]); - } - } - }; - //---------------------------------------------------------------------------------------- - // CShading - //---------------------------------------------------------------------------------------- - CShading::CShading(CXref* pXref) - { - m_pXref = pXref; - pXref->Add(this); - - m_bRgb = true; - m_pColors = NULL; - m_pColorsPoints = NULL; - m_nColorsCount = 0; - m_bBeginExtend = false; - m_bEndExtend = false; - } - CShading::~CShading() - { - if (m_pColors) - delete[] m_pColors; - - if (m_pColorsPoints) - delete[] m_pColorsPoints; - } - void CShading::SetRgbColors(unsigned char* pColors, double* pPoints, int nCount) - { - if (!pColors || !pPoints || nCount <= 1) - return; - - m_bRgb = true; - m_pColors = new unsigned char[3 * nCount]; - m_pColorsPoints = new double[nCount]; - m_nColorsCount = nCount; - - if (!m_pColors || !m_pColorsPoints) - return; - - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - m_pColors[3 * nIndex + 0] = pColors[3 * nIndex + 0]; - m_pColors[3 * nIndex + 1] = pColors[3 * nIndex + 1]; - m_pColors[3 * nIndex + 2] = pColors[3 * nIndex + 2]; - m_pColorsPoints[nIndex] = pPoints[nIndex]; - } - - Add("ColorSpace", "DeviceRGB"); - - CArrayObject* pDomain = new CArrayObject(); - if (!pDomain) - return; - - pDomain->Add(0.0); - pDomain->Add(1.0); - Add("Domain", pDomain); - - if (nCount <= 2) - { - double pC0Values[] ={ - pColors[0] / 255.0, - pColors[1] / 255.0, - pColors[2] / 255.0 - }; - - double pC1Values[] ={ - pColors[3] / 255.0, - pColors[4] / 255.0, - pColors[5] / 255.0 - }; - - CLinearFuntion* pFunction = new CLinearFuntion(m_pXref, pC0Values, pC1Values, 3); - Add("Function", pFunction); - } - else - { - double** ppValues = new double*[(nCount - 1) * 2]; - for (int nIndex = 0; nIndex < nCount - 1; nIndex++) - { - ppValues[2 * nIndex + 0] = new double[3]; - ppValues[2 * nIndex + 1] = new double[3]; - - ppValues[2 * nIndex + 0][0] = pColors[3 * nIndex + 0] / 255.0; - ppValues[2 * nIndex + 0][1] = pColors[3 * nIndex + 1] / 255.0; - ppValues[2 * nIndex + 0][2] = pColors[3 * nIndex + 2] / 255.0; - ppValues[2 * nIndex + 1][0] = pColors[3 * (nIndex + 1) + 0] / 255.0; - ppValues[2 * nIndex + 1][1] = pColors[3 * (nIndex + 1) + 1] / 255.0; - ppValues[2 * nIndex + 1][2] = pColors[3 * (nIndex + 1) + 2] / 255.0; - } - - CLineSegmentFuntion* pFunction = new CLineSegmentFuntion(m_pXref, ppValues, pPoints + 1, nCount - 1, 3); - Add("Function", pFunction); - - for (int nIndex = 0; nIndex < nCount - 1; nIndex++) - { - delete[] ppValues[2 * nIndex + 0]; - delete[] ppValues[2 * nIndex + 1]; - } - delete[] ppValues; - } - } - void CShading::SetGrayColors(unsigned char* pColors, double* pPoints, int nCount) - { - if (!pColors || !pPoints || nCount <= 1) - return; - - m_bRgb = false; - m_pColors = new unsigned char[nCount]; - m_pColorsPoints = new double[nCount]; - m_nColorsCount = nCount; - - if (!m_pColors || !m_pColorsPoints) - return; - - memcpy(m_pColors, pColors, nCount); - - Add("ColorSpace", "DeviceGray"); - - CArrayObject* pDomain = new CArrayObject(); - if (!pDomain) - return; - - pDomain->Add(0.0); - pDomain->Add(1.0); - Add("Domain", pDomain); - - if (nCount <= 2) - { - double pC0Values = pColors[0] / 255.0; - double pC1Values = pColors[1] / 255.0; - - CLinearFuntion* pFunction = new CLinearFuntion(m_pXref, &pC0Values, &pC1Values, 1); - Add("Function", pFunction); - } - else - { - double* pValues = new double[(nCount - 1) * 2]; - if (pValues) - { - for (int nIndex = 0; nIndex < nCount - 1; nIndex++) - { - pValues[2 * nIndex + 0] = pColors[nIndex] / 255.0; - pValues[2 * nIndex + 1] = pColors[nIndex + 1] / 255.0; - } - - CLineSegmentFuntion* pFunction = new CLineSegmentFuntion(m_pXref, &pValues, pPoints + 1, nCount - 1, 1); - Add("Function", pFunction); - delete[] pValues; - } - } - } - void CShading::SetExtend(bool bBegin, bool bEnd) - { - CArrayObject* pExtend = new CArrayObject(); - if (!pExtend) - return; - - pExtend->Add(bBegin); - pExtend->Add(bEnd); - Add("Extend", pExtend); - - m_bBeginExtend = bBegin; - m_bEndExtend = bEnd; - } - bool CShading::CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb) - { - if (nCount != m_nColorsCount - || (pColors && !m_pColors) - || (pPoints && !m_pColorsPoints) - || (!pColors && m_pColors) - || (!pPoints && m_pColorsPoints) - || bRgb != m_bRgb) - return false; - - if (m_bRgb) - { - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - if (pColors[3 * nIndex + 0] != m_pColors[3 * nIndex + 0] - || pColors[3 * nIndex + 1] != m_pColors[3 * nIndex + 1] - || pColors[3 * nIndex + 2] != m_pColors[3 * nIndex + 2] - || fabs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01) - return false; - } - } - else - { - for (int nIndex = 0; nIndex < nCount; nIndex++) - { - if (pColors[nIndex] != m_pColors[nIndex] - || fabs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01) - return false; - } - } - - return true; - } - bool CShading::CompareExtend(bool bBegin, bool bEnd) - { - if (bBegin != m_bBeginExtend || bEnd != m_bEndExtend) - return false; - - return true; - } - //---------------------------------------------------------------------------------------- - // CAxialShading - //---------------------------------------------------------------------------------------- - CAxialShading::CAxialShading(CXref* pXref, double dX0, double dY0, double dX1, double dY1) : CShading(pXref) - { - Add("ShadingType", 2); - - CArrayObject* pCoords = new CArrayObject(); - if (!pCoords) - return; - - pCoords->Add(dX0); - pCoords->Add(dY0); - pCoords->Add(dX1); - pCoords->Add(dY1); - Add("Coords", pCoords); - - m_dX0 = dX0; - m_dY0 = dY0; - m_dX1 = dX1; - m_dY1 = dY1; - } - bool CAxialShading::Compare(double dX0, double dY0, double dX1, double dY1) - { - if (fabs(dX0 - m_dX0) > 0.01 - || fabs(dY0 - m_dY0) > 0.01 - || fabs(dX1 - m_dX1) > 0.01 - || fabs(dY1 - m_dY1) > 0.01) - return false; - - return true; - } - //---------------------------------------------------------------------------------------- - // CRadialShading - //---------------------------------------------------------------------------------------- - CRadialShading::CRadialShading(CXref* pXref, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1) : CShading(pXref) - { - Add("ShadingType", 3); - - CArrayObject* pCoords = new CArrayObject(); - if (!pCoords) - return; - - pCoords->Add(dX0); - pCoords->Add(dY0); - pCoords->Add(dR0); - pCoords->Add(dX1); - pCoords->Add(dY1); - pCoords->Add(dR1); - Add("Coords", pCoords); - - m_dX0 = dX0; - m_dY0 = dY0; - m_dR0 = dR0; - m_dX1 = dX1; - m_dY1 = dY1; - m_dR1 = dR1; - } - bool CRadialShading::Compare(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1) - { - if (fabs(dX0 - m_dX0) > 0.01 - || fabs(dY0 - m_dY0) > 0.01 - || fabs(dR0 - m_dR0) > 0.01 - || fabs(dX1 - m_dX1) > 0.01 - || fabs(dY1 - m_dY1) > 0.01 - || fabs(dR1 - m_dR1) > 0.01) - return false; - - return true; - } +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Shading.h" + +namespace PdfWriter +{ + //---------------------------------------------------------------------------------------- + // CLinearFuntion + //---------------------------------------------------------------------------------------- + class CLinearFuntion : public CDictObject + { + public: + CLinearFuntion(CXref* pXref, double* pC0Values, double* pC1Values, int nCount) + { + if (!nCount || !pC0Values || !pC1Values) + return; + + pXref->Add(this); + + Add("FunctionType", 2); + + CArrayObject* pDomain = new CArrayObject(); + if (!pDomain) + return; + + pDomain->Add(0.0); + pDomain->Add(1.0); + + Add("Domain", pDomain); + + CArrayObject* pC0Array = new CArrayObject(); + if (!pC0Array) + return; + + Add("C0", pC0Array); + + CArrayObject* pC1Array = new CArrayObject(); + if (!pC1Array) + return; + + Add("C1", pC1Array); + + Add("N", 1); + + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + pC0Array->Add(pC0Values[nIndex]); + pC1Array->Add(pC1Values[nIndex]); + } + + } + }; + //---------------------------------------------------------------------------------------- + // CLineSegmentFuntion + //---------------------------------------------------------------------------------------- + class CLineSegmentFuntion : public CDictObject + { + public: + CLineSegmentFuntion(CXref* pXref, double** ppValues, double* pPoints, int nFunctionsCount, int nOutputDimension) + { + pXref->Add(this); + + Add("FunctionType", 3); + + CArrayObject* pDomain = new CArrayObject(); + if (!pDomain) + return; + pDomain->Add(0.0); + pDomain->Add(1.0); + Add("Domain", pDomain); + + CArrayObject* pFunctions = new CArrayObject(); + if (!pFunctions) + return; + + Add("Functions", pFunctions); + + CArrayObject* pBounds = new CArrayObject(); + if (!pBounds) + return; + + Add("Bounds", pBounds); + + CArrayObject* pEncode = new CArrayObject(); + if (!pEncode) + return; + + Add("Encode", pEncode); + + for (int nFunctionIndex = 0; nFunctionIndex < nFunctionsCount; nFunctionIndex++) + { + CLinearFuntion* pFunc = new CLinearFuntion(pXref, ppValues[2 * nFunctionIndex], ppValues[2 * nFunctionIndex + 1], nOutputDimension); + pFunctions->Add(pFunc); + pEncode->Add(0.0); + pEncode->Add(1.0); + + if (nFunctionIndex != nFunctionsCount - 1) + pBounds->Add(pPoints[nFunctionIndex]); + } + } + }; + //---------------------------------------------------------------------------------------- + // CShading + //---------------------------------------------------------------------------------------- + CShading::CShading(CXref* pXref) + { + m_pXref = pXref; + pXref->Add(this); + + m_bRgb = true; + m_pColors = NULL; + m_pColorsPoints = NULL; + m_nColorsCount = 0; + m_bBeginExtend = false; + m_bEndExtend = false; + } + CShading::~CShading() + { + if (m_pColors) + delete[] m_pColors; + + if (m_pColorsPoints) + delete[] m_pColorsPoints; + } + void CShading::SetRgbColors(unsigned char* pColors, double* pPoints, int nCount) + { + if (!pColors || !pPoints || nCount <= 1) + return; + + m_bRgb = true; + m_pColors = new unsigned char[3 * nCount]; + m_pColorsPoints = new double[nCount]; + m_nColorsCount = nCount; + + if (!m_pColors || !m_pColorsPoints) + return; + + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + m_pColors[3 * nIndex + 0] = pColors[3 * nIndex + 0]; + m_pColors[3 * nIndex + 1] = pColors[3 * nIndex + 1]; + m_pColors[3 * nIndex + 2] = pColors[3 * nIndex + 2]; + m_pColorsPoints[nIndex] = pPoints[nIndex]; + } + + Add("ColorSpace", "DeviceRGB"); + + CArrayObject* pDomain = new CArrayObject(); + if (!pDomain) + return; + + pDomain->Add(0.0); + pDomain->Add(1.0); + Add("Domain", pDomain); + + if (nCount <= 2) + { + double pC0Values[] ={ + pColors[0] / 255.0, + pColors[1] / 255.0, + pColors[2] / 255.0 + }; + + double pC1Values[] ={ + pColors[3] / 255.0, + pColors[4] / 255.0, + pColors[5] / 255.0 + }; + + CLinearFuntion* pFunction = new CLinearFuntion(m_pXref, pC0Values, pC1Values, 3); + Add("Function", pFunction); + } + else + { + double** ppValues = new double*[(nCount - 1) * 2]; + for (int nIndex = 0; nIndex < nCount - 1; nIndex++) + { + ppValues[2 * nIndex + 0] = new double[3]; + ppValues[2 * nIndex + 1] = new double[3]; + + ppValues[2 * nIndex + 0][0] = pColors[3 * nIndex + 0] / 255.0; + ppValues[2 * nIndex + 0][1] = pColors[3 * nIndex + 1] / 255.0; + ppValues[2 * nIndex + 0][2] = pColors[3 * nIndex + 2] / 255.0; + ppValues[2 * nIndex + 1][0] = pColors[3 * (nIndex + 1) + 0] / 255.0; + ppValues[2 * nIndex + 1][1] = pColors[3 * (nIndex + 1) + 1] / 255.0; + ppValues[2 * nIndex + 1][2] = pColors[3 * (nIndex + 1) + 2] / 255.0; + } + + CLineSegmentFuntion* pFunction = new CLineSegmentFuntion(m_pXref, ppValues, pPoints + 1, nCount - 1, 3); + Add("Function", pFunction); + + for (int nIndex = 0; nIndex < nCount - 1; nIndex++) + { + delete[] ppValues[2 * nIndex + 0]; + delete[] ppValues[2 * nIndex + 1]; + } + delete[] ppValues; + } + } + void CShading::SetGrayColors(unsigned char* pColors, double* pPoints, int nCount) + { + if (!pColors || !pPoints || nCount <= 1) + return; + + m_bRgb = false; + m_pColors = new unsigned char[nCount]; + m_pColorsPoints = new double[nCount]; + m_nColorsCount = nCount; + + if (!m_pColors || !m_pColorsPoints) + return; + + memcpy(m_pColors, pColors, nCount); + + Add("ColorSpace", "DeviceGray"); + + CArrayObject* pDomain = new CArrayObject(); + if (!pDomain) + return; + + pDomain->Add(0.0); + pDomain->Add(1.0); + Add("Domain", pDomain); + + if (nCount <= 2) + { + double pC0Values = pColors[0] / 255.0; + double pC1Values = pColors[1] / 255.0; + + CLinearFuntion* pFunction = new CLinearFuntion(m_pXref, &pC0Values, &pC1Values, 1); + Add("Function", pFunction); + } + else + { + double* pValues = new double[(nCount - 1) * 2]; + if (pValues) + { + for (int nIndex = 0; nIndex < nCount - 1; nIndex++) + { + pValues[2 * nIndex + 0] = pColors[nIndex] / 255.0; + pValues[2 * nIndex + 1] = pColors[nIndex + 1] / 255.0; + } + + CLineSegmentFuntion* pFunction = new CLineSegmentFuntion(m_pXref, &pValues, pPoints + 1, nCount - 1, 1); + Add("Function", pFunction); + delete[] pValues; + } + } + } + void CShading::SetExtend(bool bBegin, bool bEnd) + { + CArrayObject* pExtend = new CArrayObject(); + if (!pExtend) + return; + + pExtend->Add(bBegin); + pExtend->Add(bEnd); + Add("Extend", pExtend); + + m_bBeginExtend = bBegin; + m_bEndExtend = bEnd; + } + bool CShading::CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb) + { + if (nCount != m_nColorsCount + || (pColors && !m_pColors) + || (pPoints && !m_pColorsPoints) + || (!pColors && m_pColors) + || (!pPoints && m_pColorsPoints) + || bRgb != m_bRgb) + return false; + + if (m_bRgb) + { + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + if (pColors[3 * nIndex + 0] != m_pColors[3 * nIndex + 0] + || pColors[3 * nIndex + 1] != m_pColors[3 * nIndex + 1] + || pColors[3 * nIndex + 2] != m_pColors[3 * nIndex + 2] + || fabs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01) + return false; + } + } + else + { + for (int nIndex = 0; nIndex < nCount; nIndex++) + { + if (pColors[nIndex] != m_pColors[nIndex] + || fabs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01) + return false; + } + } + + return true; + } + bool CShading::CompareExtend(bool bBegin, bool bEnd) + { + if (bBegin != m_bBeginExtend || bEnd != m_bEndExtend) + return false; + + return true; + } + //---------------------------------------------------------------------------------------- + // CAxialShading + //---------------------------------------------------------------------------------------- + CAxialShading::CAxialShading(CXref* pXref, double dX0, double dY0, double dX1, double dY1) : CShading(pXref) + { + Add("ShadingType", 2); + + CArrayObject* pCoords = new CArrayObject(); + if (!pCoords) + return; + + pCoords->Add(dX0); + pCoords->Add(dY0); + pCoords->Add(dX1); + pCoords->Add(dY1); + Add("Coords", pCoords); + + m_dX0 = dX0; + m_dY0 = dY0; + m_dX1 = dX1; + m_dY1 = dY1; + } + bool CAxialShading::Compare(double dX0, double dY0, double dX1, double dY1) + { + if (fabs(dX0 - m_dX0) > 0.01 + || fabs(dY0 - m_dY0) > 0.01 + || fabs(dX1 - m_dX1) > 0.01 + || fabs(dY1 - m_dY1) > 0.01) + return false; + + return true; + } + //---------------------------------------------------------------------------------------- + // CRadialShading + //---------------------------------------------------------------------------------------- + CRadialShading::CRadialShading(CXref* pXref, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1) : CShading(pXref) + { + Add("ShadingType", 3); + + CArrayObject* pCoords = new CArrayObject(); + if (!pCoords) + return; + + pCoords->Add(dX0); + pCoords->Add(dY0); + pCoords->Add(dR0); + pCoords->Add(dX1); + pCoords->Add(dY1); + pCoords->Add(dR1); + Add("Coords", pCoords); + + m_dX0 = dX0; + m_dY0 = dY0; + m_dR0 = dR0; + m_dX1 = dX1; + m_dY1 = dY1; + m_dR1 = dR1; + } + bool CRadialShading::Compare(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1) + { + if (fabs(dX0 - m_dX0) > 0.01 + || fabs(dY0 - m_dY0) > 0.01 + || fabs(dR0 - m_dR0) > 0.01 + || fabs(dX1 - m_dX1) > 0.01 + || fabs(dY1 - m_dY1) > 0.01 + || fabs(dR1 - m_dR1) > 0.01) + return false; + + return true; + } } \ No newline at end of file diff --git a/PdfWriter/Src/Shading.h b/PdfFile/SrcWriter/Shading.h similarity index 97% rename from PdfWriter/Src/Shading.h rename to PdfFile/SrcWriter/Shading.h index 0592fcee74..f77e2333a2 100644 --- a/PdfWriter/Src/Shading.h +++ b/PdfFile/SrcWriter/Shading.h @@ -1,120 +1,120 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_SHADING_H -#define _PDF_WRITER_SRC_STREAMS_H - -#include "Objects.h" -#include "Pattern.h" - -namespace PdfWriter -{ - enum EShadingType - { - shadingtype_Unknown = 0, - shadingtype_Axial = 2, - shadingtype_Radial = 3 - }; - //---------------------------------------------------------------------------------------- - // CShading - //---------------------------------------------------------------------------------------- - class CShading : public CDictObject - { - public: - CShading(CXref* pXref); - virtual ~CShading(); - - void SetRgbColors(unsigned char* pColors, double* dPoints, int nCount); - void SetGrayColors(unsigned char* pColors, double* dPoints, int nCount); - void SetExtend(bool bBeing, bool bEnd); - bool CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb); - bool CompareExtend(bool bBeing, bool bEnd); - - virtual EShadingType GetShadingType() - { - return shadingtype_Unknown; - } - - protected: - - CXref* m_pXref; - - private: - - bool m_bRgb; // Rgb или Gray - unsigned char* m_pColors; - double* m_pColorsPoints; - int m_nColorsCount; - - bool m_bBeginExtend; - bool m_bEndExtend; - }; - //---------------------------------------------------------------------------------------- - // CAxialShading - //---------------------------------------------------------------------------------------- - class CAxialShading : public CShading - { - public: - CAxialShading(CXref* pXref, double dX0, double dY0, double dX1, double dY1); - bool Compare(double dX0, double dY0, double dX1, double dY1); - EShadingType GetShadingType() - { - return shadingtype_Axial; - } - private: - double m_dX0; - double m_dY0; - double m_dX1; - double m_dY1; - }; - //---------------------------------------------------------------------------------------- - // CRadialShading - //---------------------------------------------------------------------------------------- - class CRadialShading : public CShading - { - public: - CRadialShading(CXref* pXref, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1); - bool Compare(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1); - EShadingType GetShadingType() - { - return shadingtype_Radial; - } - private: - double m_dX0; - double m_dY0; - double m_dR0; - double m_dX1; - double m_dY1; - double m_dR1; - }; -} - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_SHADING_H +#define _PDF_WRITER_SRC_STREAMS_H + +#include "Objects.h" +#include "Pattern.h" + +namespace PdfWriter +{ + enum EShadingType + { + shadingtype_Unknown = 0, + shadingtype_Axial = 2, + shadingtype_Radial = 3 + }; + //---------------------------------------------------------------------------------------- + // CShading + //---------------------------------------------------------------------------------------- + class CShading : public CDictObject + { + public: + CShading(CXref* pXref); + virtual ~CShading(); + + void SetRgbColors(unsigned char* pColors, double* dPoints, int nCount); + void SetGrayColors(unsigned char* pColors, double* dPoints, int nCount); + void SetExtend(bool bBeing, bool bEnd); + bool CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb); + bool CompareExtend(bool bBeing, bool bEnd); + + virtual EShadingType GetShadingType() + { + return shadingtype_Unknown; + } + + protected: + + CXref* m_pXref; + + private: + + bool m_bRgb; // Rgb или Gray + unsigned char* m_pColors; + double* m_pColorsPoints; + int m_nColorsCount; + + bool m_bBeginExtend; + bool m_bEndExtend; + }; + //---------------------------------------------------------------------------------------- + // CAxialShading + //---------------------------------------------------------------------------------------- + class CAxialShading : public CShading + { + public: + CAxialShading(CXref* pXref, double dX0, double dY0, double dX1, double dY1); + bool Compare(double dX0, double dY0, double dX1, double dY1); + EShadingType GetShadingType() + { + return shadingtype_Axial; + } + private: + double m_dX0; + double m_dY0; + double m_dX1; + double m_dY1; + }; + //---------------------------------------------------------------------------------------- + // CRadialShading + //---------------------------------------------------------------------------------------- + class CRadialShading : public CShading + { + public: + CRadialShading(CXref* pXref, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1); + bool Compare(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1); + EShadingType GetShadingType() + { + return shadingtype_Radial; + } + private: + double m_dX0; + double m_dY0; + double m_dR0; + double m_dX1; + double m_dY1; + double m_dR1; + }; +} + #endif // _PDF_WRITER_SRC_STREAMS_H \ No newline at end of file diff --git a/PdfWriter/Src/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp similarity index 96% rename from PdfWriter/Src/Streams.cpp rename to PdfFile/SrcWriter/Streams.cpp index 02f0bc8764..1b802498c5 100644 --- a/PdfWriter/Src/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -1,961 +1,961 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Streams.h" -#include "Utils.h" -#include "Encrypt.h" -#include "Objects.h" -//#include "FastStringToDouble.h" - -#include - -#include "../../OfficeUtils/src/OfficeUtils.h" -#include "../../UnicodeConverter/UnicodeConverter.h" -#include "../../DesktopEditor/common/StringExt.h" - -#define DEFLATE_BUF_SIZ ((int)(STREAM_BUF_SIZ * 1.1) + 13) - -namespace PdfWriter -{ - static const char* c_pHexStrings[] = - { - "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", - "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", - "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", - "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", - "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" - }; - //---------------------------------------------------------------------------------------- - // CStream - //---------------------------------------------------------------------------------------- - bool CStream::CheckSize(unsigned int unSize) - { - if (Size() - Tell() >= unSize) - return true; - - return false; - } - unsigned int CStream::ReadUInt() - { - if (!CheckSize(4)) - return 0; - - unsigned int unBytesRead = 1; - int nChar0, nChar1, nChar2, nChar3; - Read((BYTE*)&nChar0, &unBytesRead); - Read((BYTE*)&nChar1, &unBytesRead); - Read((BYTE*)&nChar2, &unBytesRead); - Read((BYTE*)&nChar3, &unBytesRead); - - return (unsigned int)((nChar0 << 24) | (nChar1 << 16) | (nChar2 << 8) | nChar3); - } - unsigned char CStream::ReadUChar() - { - if (!CheckSize(1)) - return 0; - - int nChar; - unsigned int unBytesRead = 1; - Read((BYTE*)&nChar, &unBytesRead); - - return nChar; - } - char CStream::ReadChar() - { - return (char)ReadUChar(); - } - unsigned short CStream::ReadUShort() - { - if (!CheckSize(2)) - return 0; - - unsigned int unBytesRead = 1; - int nChar0, nChar1; - Read((BYTE*)&nChar0, &unBytesRead); - Read((BYTE*)&nChar1, &unBytesRead); - - return (unsigned short)((nChar0 << 8) | nChar1); - } - void CStream::Write(const BYTE* pBuffer, unsigned int unSize, bool bCalcCheckSum) - { - Write(pBuffer, unSize); - if (bCalcCheckSum) - { - CRC32 oCRC; - oCRC.ProcessCRC((void*)pBuffer, unSize); - m_unCheckSum = oCRC.m_nCRC32; - } - } - void CStream::WriteChar(char nChar) - { - Write((BYTE*)&nChar, 1); - } - void CStream::WriteStr(const char* sString) - { - unsigned int nLen = StrLen(sString, -1); - Write((BYTE*)sString, nLen); - } - void CStream::WriteUChar(unsigned char unValue) - { - Write(&unValue, 1); - } - void CStream::WriteInt(int nValue) - { - char pBuffer[32]; - memset(pBuffer, 0x00, 32); - ItoA(pBuffer, nValue, pBuffer + 31); - return WriteStr(pBuffer); - } - void CStream::WriteUInt(unsigned int unValue) - { - WriteInt((int)unValue); - } - void CStream::WriteHex(int nValue, int nLen) - { - if (2 == nLen) - Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); - else if (4 == nLen) - { - Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2); - Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); - } - else if (6 == nLen) - { - Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 16)], 2); - Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2); - Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); - } - } - void CStream::WriteReal(float fValue) - { - char pBuffer[32]; - memset(pBuffer, 0x00, 32); - FtoA(pBuffer, fValue, pBuffer + 31); - return WriteStr(pBuffer); - } - void CStream::WriteReal(double dValue) - { - //int nIVal = (int)dValue; - //int nFVal = (int)(fabs(dValue - nIVal) * 10000); - - //int nLen = 0; - //const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen); - //if (nIVal < 0) - // WriteChar('-'); - - //Write((const BYTE*)sString, nLen); - - //if (nFVal) - //{ - // sString = NSFastIntToString::GetString(nFVal, nLen); - - // WriteChar('.'); - // int nZeros = 4 - nLen; - // if (nZeros > 0) - // Write((const BYTE*)NSFastIntToString::GetZeros(nZeros), nZeros); - - // Write((const BYTE*)sString, nLen); - //} - - //char pBuffer[32]; - //int nResLen = 0; - //int nIVal = (int)dValue; - //int nFVal = (int)(fabs(dValue - nIVal) * 10000); - - //int nLen = 0; - //const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen); - //if (nIVal < 0) - // pBuffer[nResLen++] = '-'; - - //memcpy(pBuffer + nResLen, sString, nLen); - //nResLen += nLen; - - //if (nFVal) - //{ - // int nRealLen = 0; - // sString = NSFastIntToString::GetPrecisionString(nFVal, nLen, nRealLen); - - // pBuffer[nResLen++] = '.'; - // int nZeros = 4 - nRealLen; - // if (nZeros > 0) - // { - // memcpy(pBuffer + nResLen, NSFastIntToString::GetZeros(nZeros), nZeros); - // nResLen += nZeros; - // } - - // memcpy(pBuffer + nResLen, sString, nLen); - // nResLen += nLen; - //} - //return Write((const BYTE*)pBuffer, nResLen); - - char pBuffer[32]; - memset(pBuffer, 0x00, 32); - FtoA(pBuffer, dValue, pBuffer + 31); - return WriteStr(pBuffer); - } - void CStream::WriteEscapeName(const char* sValue) - { - char sTmpChar[LIMIT_MAX_NAME_LEN * 3 + 2]; - - const BYTE* pPos1; - char* pPos2; - - pPos1 = (BYTE*)sValue; - pPos2 = sTmpChar; - - *pPos2++ = '/'; - - int nLen = StrLen(sValue, LIMIT_MAX_NAME_LEN); - for (int nIndex = 0; nIndex < nLen; nIndex++) - { - BYTE nChar = *pPos1++; - if (NEEDS_ESCAPE(nChar)) - { - *pPos2++ = '#'; - *pPos2 = (char)(nChar >> 4); - - if (*pPos2 <= 9) - *pPos2 += 0x30; - else - *pPos2 += 0x41 - 10; - - pPos2++; - - *pPos2 = (char)(nChar & 0x0f); - - if (*pPos2 <= 9) - *pPos2 += 0x30; - else - *pPos2 += 0x41 - 10; - - pPos2++; - } - else - *pPos2++ = nChar; - } - - *pPos2 = 0; - - Write((BYTE*)sTmpChar, StrLen(sTmpChar, -1)); - } - void CStream::WriteEscapeText(const BYTE* sText, unsigned int unLen, bool isUTF16, bool isDictValue) - { - if (!unLen || !sText) - { - Write((BYTE*)"()", 2); - return; - } - - BYTE* sTxt = const_cast(sText); - unsigned short* pUtf16Data = NULL; - - WriteChar('('); - - if (isUTF16) - { - std::string sUtf8((char*)sText, unLen); - std::wstring sUnicode = UTF8_TO_U(sUtf8); - unsigned int unLenUtf16 = 0; - pUtf16Data = NSStringExt::CConverter::GetUtf16FromUnicode(sUnicode, unLenUtf16, false); - - sTxt = (BYTE*)pUtf16Data; - unLen = unLenUtf16 << 1; - - WriteChar(0xFE); - WriteChar(0xFF); - } - - char sBuf[TEXT_DEFAULT_LEN]; - unsigned int nIndex = 0; - - for (int nCounter = 0; nCounter < unLen; nCounter++) - { - BYTE nChar = (BYTE)*sTxt++; - - if ((isDictValue && NEEDS_ESCAPE_DICTVALUE(nChar)) || (!isDictValue && NEEDS_ESCAPE(nChar))) - { - sBuf[nIndex++] = '\\'; - sBuf[nIndex++] = 0x30 + (nChar >> 6); - sBuf[nIndex++] = 0x30 + ((nChar & 0x38) >> 3); - sBuf[nIndex++] = 0x30 + (nChar & 0x07); - } - else - { - sBuf[nIndex++] = nChar; - } - - if (nIndex > TEXT_DEFAULT_LEN - 4) - { - Write((BYTE*)sBuf, nIndex); - nIndex = 0; - } - } - - Write((BYTE*)sBuf, nIndex); - WriteChar(')'); - - if (pUtf16Data) - delete []pUtf16Data; - } - void CStream::WriteBinary(const BYTE* pData, unsigned int unLen, CEncrypt* pEncrypt) - { - char sBuf[TEXT_DEFAULT_LEN]; - - BYTE* pBuf = NULL; - bool bDelete = false; - unsigned int nIndex = 0; - - const BYTE* pBuffer = NULL; - if (pEncrypt) - { - pBuf = new BYTE[unLen + 16 + 16]; // iv + padding - bDelete = true; - unLen = pEncrypt->CryptBuf(pData, pBuf, unLen); - pBuffer = pBuf; - } - else - { - pBuffer = pData; - } - - for (int nCounter = 0; nCounter < unLen; nCounter++, pBuffer++) - { - Write((const BYTE*)c_pHexStrings[*pBuffer], 2); - } - - if (nIndex > 0) - { - Write((BYTE*)sBuf, nIndex); - } - - if (bDelete) - delete[] pBuf; - } - void CStream::WriteStreamWithDeflate(CStream* pStream, CEncrypt* pEncrypt) - { - unsigned long nRet = OK; - - CDeflate ZStream; - BYTE inbuf[STREAM_BUF_SIZ]; - BYTE otbuf[DEFLATE_BUF_SIZ]; - - BYTE *otbuf_all = NULL; - - // initialize input stream - pStream->Seek(0, SeekSet); - unsigned long size = pStream->Size(); - if (pEncrypt) - { - unsigned long size_out = (unsigned long)(size * 1.1 + 13 + 64); - otbuf_all = new BYTE[size_out]; - } - - // initialize decompression stream. - ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); - ZStream.Init(DEFLATE_DEFAULT_COMPRESSION, -1); - ZStream.SetIn(inbuf, 0); - - unsigned long size_crypt = 0; - - unsigned int offset = 0; - while(true) - { - unsigned int unSize = STREAM_BUF_SIZ; - pStream->Read(inbuf, &unSize); - - ZStream.SetIn(inbuf, unSize); - - if (0 == unSize) - break; - - while (ZStream.GetAvailIn() > 0) - { - ZStream.Process(DEFLATE_NO_FLUSH); - - if (ZStream.GetAvailOut() == 0) - { - if (pEncrypt) - { - memcpy(otbuf_all + offset, otbuf, DEFLATE_BUF_SIZ); - offset += DEFLATE_BUF_SIZ; - } - else - Write(otbuf, DEFLATE_BUF_SIZ); - - ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); - } - } - } - - bool bEnd = false; - while(true) - { - nRet = ZStream.Process(DEFLATE_FINISH); - if (DEFLATE_OK != nRet && DEFLATE_STREAM_END != nRet) - { - ZStream.End(); - return; - } - - if (DEFLATE_STREAM_END == nRet) - bEnd = true; - - if (ZStream.GetAvailOut() < DEFLATE_BUF_SIZ) - { - unsigned int osize = DEFLATE_BUF_SIZ - ZStream.GetAvailOut(); - if (pEncrypt) - { - memcpy(otbuf_all + offset, otbuf, osize); - offset += osize; - } - else - Write(otbuf, osize); - - ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); - } - - if (bEnd) - break; - } - if (pEncrypt) - { - BYTE *etbuf_all = new BYTE[offset + 32]; - unsigned int osize = pEncrypt->CryptBuf(otbuf_all, etbuf_all, offset); - delete []otbuf_all; - - Write(etbuf_all, osize); - - delete []etbuf_all; - } - - ZStream.End(); - } - void CStream::WriteStream(CStream* pStream, unsigned int unFilter, CEncrypt *pEncrypt) - { - if (pStream->Size() <= 0) - return; - -#ifndef FILTER_FLATE_DECODE_DISABLED - - if (unFilter & STREAM_FILTER_FLATE_DECODE) - return WriteStreamWithDeflate(pStream, pEncrypt); - -#endif - pStream->Seek(0, SeekSet); - - if (pEncrypt) - { - unsigned int size = pStream->Size(); - - BYTE *pBuf = new BYTE[size]; - BYTE *pEBuf = new BYTE[size + 32]; - - pStream->Read(pBuf, &size); - size = pEncrypt->CryptBuf(pBuf, pEBuf, size); - Write(pEBuf, size); - - delete []pBuf; - delete []pEBuf; - } - else - { - BYTE pBuf[STREAM_BUF_SIZ]; - - while(true) - { - unsigned int unSize = STREAM_BUF_SIZ; - pStream->Read(pBuf, &unSize); - - if (0 == unSize) - break; - Write(pBuf, unSize); - } - } - } - void CStream::Write(CNullObject* pNull) - { - } - void CStream::Write(CBoolObject* pBool) - { - if (pBool->Get()) - WriteStr("true"); - else - WriteStr("false"); - } - void CStream::Write(CNumberObject* pNumber) - { - WriteInt(pNumber->Get()); - } - void CStream::Write(CRealObject* pReal) - { - WriteReal(pReal->Get()); - } - void CStream::Write(CNameObject* pName) - { - WriteEscapeName(pName->Get()); - } - void CStream::Write(CStringObject* pString, CEncrypt* pEncrypt) - { - if (pEncrypt) - pEncrypt->Reset(); - - if (pEncrypt) - { - const BYTE* pBinary = pString->GetString(); - WriteChar('<'); - WriteBinary(pBinary, StrLen((const char*)pBinary, -1), pEncrypt); - WriteChar('>'); - } - else - { - WriteEscapeText(pString->GetString(), pString->GetLength(), pString->IsUTF16(), pString->IsDictValue()); - } - } - void CStream::Write(CBinaryObject* pBinary, CEncrypt* pEncrypt) - { - unsigned int unLen = pBinary->GetLength(); - BYTE* pValue = pBinary->GetValue(); - - if (0 == unLen || !pValue) - return WriteStr("<>"); - - if (pEncrypt) - pEncrypt->Reset(); - - WriteChar('<'); - WriteBinary(pValue, unLen, pEncrypt); - WriteChar('>'); - } - void CStream::Write(CArrayObject* pArray, CEncrypt* pEncrypt) - { - WriteStr("[ "); - for (int nIndex = 0, nCount = pArray->GetCount(); nIndex < nCount; nIndex++) - { - CObjectBase* pObject = pArray->Get(nIndex, false); - Write(pObject, pEncrypt); - WriteChar(' '); - } - WriteChar(']'); - } - void CStream::Write(CDictObject* pDict, CEncrypt* pEncrypt) - { - WriteStr("<<\012"); - - pDict->BeforeWrite(); - - // EncryptDict не надо шифровать - if (dict_type_ENCRYPT == pDict->GetDictType()) - pEncrypt = NULL; - - // Добавляем запись Filter - if (pDict->GetStream()) - { - pDict->Remove("Filter"); - unsigned int unFilter = pDict->GetFilter(); - if (STREAM_FILTER_NONE != unFilter) - { - CArrayObject* pFilter = new CArrayObject(); - pDict->Add("Filter", pFilter); - -#ifndef FILTER_FLATE_DECODE_DISABLED - if (unFilter & STREAM_FILTER_FLATE_DECODE) - pFilter->Add("FlateDecode"); -#endif - if (unFilter & STREAM_FILTER_DCT_DECODE) - pFilter->Add("DCTDecode"); - - if (unFilter & STREAM_FILTER_JPX_DECODE) - pFilter->Add("JPXDecode"); - - if (unFilter & STREAM_FILTER_JBIG2_DECODE) - pFilter->Add("JBIG2Decode"); - - if (unFilter & STREAM_FILTER_LZW_DECODE) - pFilter->Add("LZWDecode"); - - if (unFilter & STREAM_FILTER_CCITT_DECODE) - pFilter->Add("CCITTFaxDecode"); - - unsigned int unPredictor = pDict->GetPredictor(); - //pDict->Remove("DecodeParams"); - if (STREAM_PREDICTOR_NONE != unPredictor) - { - CArrayObject* pDecode = new CArrayObject(); - pDict->Add("DecodeParams", pDecode); -#ifndef FILTER_FLATE_DECODE_DISABLED - if (unFilter & STREAM_FILTER_FLATE_DECODE) - { - //if ( STREAM_PREDICTOR_FLATE_TIFF == oDict->nPredictor ) - pDecode->Add(new CNullObject()); - } -#endif - if (unFilter & STREAM_FILTER_DCT_DECODE) - { - pDecode->Add(new CNullObject()); - } - if (unFilter & STREAM_FILTER_JPX_DECODE) - { - pDecode->Add(new CNullObject()); - } - if (unFilter & STREAM_FILTER_JBIG2_DECODE) - { - pDecode->Add(new CNullObject()); - } - if (unFilter & STREAM_FILTER_LZW_DECODE) - { - pDecode->Add(new CNullObject()); - } - } - } - } - - if (dict_type_SIGNATURE == pDict->GetDictType()) - pDict->WriteSignatureToStream(this, pEncrypt); - else - pDict->WriteToStream(this, pEncrypt); - - pDict->Write(this); - WriteStr(">>"); - - CStream* pStream = pDict->GetStream(); - if (pStream) - { - CNumberObject* pLength = (CNumberObject*)pDict->Get("Length"); - // "Length" должен управляться таблицей Xref (флаг Indirect) - if (pLength && object_type_NUMBER == pLength->GetType() && pLength->IsIndirect()) - { - if (pEncrypt) - pEncrypt->Reset(); - - WriteStr("\012stream\015\012"); - - unsigned int unStartSize = Tell(); - WriteStream(pStream, pDict->GetFilter(), pEncrypt); - pLength->Set(Tell() - unStartSize); - - WriteStr("\012endstream"); - } - } - - pDict->AfterWrite(); - } - void CStream::Write(CObjectBase* pObject, CEncrypt* pEncrypt) - { - if (pObject) - { - pObject->Write(this, pEncrypt); - } - } - //---------------------------------------------------------------------------------------- - // CMemoryStream - //---------------------------------------------------------------------------------------- - CMemoryStream::CMemoryStream() - { - m_unSize = 0; - m_nBufferSize = 0; - m_pBuffer = NULL; - m_pCur = NULL; - } - CMemoryStream::CMemoryStream(unsigned int unBufferSize) - { - m_unSize = 0; - m_nBufferSize = 0; - m_pBuffer = NULL; - m_pCur = NULL; - - Shrink(unBufferSize); - } - CMemoryStream::~CMemoryStream() - { - Close(); - } - bool CMemoryStream::IsEof() - { - int nRemainBytes = Size() - Tell(); - if (nRemainBytes <= 0) - return true; - - return false; - } - void CMemoryStream::Write(const BYTE* pBuffer, unsigned int unSize) - { - unsigned int unRemainBytes = m_nBufferSize - Tell(); - if (unRemainBytes < unSize) - { - unsigned int unShrinkSize = std::max(unSize, (unsigned int)STREAM_BUF_SIZ); - Shrink(unShrinkSize); - } - MemCpy(m_pCur, pBuffer, unSize); - m_pCur += unSize; - m_unSize = (unsigned int)std::max(m_unSize, (unsigned int)(m_pCur - m_pBuffer)); - } - void CMemoryStream::Read(BYTE* pBuffer, unsigned int* punSize) - { - unsigned int unRemainBytes = m_unSize - Tell(); - unsigned int unReadedBytes = (punSize ? std::min(*punSize, unRemainBytes) : unRemainBytes); - MemCpy(pBuffer, m_pCur, unReadedBytes); - m_pCur += unReadedBytes; - if (punSize) - *punSize = unReadedBytes; - } - void CMemoryStream::Seek(int nPos, EWhenceMode eMode) - { - switch (eMode) - { - case SeekCur: m_pCur += nPos; break; - case SeekEnd: m_pCur = m_pBuffer + m_unSize - nPos; break; - case SeekSet: m_pCur = m_pBuffer + nPos; break; - } - } - int CMemoryStream::Tell() - { - return (int)(m_pCur - m_pBuffer); - } - void CMemoryStream::Close() - { - if (m_pBuffer) - { - free(m_pBuffer); - //delete[] m_pBuffer; - } - - m_nBufferSize = 0; - m_pBuffer = NULL; - m_pCur = NULL; - m_unSize = 0; - } - unsigned int CMemoryStream::Size() - { - return m_unSize; - } - void CMemoryStream::Shrink(unsigned int unSize) - { - if (m_pBuffer) - { - long lPos = Tell(); - - //BYTE* pNewBuffer = new BYTE[m_nBufferSize + unSize]; - //MemCpy(pNewBuffer, m_pBuffer, m_unSize); - //delete[] m_pBuffer; - //m_pBuffer = pNewBuffer; - //m_pCur = m_pBuffer + lPos; - //m_nBufferSize = m_nBufferSize + unSize; - - m_pBuffer = (BYTE*)realloc(m_pBuffer, m_nBufferSize + unSize); - m_pCur = m_pBuffer + lPos; - m_nBufferSize = m_nBufferSize + unSize; - } - else - { - //m_pBuffer = new BYTE[unSize]; - //m_pCur = m_pBuffer; - //m_nBufferSize = unSize; - - m_pBuffer = (BYTE*)malloc(unSize); - m_pCur = m_pBuffer; - m_nBufferSize = unSize; - } - } - //---------------------------------------------------------------------------------------- - // CFileStream - //---------------------------------------------------------------------------------------- - CFileStream::CFileStream() - { - m_wsFilePath = L""; - } - CFileStream::~CFileStream() - { - Close(); - } - bool CFileStream::IsEof() - { - if (m_oFile.TellFile() >= m_oFile.SizeFile()) - return true; - - return false; - } - void CFileStream::Write(const BYTE* pBuffer, unsigned int unSize) - { - m_oFile.WriteFile((BYTE*)pBuffer, unSize); - } - void CFileStream::Read(BYTE *pBuffer, unsigned int* punSize) - { - DWORD dwBytesToRead = *punSize; - DWORD dwSizeRead = 0; - m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead); - *punSize = dwSizeRead; - } - void CFileStream::Seek(int nPos, EWhenceMode eMode) - { - switch (eMode) - { - case SeekCur: m_oFile.SeekFile(nPos, SEEK_CUR); break; - case SeekEnd: m_oFile.SeekFile(nPos, SEEK_END); break; - case SeekSet: m_oFile.SeekFile(nPos, SEEK_SET); break; - } - } - int CFileStream::Tell() - { - return m_oFile.TellFile(); - } - void CFileStream::Close() - { - m_oFile.CloseFile(); - } - unsigned int CFileStream::Size() - { - return m_oFile.SizeFile(); - } - bool CFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite) - { - Close(); - - m_wsFilePath = wsFilePath; - - if (!bWrite) - { - if (!m_oFile.OpenFile(wsFilePath, true)) - return false; - m_oFile.SeekFile(m_oFile.SizeFile(), SEEK_SET); - } - else - { - if (!m_oFile.CreateFileW(wsFilePath)) - return false; - } - - return true; - } - //---------------------------------------------------------------------------------------- - // CImageFileStream - //---------------------------------------------------------------------------------------- - CImageFileStream::CImageFileStream() - { - m_wsFilePath = L""; - m_nFilePos = 0; - m_nFileSize = 0; - } - CImageFileStream::~CImageFileStream() - { - Close(); - } - bool CImageFileStream::IsEof() - { - if (m_nFilePos >= m_nFileSize) - return true; - - return false; - } - void CImageFileStream::Write(const BYTE* pBuffer, unsigned int unSize) - { - // not used - } - void CImageFileStream::Read(BYTE *pBuffer, unsigned int* punSize) - { - if (!OpenFile()) - { - *punSize = 0; - return; - } - DWORD dwBytesToRead = *punSize; - DWORD dwSizeRead = 0; - m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead); - *punSize = dwSizeRead; - CloseFile(); - } - void CImageFileStream::Seek(int nPos, EWhenceMode eMode) - { - switch (eMode) - { - case SeekCur: m_nFilePos += nPos; break; - case SeekEnd: m_nFilePos = std::max(0, (m_nFileSize - nPos)); break; - case SeekSet: m_nFilePos = nPos; break; - } - } - int CImageFileStream::Tell() - { - return m_nFilePos; - } - void CImageFileStream::Close() - { - m_oFile.CloseFile(); - } - unsigned int CImageFileStream::Size() - { - return m_nFileSize; - } - bool CImageFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite) - { - Close(); - - m_wsFilePath = wsFilePath; - - if (!bWrite) - { - if (!m_oFile.OpenFile(wsFilePath)) - return false; - } - else - { - if (!m_oFile.CreateFileW(wsFilePath)) - return false; - } - - m_nFilePos = 0; - m_nFileSize = m_oFile.SizeFile(); - CloseFile(); - return true; - } - bool CImageFileStream::OpenFile() - { - if (!m_oFile.OpenFile(m_wsFilePath)) - return false; - - m_oFile.SeekFile(m_nFilePos); - return true; - } - void CImageFileStream::CloseFile() - { - m_nFilePos = m_oFile.TellFile(); - m_oFile.CloseFile(); - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Streams.h" +#include "Utils.h" +#include "Encrypt.h" +#include "Objects.h" +//#include "FastStringToDouble.h" + +#include + +#include "../../OfficeUtils/src/OfficeUtils.h" +#include "../../UnicodeConverter/UnicodeConverter.h" +#include "../../DesktopEditor/common/StringExt.h" + +#define DEFLATE_BUF_SIZ ((int)(STREAM_BUF_SIZ * 1.1) + 13) + +namespace PdfWriter +{ + static const char* c_pHexStrings[] = + { + "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", + "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", + "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" + }; + //---------------------------------------------------------------------------------------- + // CStream + //---------------------------------------------------------------------------------------- + bool CStream::CheckSize(unsigned int unSize) + { + if (Size() - Tell() >= unSize) + return true; + + return false; + } + unsigned int CStream::ReadUInt() + { + if (!CheckSize(4)) + return 0; + + unsigned int unBytesRead = 1; + int nChar0, nChar1, nChar2, nChar3; + Read((BYTE*)&nChar0, &unBytesRead); + Read((BYTE*)&nChar1, &unBytesRead); + Read((BYTE*)&nChar2, &unBytesRead); + Read((BYTE*)&nChar3, &unBytesRead); + + return (unsigned int)((nChar0 << 24) | (nChar1 << 16) | (nChar2 << 8) | nChar3); + } + unsigned char CStream::ReadUChar() + { + if (!CheckSize(1)) + return 0; + + int nChar; + unsigned int unBytesRead = 1; + Read((BYTE*)&nChar, &unBytesRead); + + return nChar; + } + char CStream::ReadChar() + { + return (char)ReadUChar(); + } + unsigned short CStream::ReadUShort() + { + if (!CheckSize(2)) + return 0; + + unsigned int unBytesRead = 1; + int nChar0, nChar1; + Read((BYTE*)&nChar0, &unBytesRead); + Read((BYTE*)&nChar1, &unBytesRead); + + return (unsigned short)((nChar0 << 8) | nChar1); + } + void CStream::Write(const BYTE* pBuffer, unsigned int unSize, bool bCalcCheckSum) + { + Write(pBuffer, unSize); + if (bCalcCheckSum) + { + CRC32 oCRC; + oCRC.ProcessCRC((void*)pBuffer, unSize); + m_unCheckSum = oCRC.m_nCRC32; + } + } + void CStream::WriteChar(char nChar) + { + Write((BYTE*)&nChar, 1); + } + void CStream::WriteStr(const char* sString) + { + unsigned int nLen = StrLen(sString, -1); + Write((BYTE*)sString, nLen); + } + void CStream::WriteUChar(unsigned char unValue) + { + Write(&unValue, 1); + } + void CStream::WriteInt(int nValue) + { + char pBuffer[32]; + memset(pBuffer, 0x00, 32); + ItoA(pBuffer, nValue, pBuffer + 31); + return WriteStr(pBuffer); + } + void CStream::WriteUInt(unsigned int unValue) + { + WriteInt((int)unValue); + } + void CStream::WriteHex(int nValue, int nLen) + { + if (2 == nLen) + Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); + else if (4 == nLen) + { + Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2); + Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); + } + else if (6 == nLen) + { + Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 16)], 2); + Write((const BYTE*)c_pHexStrings[(unsigned char)(nValue >> 8)], 2); + Write((const BYTE*)c_pHexStrings[(unsigned char)nValue], 2); + } + } + void CStream::WriteReal(float fValue) + { + char pBuffer[32]; + memset(pBuffer, 0x00, 32); + FtoA(pBuffer, fValue, pBuffer + 31); + return WriteStr(pBuffer); + } + void CStream::WriteReal(double dValue) + { + //int nIVal = (int)dValue; + //int nFVal = (int)(fabs(dValue - nIVal) * 10000); + + //int nLen = 0; + //const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen); + //if (nIVal < 0) + // WriteChar('-'); + + //Write((const BYTE*)sString, nLen); + + //if (nFVal) + //{ + // sString = NSFastIntToString::GetString(nFVal, nLen); + + // WriteChar('.'); + // int nZeros = 4 - nLen; + // if (nZeros > 0) + // Write((const BYTE*)NSFastIntToString::GetZeros(nZeros), nZeros); + + // Write((const BYTE*)sString, nLen); + //} + + //char pBuffer[32]; + //int nResLen = 0; + //int nIVal = (int)dValue; + //int nFVal = (int)(fabs(dValue - nIVal) * 10000); + + //int nLen = 0; + //const char* sString = NSFastIntToString::GetString(fabs(nIVal), nLen); + //if (nIVal < 0) + // pBuffer[nResLen++] = '-'; + + //memcpy(pBuffer + nResLen, sString, nLen); + //nResLen += nLen; + + //if (nFVal) + //{ + // int nRealLen = 0; + // sString = NSFastIntToString::GetPrecisionString(nFVal, nLen, nRealLen); + + // pBuffer[nResLen++] = '.'; + // int nZeros = 4 - nRealLen; + // if (nZeros > 0) + // { + // memcpy(pBuffer + nResLen, NSFastIntToString::GetZeros(nZeros), nZeros); + // nResLen += nZeros; + // } + + // memcpy(pBuffer + nResLen, sString, nLen); + // nResLen += nLen; + //} + //return Write((const BYTE*)pBuffer, nResLen); + + char pBuffer[32]; + memset(pBuffer, 0x00, 32); + FtoA(pBuffer, dValue, pBuffer + 31); + return WriteStr(pBuffer); + } + void CStream::WriteEscapeName(const char* sValue) + { + char sTmpChar[LIMIT_MAX_NAME_LEN * 3 + 2]; + + const BYTE* pPos1; + char* pPos2; + + pPos1 = (BYTE*)sValue; + pPos2 = sTmpChar; + + *pPos2++ = '/'; + + int nLen = StrLen(sValue, LIMIT_MAX_NAME_LEN); + for (int nIndex = 0; nIndex < nLen; nIndex++) + { + BYTE nChar = *pPos1++; + if (NEEDS_ESCAPE(nChar)) + { + *pPos2++ = '#'; + *pPos2 = (char)(nChar >> 4); + + if (*pPos2 <= 9) + *pPos2 += 0x30; + else + *pPos2 += 0x41 - 10; + + pPos2++; + + *pPos2 = (char)(nChar & 0x0f); + + if (*pPos2 <= 9) + *pPos2 += 0x30; + else + *pPos2 += 0x41 - 10; + + pPos2++; + } + else + *pPos2++ = nChar; + } + + *pPos2 = 0; + + Write((BYTE*)sTmpChar, StrLen(sTmpChar, -1)); + } + void CStream::WriteEscapeText(const BYTE* sText, unsigned int unLen, bool isUTF16, bool isDictValue) + { + if (!unLen || !sText) + { + Write((BYTE*)"()", 2); + return; + } + + BYTE* sTxt = const_cast(sText); + unsigned short* pUtf16Data = NULL; + + WriteChar('('); + + if (isUTF16) + { + std::string sUtf8((char*)sText, unLen); + std::wstring sUnicode = UTF8_TO_U(sUtf8); + unsigned int unLenUtf16 = 0; + pUtf16Data = NSStringExt::CConverter::GetUtf16FromUnicode(sUnicode, unLenUtf16, false); + + sTxt = (BYTE*)pUtf16Data; + unLen = unLenUtf16 << 1; + + WriteChar(0xFE); + WriteChar(0xFF); + } + + char sBuf[TEXT_DEFAULT_LEN]; + unsigned int nIndex = 0; + + for (int nCounter = 0; nCounter < unLen; nCounter++) + { + BYTE nChar = (BYTE)*sTxt++; + + if ((isDictValue && NEEDS_ESCAPE_DICTVALUE(nChar)) || (!isDictValue && NEEDS_ESCAPE(nChar))) + { + sBuf[nIndex++] = '\\'; + sBuf[nIndex++] = 0x30 + (nChar >> 6); + sBuf[nIndex++] = 0x30 + ((nChar & 0x38) >> 3); + sBuf[nIndex++] = 0x30 + (nChar & 0x07); + } + else + { + sBuf[nIndex++] = nChar; + } + + if (nIndex > TEXT_DEFAULT_LEN - 4) + { + Write((BYTE*)sBuf, nIndex); + nIndex = 0; + } + } + + Write((BYTE*)sBuf, nIndex); + WriteChar(')'); + + if (pUtf16Data) + delete []pUtf16Data; + } + void CStream::WriteBinary(const BYTE* pData, unsigned int unLen, CEncrypt* pEncrypt) + { + char sBuf[TEXT_DEFAULT_LEN]; + + BYTE* pBuf = NULL; + bool bDelete = false; + unsigned int nIndex = 0; + + const BYTE* pBuffer = NULL; + if (pEncrypt) + { + pBuf = new BYTE[unLen + 16 + 16]; // iv + padding + bDelete = true; + unLen = pEncrypt->CryptBuf(pData, pBuf, unLen); + pBuffer = pBuf; + } + else + { + pBuffer = pData; + } + + for (int nCounter = 0; nCounter < unLen; nCounter++, pBuffer++) + { + Write((const BYTE*)c_pHexStrings[*pBuffer], 2); + } + + if (nIndex > 0) + { + Write((BYTE*)sBuf, nIndex); + } + + if (bDelete) + delete[] pBuf; + } + void CStream::WriteStreamWithDeflate(CStream* pStream, CEncrypt* pEncrypt) + { + unsigned long nRet = OK; + + CDeflate ZStream; + BYTE inbuf[STREAM_BUF_SIZ]; + BYTE otbuf[DEFLATE_BUF_SIZ]; + + BYTE *otbuf_all = NULL; + + // initialize input stream + pStream->Seek(0, SeekSet); + unsigned long size = pStream->Size(); + if (pEncrypt) + { + unsigned long size_out = (unsigned long)(size * 1.1 + 13 + 64); + otbuf_all = new BYTE[size_out]; + } + + // initialize decompression stream. + ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); + ZStream.Init(DEFLATE_DEFAULT_COMPRESSION, -1); + ZStream.SetIn(inbuf, 0); + + unsigned long size_crypt = 0; + + unsigned int offset = 0; + while(true) + { + unsigned int unSize = STREAM_BUF_SIZ; + pStream->Read(inbuf, &unSize); + + ZStream.SetIn(inbuf, unSize); + + if (0 == unSize) + break; + + while (ZStream.GetAvailIn() > 0) + { + ZStream.Process(DEFLATE_NO_FLUSH); + + if (ZStream.GetAvailOut() == 0) + { + if (pEncrypt) + { + memcpy(otbuf_all + offset, otbuf, DEFLATE_BUF_SIZ); + offset += DEFLATE_BUF_SIZ; + } + else + Write(otbuf, DEFLATE_BUF_SIZ); + + ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); + } + } + } + + bool bEnd = false; + while(true) + { + nRet = ZStream.Process(DEFLATE_FINISH); + if (DEFLATE_OK != nRet && DEFLATE_STREAM_END != nRet) + { + ZStream.End(); + return; + } + + if (DEFLATE_STREAM_END == nRet) + bEnd = true; + + if (ZStream.GetAvailOut() < DEFLATE_BUF_SIZ) + { + unsigned int osize = DEFLATE_BUF_SIZ - ZStream.GetAvailOut(); + if (pEncrypt) + { + memcpy(otbuf_all + offset, otbuf, osize); + offset += osize; + } + else + Write(otbuf, osize); + + ZStream.SetOut(otbuf, DEFLATE_BUF_SIZ); + } + + if (bEnd) + break; + } + if (pEncrypt) + { + BYTE *etbuf_all = new BYTE[offset + 32]; + unsigned int osize = pEncrypt->CryptBuf(otbuf_all, etbuf_all, offset); + delete []otbuf_all; + + Write(etbuf_all, osize); + + delete []etbuf_all; + } + + ZStream.End(); + } + void CStream::WriteStream(CStream* pStream, unsigned int unFilter, CEncrypt *pEncrypt) + { + if (pStream->Size() <= 0) + return; + +#ifndef FILTER_FLATE_DECODE_DISABLED + + if (unFilter & STREAM_FILTER_FLATE_DECODE) + return WriteStreamWithDeflate(pStream, pEncrypt); + +#endif + pStream->Seek(0, SeekSet); + + if (pEncrypt) + { + unsigned int size = pStream->Size(); + + BYTE *pBuf = new BYTE[size]; + BYTE *pEBuf = new BYTE[size + 32]; + + pStream->Read(pBuf, &size); + size = pEncrypt->CryptBuf(pBuf, pEBuf, size); + Write(pEBuf, size); + + delete []pBuf; + delete []pEBuf; + } + else + { + BYTE pBuf[STREAM_BUF_SIZ]; + + while(true) + { + unsigned int unSize = STREAM_BUF_SIZ; + pStream->Read(pBuf, &unSize); + + if (0 == unSize) + break; + Write(pBuf, unSize); + } + } + } + void CStream::Write(CNullObject* pNull) + { + } + void CStream::Write(CBoolObject* pBool) + { + if (pBool->Get()) + WriteStr("true"); + else + WriteStr("false"); + } + void CStream::Write(CNumberObject* pNumber) + { + WriteInt(pNumber->Get()); + } + void CStream::Write(CRealObject* pReal) + { + WriteReal(pReal->Get()); + } + void CStream::Write(CNameObject* pName) + { + WriteEscapeName(pName->Get()); + } + void CStream::Write(CStringObject* pString, CEncrypt* pEncrypt) + { + if (pEncrypt) + pEncrypt->Reset(); + + if (pEncrypt) + { + const BYTE* pBinary = pString->GetString(); + WriteChar('<'); + WriteBinary(pBinary, StrLen((const char*)pBinary, -1), pEncrypt); + WriteChar('>'); + } + else + { + WriteEscapeText(pString->GetString(), pString->GetLength(), pString->IsUTF16(), pString->IsDictValue()); + } + } + void CStream::Write(CBinaryObject* pBinary, CEncrypt* pEncrypt) + { + unsigned int unLen = pBinary->GetLength(); + BYTE* pValue = pBinary->GetValue(); + + if (0 == unLen || !pValue) + return WriteStr("<>"); + + if (pEncrypt) + pEncrypt->Reset(); + + WriteChar('<'); + WriteBinary(pValue, unLen, pEncrypt); + WriteChar('>'); + } + void CStream::Write(CArrayObject* pArray, CEncrypt* pEncrypt) + { + WriteStr("[ "); + for (int nIndex = 0, nCount = pArray->GetCount(); nIndex < nCount; nIndex++) + { + CObjectBase* pObject = pArray->Get(nIndex, false); + Write(pObject, pEncrypt); + WriteChar(' '); + } + WriteChar(']'); + } + void CStream::Write(CDictObject* pDict, CEncrypt* pEncrypt) + { + WriteStr("<<\012"); + + pDict->BeforeWrite(); + + // EncryptDict не надо шифровать + if (dict_type_ENCRYPT == pDict->GetDictType()) + pEncrypt = NULL; + + // Добавляем запись Filter + if (pDict->GetStream()) + { + pDict->Remove("Filter"); + unsigned int unFilter = pDict->GetFilter(); + if (STREAM_FILTER_NONE != unFilter) + { + CArrayObject* pFilter = new CArrayObject(); + pDict->Add("Filter", pFilter); + +#ifndef FILTER_FLATE_DECODE_DISABLED + if (unFilter & STREAM_FILTER_FLATE_DECODE) + pFilter->Add("FlateDecode"); +#endif + if (unFilter & STREAM_FILTER_DCT_DECODE) + pFilter->Add("DCTDecode"); + + if (unFilter & STREAM_FILTER_JPX_DECODE) + pFilter->Add("JPXDecode"); + + if (unFilter & STREAM_FILTER_JBIG2_DECODE) + pFilter->Add("JBIG2Decode"); + + if (unFilter & STREAM_FILTER_LZW_DECODE) + pFilter->Add("LZWDecode"); + + if (unFilter & STREAM_FILTER_CCITT_DECODE) + pFilter->Add("CCITTFaxDecode"); + + unsigned int unPredictor = pDict->GetPredictor(); + //pDict->Remove("DecodeParams"); + if (STREAM_PREDICTOR_NONE != unPredictor) + { + CArrayObject* pDecode = new CArrayObject(); + pDict->Add("DecodeParams", pDecode); +#ifndef FILTER_FLATE_DECODE_DISABLED + if (unFilter & STREAM_FILTER_FLATE_DECODE) + { + //if ( STREAM_PREDICTOR_FLATE_TIFF == oDict->nPredictor ) + pDecode->Add(new CNullObject()); + } +#endif + if (unFilter & STREAM_FILTER_DCT_DECODE) + { + pDecode->Add(new CNullObject()); + } + if (unFilter & STREAM_FILTER_JPX_DECODE) + { + pDecode->Add(new CNullObject()); + } + if (unFilter & STREAM_FILTER_JBIG2_DECODE) + { + pDecode->Add(new CNullObject()); + } + if (unFilter & STREAM_FILTER_LZW_DECODE) + { + pDecode->Add(new CNullObject()); + } + } + } + } + + if (dict_type_SIGNATURE == pDict->GetDictType()) + pDict->WriteSignatureToStream(this, pEncrypt); + else + pDict->WriteToStream(this, pEncrypt); + + pDict->Write(this); + WriteStr(">>"); + + CStream* pStream = pDict->GetStream(); + if (pStream) + { + CNumberObject* pLength = (CNumberObject*)pDict->Get("Length"); + // "Length" должен управляться таблицей Xref (флаг Indirect) + if (pLength && object_type_NUMBER == pLength->GetType() && pLength->IsIndirect()) + { + if (pEncrypt) + pEncrypt->Reset(); + + WriteStr("\012stream\015\012"); + + unsigned int unStartSize = Tell(); + WriteStream(pStream, pDict->GetFilter(), pEncrypt); + pLength->Set(Tell() - unStartSize); + + WriteStr("\012endstream"); + } + } + + pDict->AfterWrite(); + } + void CStream::Write(CObjectBase* pObject, CEncrypt* pEncrypt) + { + if (pObject) + { + pObject->Write(this, pEncrypt); + } + } + //---------------------------------------------------------------------------------------- + // CMemoryStream + //---------------------------------------------------------------------------------------- + CMemoryStream::CMemoryStream() + { + m_unSize = 0; + m_nBufferSize = 0; + m_pBuffer = NULL; + m_pCur = NULL; + } + CMemoryStream::CMemoryStream(unsigned int unBufferSize) + { + m_unSize = 0; + m_nBufferSize = 0; + m_pBuffer = NULL; + m_pCur = NULL; + + Shrink(unBufferSize); + } + CMemoryStream::~CMemoryStream() + { + Close(); + } + bool CMemoryStream::IsEof() + { + int nRemainBytes = Size() - Tell(); + if (nRemainBytes <= 0) + return true; + + return false; + } + void CMemoryStream::Write(const BYTE* pBuffer, unsigned int unSize) + { + unsigned int unRemainBytes = m_nBufferSize - Tell(); + if (unRemainBytes < unSize) + { + unsigned int unShrinkSize = std::max(unSize, (unsigned int)STREAM_BUF_SIZ); + Shrink(unShrinkSize); + } + MemCpy(m_pCur, pBuffer, unSize); + m_pCur += unSize; + m_unSize = (unsigned int)std::max(m_unSize, (unsigned int)(m_pCur - m_pBuffer)); + } + void CMemoryStream::Read(BYTE* pBuffer, unsigned int* punSize) + { + unsigned int unRemainBytes = m_unSize - Tell(); + unsigned int unReadedBytes = (punSize ? std::min(*punSize, unRemainBytes) : unRemainBytes); + MemCpy(pBuffer, m_pCur, unReadedBytes); + m_pCur += unReadedBytes; + if (punSize) + *punSize = unReadedBytes; + } + void CMemoryStream::Seek(int nPos, EWhenceMode eMode) + { + switch (eMode) + { + case SeekCur: m_pCur += nPos; break; + case SeekEnd: m_pCur = m_pBuffer + m_unSize - nPos; break; + case SeekSet: m_pCur = m_pBuffer + nPos; break; + } + } + int CMemoryStream::Tell() + { + return (int)(m_pCur - m_pBuffer); + } + void CMemoryStream::Close() + { + if (m_pBuffer) + { + free(m_pBuffer); + //delete[] m_pBuffer; + } + + m_nBufferSize = 0; + m_pBuffer = NULL; + m_pCur = NULL; + m_unSize = 0; + } + unsigned int CMemoryStream::Size() + { + return m_unSize; + } + void CMemoryStream::Shrink(unsigned int unSize) + { + if (m_pBuffer) + { + long lPos = Tell(); + + //BYTE* pNewBuffer = new BYTE[m_nBufferSize + unSize]; + //MemCpy(pNewBuffer, m_pBuffer, m_unSize); + //delete[] m_pBuffer; + //m_pBuffer = pNewBuffer; + //m_pCur = m_pBuffer + lPos; + //m_nBufferSize = m_nBufferSize + unSize; + + m_pBuffer = (BYTE*)realloc(m_pBuffer, m_nBufferSize + unSize); + m_pCur = m_pBuffer + lPos; + m_nBufferSize = m_nBufferSize + unSize; + } + else + { + //m_pBuffer = new BYTE[unSize]; + //m_pCur = m_pBuffer; + //m_nBufferSize = unSize; + + m_pBuffer = (BYTE*)malloc(unSize); + m_pCur = m_pBuffer; + m_nBufferSize = unSize; + } + } + //---------------------------------------------------------------------------------------- + // CFileStream + //---------------------------------------------------------------------------------------- + CFileStream::CFileStream() + { + m_wsFilePath = L""; + } + CFileStream::~CFileStream() + { + Close(); + } + bool CFileStream::IsEof() + { + if (m_oFile.TellFile() >= m_oFile.SizeFile()) + return true; + + return false; + } + void CFileStream::Write(const BYTE* pBuffer, unsigned int unSize) + { + m_oFile.WriteFile((BYTE*)pBuffer, unSize); + } + void CFileStream::Read(BYTE *pBuffer, unsigned int* punSize) + { + DWORD dwBytesToRead = *punSize; + DWORD dwSizeRead = 0; + m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead); + *punSize = dwSizeRead; + } + void CFileStream::Seek(int nPos, EWhenceMode eMode) + { + switch (eMode) + { + case SeekCur: m_oFile.SeekFile(nPos, SEEK_CUR); break; + case SeekEnd: m_oFile.SeekFile(nPos, SEEK_END); break; + case SeekSet: m_oFile.SeekFile(nPos, SEEK_SET); break; + } + } + int CFileStream::Tell() + { + return m_oFile.TellFile(); + } + void CFileStream::Close() + { + m_oFile.CloseFile(); + } + unsigned int CFileStream::Size() + { + return m_oFile.SizeFile(); + } + bool CFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite) + { + Close(); + + m_wsFilePath = wsFilePath; + + if (!bWrite) + { + if (!m_oFile.OpenFile(wsFilePath, true)) + return false; + m_oFile.SeekFile(m_oFile.SizeFile(), SEEK_SET); + } + else + { + if (!m_oFile.CreateFileW(wsFilePath)) + return false; + } + + return true; + } + //---------------------------------------------------------------------------------------- + // CImageFileStream + //---------------------------------------------------------------------------------------- + CImageFileStream::CImageFileStream() + { + m_wsFilePath = L""; + m_nFilePos = 0; + m_nFileSize = 0; + } + CImageFileStream::~CImageFileStream() + { + Close(); + } + bool CImageFileStream::IsEof() + { + if (m_nFilePos >= m_nFileSize) + return true; + + return false; + } + void CImageFileStream::Write(const BYTE* pBuffer, unsigned int unSize) + { + // not used + } + void CImageFileStream::Read(BYTE *pBuffer, unsigned int* punSize) + { + if (!OpenFile()) + { + *punSize = 0; + return; + } + DWORD dwBytesToRead = *punSize; + DWORD dwSizeRead = 0; + m_oFile.ReadFile(pBuffer, dwBytesToRead, dwSizeRead); + *punSize = dwSizeRead; + CloseFile(); + } + void CImageFileStream::Seek(int nPos, EWhenceMode eMode) + { + switch (eMode) + { + case SeekCur: m_nFilePos += nPos; break; + case SeekEnd: m_nFilePos = std::max(0, (m_nFileSize - nPos)); break; + case SeekSet: m_nFilePos = nPos; break; + } + } + int CImageFileStream::Tell() + { + return m_nFilePos; + } + void CImageFileStream::Close() + { + m_oFile.CloseFile(); + } + unsigned int CImageFileStream::Size() + { + return m_nFileSize; + } + bool CImageFileStream::OpenFile(const std::wstring& wsFilePath, bool bWrite) + { + Close(); + + m_wsFilePath = wsFilePath; + + if (!bWrite) + { + if (!m_oFile.OpenFile(wsFilePath)) + return false; + } + else + { + if (!m_oFile.CreateFileW(wsFilePath)) + return false; + } + + m_nFilePos = 0; + m_nFileSize = m_oFile.SizeFile(); + CloseFile(); + return true; + } + bool CImageFileStream::OpenFile() + { + if (!m_oFile.OpenFile(m_wsFilePath)) + return false; + + m_oFile.SeekFile(m_nFilePos); + return true; + } + void CImageFileStream::CloseFile() + { + m_nFilePos = m_oFile.TellFile(); + m_oFile.CloseFile(); + } +} diff --git a/PdfWriter/Src/Streams.h b/PdfFile/SrcWriter/Streams.h similarity index 96% rename from PdfWriter/Src/Streams.h rename to PdfFile/SrcWriter/Streams.h index 182c156070..af8c87699c 100644 --- a/PdfWriter/Src/Streams.h +++ b/PdfFile/SrcWriter/Streams.h @@ -1,230 +1,230 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_STREAMS_H -#define _PDF_WRITER_SRC_STREAMS_H - -#include "Types.h" -#include "../../DesktopEditor/common/File.h" - -#define STREAM_FILTER_NONE 0x0000 -#define STREAM_FILTER_ASCIIHEX 0x0100 -#define STREAM_FILTER_ASCII85 0x0200 -#define STREAM_FILTER_FLATE_DECODE 0x0400 -#define STREAM_FILTER_DCT_DECODE 0x0800 -#define STREAM_FILTER_JPX_DECODE 0x1000 -#define STREAM_FILTER_JBIG2_DECODE 0x2000 -#define STREAM_FILTER_LZW_DECODE 0x4000 -#define STREAM_FILTER_CCITT_DECODE 0x8000 - -#define STREAM_PREDICTOR_NONE 0x0000 -#define STREAM_PREDICTOR_FLATE_TIFF 0x0001 - -namespace PdfWriter -{ - typedef enum - { - SeekSet = 0, - SeekCur = 1, - SeekEnd = 2, - SeekWrite = 3 - } EWhenceMode; - typedef enum - { - StreamUnknown = 0, - StreamCallBack = 1, - StreamFile = 2, - StreamMemory = 3, - StreamTempFile = 4 - } EStreamType; - - class CNullObject; - class CBoolObject; - class CNumberObject; - class CRealObject; - class CNameObject; - class CStringObject; - class CBinaryObject; - class CArrayObject; - class CDictObject; - class CObjectBase; - - class CEncrypt; - class CStream - { - public: - - CStream() - { - m_unCheckSum = 0; - } - virtual ~CStream() - { - } - virtual bool IsEof() = 0; - virtual void Write(const BYTE* pBuffer, unsigned int unSize) = 0; - virtual void Read(BYTE* pBuffer, unsigned int* punSize) = 0; - virtual void Seek(int nPos, EWhenceMode eMode) = 0; - virtual int Tell() = 0; - virtual void Close() = 0; - virtual unsigned int Size() = 0; - virtual EStreamType GetType() - { - return StreamUnknown; - } - - unsigned int ReadUInt(); - unsigned char ReadUChar(); - char ReadChar(); - unsigned short ReadUShort(); - - void Write(const BYTE* pBuffer, unsigned int unSize, bool bCalcCheckSum); - void WriteChar (char nChar); - void WriteStr (const char* sString); - void WriteUChar(unsigned char unChar); - void WriteInt (int nValue); - void WriteUInt (unsigned int nValue); - void WriteHex (int nValue, int nLen); - void WriteReal (float fValue); - void WriteReal (double dValue); - void WriteEscapeName(const char* sValue); - void WriteEscapeText(const BYTE* sText, unsigned int unLen, bool isUTF16 = false, bool isDictValue = false); - void WriteBinary(const BYTE* pData, unsigned int unLen, CEncrypt* pEncrypt); - void WriteStream(CStream* pStream, unsigned int unFilter, CEncrypt* pEncrypt); - - void Write(CNullObject* pNull); - void Write(CBoolObject* pBool); - void Write(CNumberObject* pNumber); - void Write(CRealObject* pReal); - void Write(CNameObject* pName); - void Write(CStringObject* pString, CEncrypt* pEncrypt); - void Write(CBinaryObject* pBinary, CEncrypt* pEncrypt); - void Write(CArrayObject* pBinary, CEncrypt* pEncrypt); - void Write(CDictObject* pDict, CEncrypt* pEncrypt); - void Write(CObjectBase* pObject, CEncrypt* pEncrypt); - - private: - - void WriteStreamWithDeflate(CStream* pStream, CEncrypt* pEncrypt); - bool CheckSize(unsigned int unSize); - - protected: - - unsigned int m_unCheckSum; - }; - class CMemoryStream : public CStream - { - public: - - CMemoryStream(); - CMemoryStream(unsigned int unBufferSize); - ~CMemoryStream(); - bool IsEof(); - void Write(const BYTE* pBuffer, unsigned int unSize); - void Read(BYTE* pBuffer, unsigned int* punSize); - void Seek(int nPos, EWhenceMode eMode); - int Tell(); - void Close(); - unsigned int Size(); - EStreamType GetType() - { - return StreamMemory; - } - - private: - - void Shrink(unsigned int unSize); - - private: - - BYTE* m_pBuffer; - int m_nBufferSize; - BYTE* m_pCur; - unsigned int m_unSize; - }; - class CFileStream : public CStream - { - public: - - CFileStream(); - ~CFileStream(); - bool IsEof(); - void Write(const BYTE* pBuffer, unsigned int unSize); - void Read(BYTE* pBuffer, unsigned int* punSize); - void Seek(int nPos, EWhenceMode eMode); - int Tell(); - void Close(); - unsigned int Size(); - EStreamType GetType() - { - return StreamFile; - } - bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false); - - private: - - NSFile::CFileBinary m_oFile; - std::wstring m_wsFilePath; - }; - class CImageFileStream : public CStream - { - public: - - CImageFileStream(); - ~CImageFileStream(); - bool IsEof(); - void Write(const BYTE* pBuffer, unsigned int unSize); - void Read(BYTE* pBuffer, unsigned int* punSize); - void Seek(int nPos, EWhenceMode eMode); - int Tell(); - void Close(); - unsigned int Size(); - EStreamType GetType() - { - return StreamFile; - } - bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false); - - private: - - bool OpenFile(); - void CloseFile(); - - private: - - NSFile::CFileBinary m_oFile; - std::wstring m_wsFilePath; - int m_nFilePos; - int m_nFileSize; - }; -} - -#endif // _PDF_WRITER_SRC_STREAMS_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_STREAMS_H +#define _PDF_WRITER_SRC_STREAMS_H + +#include "Types.h" +#include "../../DesktopEditor/common/File.h" + +#define STREAM_FILTER_NONE 0x0000 +#define STREAM_FILTER_ASCIIHEX 0x0100 +#define STREAM_FILTER_ASCII85 0x0200 +#define STREAM_FILTER_FLATE_DECODE 0x0400 +#define STREAM_FILTER_DCT_DECODE 0x0800 +#define STREAM_FILTER_JPX_DECODE 0x1000 +#define STREAM_FILTER_JBIG2_DECODE 0x2000 +#define STREAM_FILTER_LZW_DECODE 0x4000 +#define STREAM_FILTER_CCITT_DECODE 0x8000 + +#define STREAM_PREDICTOR_NONE 0x0000 +#define STREAM_PREDICTOR_FLATE_TIFF 0x0001 + +namespace PdfWriter +{ + typedef enum + { + SeekSet = 0, + SeekCur = 1, + SeekEnd = 2, + SeekWrite = 3 + } EWhenceMode; + typedef enum + { + StreamUnknown = 0, + StreamCallBack = 1, + StreamFile = 2, + StreamMemory = 3, + StreamTempFile = 4 + } EStreamType; + + class CNullObject; + class CBoolObject; + class CNumberObject; + class CRealObject; + class CNameObject; + class CStringObject; + class CBinaryObject; + class CArrayObject; + class CDictObject; + class CObjectBase; + + class CEncrypt; + class CStream + { + public: + + CStream() + { + m_unCheckSum = 0; + } + virtual ~CStream() + { + } + virtual bool IsEof() = 0; + virtual void Write(const BYTE* pBuffer, unsigned int unSize) = 0; + virtual void Read(BYTE* pBuffer, unsigned int* punSize) = 0; + virtual void Seek(int nPos, EWhenceMode eMode) = 0; + virtual int Tell() = 0; + virtual void Close() = 0; + virtual unsigned int Size() = 0; + virtual EStreamType GetType() + { + return StreamUnknown; + } + + unsigned int ReadUInt(); + unsigned char ReadUChar(); + char ReadChar(); + unsigned short ReadUShort(); + + void Write(const BYTE* pBuffer, unsigned int unSize, bool bCalcCheckSum); + void WriteChar (char nChar); + void WriteStr (const char* sString); + void WriteUChar(unsigned char unChar); + void WriteInt (int nValue); + void WriteUInt (unsigned int nValue); + void WriteHex (int nValue, int nLen); + void WriteReal (float fValue); + void WriteReal (double dValue); + void WriteEscapeName(const char* sValue); + void WriteEscapeText(const BYTE* sText, unsigned int unLen, bool isUTF16 = false, bool isDictValue = false); + void WriteBinary(const BYTE* pData, unsigned int unLen, CEncrypt* pEncrypt); + void WriteStream(CStream* pStream, unsigned int unFilter, CEncrypt* pEncrypt); + + void Write(CNullObject* pNull); + void Write(CBoolObject* pBool); + void Write(CNumberObject* pNumber); + void Write(CRealObject* pReal); + void Write(CNameObject* pName); + void Write(CStringObject* pString, CEncrypt* pEncrypt); + void Write(CBinaryObject* pBinary, CEncrypt* pEncrypt); + void Write(CArrayObject* pBinary, CEncrypt* pEncrypt); + void Write(CDictObject* pDict, CEncrypt* pEncrypt); + void Write(CObjectBase* pObject, CEncrypt* pEncrypt); + + private: + + void WriteStreamWithDeflate(CStream* pStream, CEncrypt* pEncrypt); + bool CheckSize(unsigned int unSize); + + protected: + + unsigned int m_unCheckSum; + }; + class CMemoryStream : public CStream + { + public: + + CMemoryStream(); + CMemoryStream(unsigned int unBufferSize); + ~CMemoryStream(); + bool IsEof(); + void Write(const BYTE* pBuffer, unsigned int unSize); + void Read(BYTE* pBuffer, unsigned int* punSize); + void Seek(int nPos, EWhenceMode eMode); + int Tell(); + void Close(); + unsigned int Size(); + EStreamType GetType() + { + return StreamMemory; + } + + private: + + void Shrink(unsigned int unSize); + + private: + + BYTE* m_pBuffer; + int m_nBufferSize; + BYTE* m_pCur; + unsigned int m_unSize; + }; + class CFileStream : public CStream + { + public: + + CFileStream(); + ~CFileStream(); + bool IsEof(); + void Write(const BYTE* pBuffer, unsigned int unSize); + void Read(BYTE* pBuffer, unsigned int* punSize); + void Seek(int nPos, EWhenceMode eMode); + int Tell(); + void Close(); + unsigned int Size(); + EStreamType GetType() + { + return StreamFile; + } + bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false); + + private: + + NSFile::CFileBinary m_oFile; + std::wstring m_wsFilePath; + }; + class CImageFileStream : public CStream + { + public: + + CImageFileStream(); + ~CImageFileStream(); + bool IsEof(); + void Write(const BYTE* pBuffer, unsigned int unSize); + void Read(BYTE* pBuffer, unsigned int* punSize); + void Seek(int nPos, EWhenceMode eMode); + int Tell(); + void Close(); + unsigned int Size(); + EStreamType GetType() + { + return StreamFile; + } + bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false); + + private: + + bool OpenFile(); + void CloseFile(); + + private: + + NSFile::CFileBinary m_oFile; + std::wstring m_wsFilePath; + int m_nFilePos; + int m_nFileSize; + }; +} + +#endif // _PDF_WRITER_SRC_STREAMS_H diff --git a/PdfWriter/Src/Types.h b/PdfFile/SrcWriter/Types.h similarity index 95% rename from PdfWriter/Src/Types.h rename to PdfFile/SrcWriter/Types.h index bdc9b11f9b..06436a8248 100644 --- a/PdfWriter/Src/Types.h +++ b/PdfFile/SrcWriter/Types.h @@ -1,452 +1,452 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_TYPES_H -#define _PDF_WRITER_SRC_TYPES_H - -#include "Consts.h" -#include "../../DesktopEditor/common/Types.h" - -#ifdef max -#undef max -#endif -#ifdef min -#undef min -#endif - -#include -#include -#include - -#ifdef __linux__ -#include -#endif - -namespace PdfWriter -{ - struct TRect - { - TRect() - { - fLeft = 0.0; - fBottom = 0.0; - fRight = 0.0; - fTop = 0.0; - } - TRect(double dL, double dT, double dR, double dB) - { - fLeft = dL; - fBottom = dB; - fRight = dR; - fTop = dT; - } - - double fLeft; - double fBottom; - double fRight; - double fTop; - }; - typedef TRect TBox; - class CMatrix - { - public: - - CMatrix() - { - m11 = 1; - m12 = 0; - m21 = 0; - m22 = 1; - x = 0; - y = 0; - } - - void Reset() - { - m11 = 1; - m12 = 0; - m21 = 0; - m22 = 1; - x = 0; - y = 0; - } - bool IsIdentity() const - { - if (fabs(m11 - 1) < 0.001 - && fabs(m12) < 0.001 - && fabs(m21) < 0.001 - && fabs(m22 - 1) < 0.001 - && fabs(x) < 0.001 - && fabs(y) < 0.001) - return true; - - return false; - } - void Apply(double& dX, double& dY) - { - double _x = dX; - double _y = dY; - - dX = _x * m11 + _y * m21 + x; - dY = _x * m12 + _y * m22 + y; - } - bool operator==(const CMatrix& oMatrix) - { - if (fabs(oMatrix.m11 - m11) > 0.001 - || fabs(oMatrix.m12 - m12) > 0.001 - || fabs(oMatrix.m21 - m21) > 0.001 - || fabs(oMatrix.m22 - m22) > 0.001 - || fabs(oMatrix.x - x) > 0.001 - || fabs(oMatrix.y - y) > 0.001) - return false; - - return true; - } - CMatrix Inverse() - { - CMatrix oInverse; - - double dDet = m11 * m22 - m12 * m21; - if (dDet < 0.0001 && dDet > 0.0001) - return oInverse; - - oInverse.m11 = m22 / dDet; - oInverse.m12 = -m12 / dDet; - oInverse.m21 = -m21 / dDet; - oInverse.m22 = m11 / dDet; - oInverse.x = y * m21 / dDet - x * m22 / dDet; - oInverse.y = x * m12 / dDet - y * m11 / dDet; - - return oInverse; - } - - public: - - double m11; - double m12; - double m21; - double m22; - double x; - double y; - }; - enum ELineCapStyle - { - linecap_Butt = 0, - linecap_Round = 1, - linecap_ProjectingSquare = 2, - - linecap_Min = 0, - linecap_Max = 2 - }; - enum ELineJoinStyle - { - linejoin_Miter = 0, - linejoin_Round = 1, - linejoin_Bevel = 2, - - linejoin_Min = 0, - linejoin_Max = 2 - }; - class CDashMode - { - public: - - CDashMode() - { - m_pPattern = NULL; - m_unCount = 0; - m_dPhase = 0; - } - ~CDashMode() - { - if (m_pPattern) - delete[] m_pPattern; - } - CDashMode(const CDashMode& oSrc) - { - m_pPattern = NULL; - Set(oSrc.m_pPattern, oSrc.m_unCount, oSrc.m_dPhase); - } - CDashMode& operator=(const CDashMode& oSrc) - { - m_pPattern = NULL; - Set(oSrc.m_pPattern, oSrc.m_unCount, oSrc.m_dPhase); - return *this; - } - - void Set(const double* pPattern, unsigned int unCount, double dPhase) - { - if (!pPattern || !unCount) - return; - - if (m_pPattern && m_pPattern != pPattern) - delete[] m_pPattern; - - m_pPattern = new double[unCount]; - if (!m_pPattern) - return; - - ::memcpy((BYTE*)m_pPattern, (BYTE*)pPattern, unCount * sizeof(double)); - m_unCount = unCount; - m_dPhase = dPhase; - } - - private: - double* m_pPattern; - unsigned int m_unCount; - double m_dPhase; - }; - enum ETextRenderingMode - { - textrenderingmode_Fill = 0, - textrenderingmode_Stroke = 1, - textrenderingmode_FillThenStroke = 2, - textrenderingmode_Invisible = 3, - textrenderingmode_FillClipping = 4, - textrenderingmode_StrokeClipping = 5, - textrenderingmode_FillStrokeClipping = 6, - textrenderingmode_Clipping = 7, - - textrenderingmode_Min = 0, - textrenderingmode_Max = 7 - }; - enum EColorSpace - { - colotspace_DeviceGray = 0, - colotspace_DeviceRGB = 1, - colotspace_DeviceCMYK = 2, - colotspace_CalGray = 3, - colotspace_CalRGB = 4, - colotspace_LAB = 5, - colotspace_ICCBASED = 6, - colotspace_Separation = 7, - colotspace_DeviceN = 8, - colotspace_Indexed = 9, - colotspace_Pattern = 10, - - colotspace_Min = 0, - colotspace_Max = 10 - }; - struct TRgb - { - double r; - double g; - double b; - - public: - TRgb() - { - r = 0; - g = 0; - b = 0; - } - TRgb(const TRgb& oColor) - { - r = oColor.r; - g = oColor.g; - b = oColor.b; - } - TRgb(const unsigned char& R, const unsigned char& G, const unsigned char& B) - { - r = R / 255.0; - g = G / 255.0; - b = B / 255.0; - } - bool operator ==(const TRgb& oColor)const - { - if (r == oColor.r && g == oColor.g && b == oColor.b) - return true; - - return false; - } - }; - struct TColor - { - unsigned char r; - unsigned char g; - unsigned char b; - - public: - TColor() - { - r = 0; - g = 0; - b = 0; - } - TColor(const unsigned char& R, const unsigned char& G, const unsigned char& B) - { - r = R; - g = G; - b = B; - } - }; - enum EPageLayout - { - pagelayout_Single = 0, - pagelayout_OneColumn = 1, - pagelayout_TwoColumnLeft = 2, - pagelayout_TwoCoulmnRight = 3, - pagelayout_TwoPageLeft = 4, - pagelayout_TwoPageRight = 5, - - pagelayout_Min = 0, - pagelayout_Max = 5 - }; - enum EPageMode - { - pagemode_UseNone = 0, - pagemode_UseOutline = 1, - pagemode_UseThumbs = 2, - pagemode_FullScreen = 3, - pagemode_UseOC = 4, - pagemode_UseAttachments = 5, - - pagemode_Min = 0, - pagemode_Max = 5 - }; - enum EPageNumStyle - { - pagenumstyle_Decimal = 0, - pagenumstyle_UpperRoman = 1, - pagenumstyle_LowerRoman = 2, - pagenumstyle_UpperLetters = 3, - pagenumstyle_LowerLetters = 4, - - pagenumstyle_Min = 0, - pagenumstyle_Max = 4 - }; - class CPoint - { - public: - - CPoint() - { - x = 0; - y = 0; - } - void Set(double dX, double dY) - { - x = dX; - y = dY; - } - void Reset() - { - x = 0; - y = 0; - } - CPoint& operator=(const CPoint& oPoint) - { - x = oPoint.x; - y = oPoint.y; - return *this; - } - - public: - - double x; - double y; - }; - enum EGrMode - { - grmode_PAGE = 0x01, - grmode_PATH = 0x02, - grmode_TEXT = 0x03, - grmode_CLIP = 0x04, - grmode_SHADE = 0x05, - grmode_IMAGE = 0x06, - grmode_XOBJ = 0x08 - }; - enum EBlendMode - { - blendmode_Normal = 0, - blendmode_Multiply = 1, - blendmode_Screen = 2, - blendmode_Overlay = 3, - blendmode_Darken = 4, - blendmode_Lighten = 5, - blendmode_ColorDodge = 6, - blendmode_ColorBum = 7, - blendmode_HardLight = 8, - blendmode_SoftLight = 9, - blendmode_Difference = 10, - blendmode_Exclusion = 11, - - blendmode_Min = 0, - blendmode_Max = 11, - blendmode_Unknown = 12 - }; - enum EStandard14Fonts - { - standard14fonts_Helvetica = 0, - standard14fonts_HelveticaBold = 1, - standard14fonts_HelveticaOblique = 2, - standard14fonts_HelveticeBoldOblique = 3, - standard14fonts_Courier = 4, - standard14fonts_CourierBold = 5, - standard14fonts_CourierOblique = 6, - standard14fonts_CourierBoldOblique = 7, - standard14fonts_Times = 8, - standard14fonts_TimesBold = 9, - standard14fonts_TimesOblique = 10, - standard14fonts_TimesBoldOblique = 11, - standard14fonts_Symbol = 12, - standard14fonts_ZapfDingbats = 13, - - standard14fonts_Min = 0, - standard14fonts_Max = 13 - }; - enum EImageTilePatternType - { - imagetilepatterntype_Default = 0, - imagetilepatterntype_InverseX = 1, - imagetilepatterntype_InverseY = 2, - imagetilepatterntype_InverseXY = 3 - }; - enum EFontType - { - fontUnknownType, - //----- Gr8BitFont - fontType1, - fontType1C, - fontType1COT, - fontType3, - fontTrueType, - fontTrueTypeOT, - //----- GrCIDFont - fontCIDType0, - fontCIDType0C, - fontCIDType0COT, - fontCIDType2, - fontCIDType2OT - }; -} - -#endif // _PDF_WRITER_SRC_TYPES_H +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_TYPES_H +#define _PDF_WRITER_SRC_TYPES_H + +#include "Consts.h" +#include "../../DesktopEditor/common/Types.h" + +#ifdef max +#undef max +#endif +#ifdef min +#undef min +#endif + +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +namespace PdfWriter +{ + struct TRect + { + TRect() + { + fLeft = 0.0; + fBottom = 0.0; + fRight = 0.0; + fTop = 0.0; + } + TRect(double dL, double dT, double dR, double dB) + { + fLeft = dL; + fBottom = dB; + fRight = dR; + fTop = dT; + } + + double fLeft; + double fBottom; + double fRight; + double fTop; + }; + typedef TRect TBox; + class CMatrix + { + public: + + CMatrix() + { + m11 = 1; + m12 = 0; + m21 = 0; + m22 = 1; + x = 0; + y = 0; + } + + void Reset() + { + m11 = 1; + m12 = 0; + m21 = 0; + m22 = 1; + x = 0; + y = 0; + } + bool IsIdentity() const + { + if (fabs(m11 - 1) < 0.001 + && fabs(m12) < 0.001 + && fabs(m21) < 0.001 + && fabs(m22 - 1) < 0.001 + && fabs(x) < 0.001 + && fabs(y) < 0.001) + return true; + + return false; + } + void Apply(double& dX, double& dY) + { + double _x = dX; + double _y = dY; + + dX = _x * m11 + _y * m21 + x; + dY = _x * m12 + _y * m22 + y; + } + bool operator==(const CMatrix& oMatrix) + { + if (fabs(oMatrix.m11 - m11) > 0.001 + || fabs(oMatrix.m12 - m12) > 0.001 + || fabs(oMatrix.m21 - m21) > 0.001 + || fabs(oMatrix.m22 - m22) > 0.001 + || fabs(oMatrix.x - x) > 0.001 + || fabs(oMatrix.y - y) > 0.001) + return false; + + return true; + } + CMatrix Inverse() + { + CMatrix oInverse; + + double dDet = m11 * m22 - m12 * m21; + if (dDet < 0.0001 && dDet > 0.0001) + return oInverse; + + oInverse.m11 = m22 / dDet; + oInverse.m12 = -m12 / dDet; + oInverse.m21 = -m21 / dDet; + oInverse.m22 = m11 / dDet; + oInverse.x = y * m21 / dDet - x * m22 / dDet; + oInverse.y = x * m12 / dDet - y * m11 / dDet; + + return oInverse; + } + + public: + + double m11; + double m12; + double m21; + double m22; + double x; + double y; + }; + enum ELineCapStyle + { + linecap_Butt = 0, + linecap_Round = 1, + linecap_ProjectingSquare = 2, + + linecap_Min = 0, + linecap_Max = 2 + }; + enum ELineJoinStyle + { + linejoin_Miter = 0, + linejoin_Round = 1, + linejoin_Bevel = 2, + + linejoin_Min = 0, + linejoin_Max = 2 + }; + class CDashMode + { + public: + + CDashMode() + { + m_pPattern = NULL; + m_unCount = 0; + m_dPhase = 0; + } + ~CDashMode() + { + if (m_pPattern) + delete[] m_pPattern; + } + CDashMode(const CDashMode& oSrc) + { + m_pPattern = NULL; + Set(oSrc.m_pPattern, oSrc.m_unCount, oSrc.m_dPhase); + } + CDashMode& operator=(const CDashMode& oSrc) + { + m_pPattern = NULL; + Set(oSrc.m_pPattern, oSrc.m_unCount, oSrc.m_dPhase); + return *this; + } + + void Set(const double* pPattern, unsigned int unCount, double dPhase) + { + if (!pPattern || !unCount) + return; + + if (m_pPattern && m_pPattern != pPattern) + delete[] m_pPattern; + + m_pPattern = new double[unCount]; + if (!m_pPattern) + return; + + ::memcpy((BYTE*)m_pPattern, (BYTE*)pPattern, unCount * sizeof(double)); + m_unCount = unCount; + m_dPhase = dPhase; + } + + private: + double* m_pPattern; + unsigned int m_unCount; + double m_dPhase; + }; + enum ETextRenderingMode + { + textrenderingmode_Fill = 0, + textrenderingmode_Stroke = 1, + textrenderingmode_FillThenStroke = 2, + textrenderingmode_Invisible = 3, + textrenderingmode_FillClipping = 4, + textrenderingmode_StrokeClipping = 5, + textrenderingmode_FillStrokeClipping = 6, + textrenderingmode_Clipping = 7, + + textrenderingmode_Min = 0, + textrenderingmode_Max = 7 + }; + enum EColorSpace + { + colotspace_DeviceGray = 0, + colotspace_DeviceRGB = 1, + colotspace_DeviceCMYK = 2, + colotspace_CalGray = 3, + colotspace_CalRGB = 4, + colotspace_LAB = 5, + colotspace_ICCBASED = 6, + colotspace_Separation = 7, + colotspace_DeviceN = 8, + colotspace_Indexed = 9, + colotspace_Pattern = 10, + + colotspace_Min = 0, + colotspace_Max = 10 + }; + struct TRgb + { + double r; + double g; + double b; + + public: + TRgb() + { + r = 0; + g = 0; + b = 0; + } + TRgb(const TRgb& oColor) + { + r = oColor.r; + g = oColor.g; + b = oColor.b; + } + TRgb(const unsigned char& R, const unsigned char& G, const unsigned char& B) + { + r = R / 255.0; + g = G / 255.0; + b = B / 255.0; + } + bool operator ==(const TRgb& oColor)const + { + if (r == oColor.r && g == oColor.g && b == oColor.b) + return true; + + return false; + } + }; + struct TColor + { + unsigned char r; + unsigned char g; + unsigned char b; + + public: + TColor() + { + r = 0; + g = 0; + b = 0; + } + TColor(const unsigned char& R, const unsigned char& G, const unsigned char& B) + { + r = R; + g = G; + b = B; + } + }; + enum EPageLayout + { + pagelayout_Single = 0, + pagelayout_OneColumn = 1, + pagelayout_TwoColumnLeft = 2, + pagelayout_TwoCoulmnRight = 3, + pagelayout_TwoPageLeft = 4, + pagelayout_TwoPageRight = 5, + + pagelayout_Min = 0, + pagelayout_Max = 5 + }; + enum EPageMode + { + pagemode_UseNone = 0, + pagemode_UseOutline = 1, + pagemode_UseThumbs = 2, + pagemode_FullScreen = 3, + pagemode_UseOC = 4, + pagemode_UseAttachments = 5, + + pagemode_Min = 0, + pagemode_Max = 5 + }; + enum EPageNumStyle + { + pagenumstyle_Decimal = 0, + pagenumstyle_UpperRoman = 1, + pagenumstyle_LowerRoman = 2, + pagenumstyle_UpperLetters = 3, + pagenumstyle_LowerLetters = 4, + + pagenumstyle_Min = 0, + pagenumstyle_Max = 4 + }; + class CPoint + { + public: + + CPoint() + { + x = 0; + y = 0; + } + void Set(double dX, double dY) + { + x = dX; + y = dY; + } + void Reset() + { + x = 0; + y = 0; + } + CPoint& operator=(const CPoint& oPoint) + { + x = oPoint.x; + y = oPoint.y; + return *this; + } + + public: + + double x; + double y; + }; + enum EGrMode + { + grmode_PAGE = 0x01, + grmode_PATH = 0x02, + grmode_TEXT = 0x03, + grmode_CLIP = 0x04, + grmode_SHADE = 0x05, + grmode_IMAGE = 0x06, + grmode_XOBJ = 0x08 + }; + enum EBlendMode + { + blendmode_Normal = 0, + blendmode_Multiply = 1, + blendmode_Screen = 2, + blendmode_Overlay = 3, + blendmode_Darken = 4, + blendmode_Lighten = 5, + blendmode_ColorDodge = 6, + blendmode_ColorBum = 7, + blendmode_HardLight = 8, + blendmode_SoftLight = 9, + blendmode_Difference = 10, + blendmode_Exclusion = 11, + + blendmode_Min = 0, + blendmode_Max = 11, + blendmode_Unknown = 12 + }; + enum EStandard14Fonts + { + standard14fonts_Helvetica = 0, + standard14fonts_HelveticaBold = 1, + standard14fonts_HelveticaOblique = 2, + standard14fonts_HelveticeBoldOblique = 3, + standard14fonts_Courier = 4, + standard14fonts_CourierBold = 5, + standard14fonts_CourierOblique = 6, + standard14fonts_CourierBoldOblique = 7, + standard14fonts_Times = 8, + standard14fonts_TimesBold = 9, + standard14fonts_TimesOblique = 10, + standard14fonts_TimesBoldOblique = 11, + standard14fonts_Symbol = 12, + standard14fonts_ZapfDingbats = 13, + + standard14fonts_Min = 0, + standard14fonts_Max = 13 + }; + enum EImageTilePatternType + { + imagetilepatterntype_Default = 0, + imagetilepatterntype_InverseX = 1, + imagetilepatterntype_InverseY = 2, + imagetilepatterntype_InverseXY = 3 + }; + enum EFontType + { + fontUnknownType, + //----- Gr8BitFont + fontType1, + fontType1C, + fontType1COT, + fontType3, + fontTrueType, + fontTrueTypeOT, + //----- GrCIDFont + fontCIDType0, + fontCIDType0C, + fontCIDType0COT, + fontCIDType2, + fontCIDType2OT + }; +} + +#endif // _PDF_WRITER_SRC_TYPES_H diff --git a/PdfWriter/Src/Utils.cpp b/PdfFile/SrcWriter/Utils.cpp similarity index 95% rename from PdfWriter/Src/Utils.cpp rename to PdfFile/SrcWriter/Utils.cpp index d94059bb45..17ad872b72 100644 --- a/PdfWriter/Src/Utils.cpp +++ b/PdfFile/SrcWriter/Utils.cpp @@ -1,244 +1,244 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Utils.h" -#include - -namespace PdfWriter -{ - BYTE* MemCpy(BYTE* pDst, const BYTE *pSrc, unsigned int unLen) - { - if (unLen > 0) - memcpy(pDst, pSrc, unLen); - - return pDst; - } - int StrLen(const char* sString, int nMaxLen) - { - int nLen = 0; - - if (!sString) - return 0; - - while (*sString != 0 && (nMaxLen < 0 || nLen < nMaxLen)) - { - sString++; - nLen++; - } - - return nLen; - } - BYTE* StrCpy(char* sDst, const char* sSrc, char* pEnd) - { - if (NULL != sSrc) - { - while (pEnd > sDst && *sSrc != 0) - *sDst++ = *sSrc++; - } - - *sDst = 0; - - return (BYTE*)sDst; - } - void MemSet(void *pBuf, BYTE nChar, unsigned int unLen) - { - memset(pBuf, nChar, unLen); - } - char* ItoA (char *str, int nVal, char *eptr) - { - char* sTemp; - char sBuf[INT_LEN + 1]; - - if (nVal < 0) - { - if (nVal < LIMIT_MIN_INT) - nVal = LIMIT_MIN_INT; - *str++ = '-'; - nVal = -nVal; - } - else if (nVal > LIMIT_MAX_INT) - { - nVal = LIMIT_MAX_INT; - } - else if (nVal == 0) - { - *str++ = '0'; - } - - sTemp = sBuf + INT_LEN; - *sTemp-- = 0; - - while (nVal > 0) - { - *sTemp = (char)(nVal % 10) + '0'; - nVal /= 10; - sTemp--; - } - - sTemp++; - while (str < eptr && *sTemp != 0) - *str++ = *sTemp++; - - *str = 0; - - return str; - } - char* ItoA2 (char *str, unsigned int nVal, unsigned int nLen) - { - char* sT; - char* sU; - - if (nVal > LIMIT_MAX_INT) - nVal = LIMIT_MAX_INT; - - sU = str + nLen - 1; - *sU = 0; - sT = sU - 1; - while (nVal > 0 && sT >= str) - { - *sT = (char)(nVal % 10) + '0'; - nVal /= 10; - sT--; - } - - while (str <= sT) - *sT-- = '0'; - - return str + nLen - 1; - } - int StrCmp(const char* s1, const char* s2) - { - if (!s1 || !s2) - { - if (!s1 && !s2) - return 0; - if (!s1 && s2) - return -1; - else - return 1; - } - - while (*s1 == *s2) - { - s1++; - s2++; - if (*s1 == 0 || *s2 == 0) - break; - } - - return (BYTE)*s1 - (BYTE)*s2; - } - char* FtoA (char* sDst, double dVal, char* pEnd) - { - int nNPartVal = 0; - int nFPartVal = 0; - char sBuf[REAL_LEN + 1]; - char* sptr = sDst; - char* sTemp; - - unsigned int nIndex = 0; - - if (dVal > LIMIT_MAX_REAL) - dVal = LIMIT_MAX_REAL; - else if (dVal < LIMIT_MIN_REAL) - dVal = LIMIT_MIN_REAL; - - sTemp = sBuf + REAL_LEN; - *sTemp-- = 0; - - if (dVal < 0) - { - *sDst++ = '-'; - dVal = -dVal; - } - - // разделяем целую и дробную части - nNPartVal = (int)(dVal + 0.000005); - nFPartVal = (int)((float)(dVal - nNPartVal + 0.000005) * 100000); - - // пишем дробную часть - for (nIndex = 0; nIndex < 5; nIndex++) - { - *sTemp = (char)(nFPartVal % 10) + '0'; - nFPartVal /= 10; - sTemp--; - } - - // пишем целую часть - *sTemp-- = '.'; - *sTemp = '0'; - if (nNPartVal == 0) - sTemp--; - - while (nNPartVal > 0) - { - *sTemp = (char)(nNPartVal % 10) + '0'; - nNPartVal /= 10; - sTemp--; - } - - sTemp++; - - while (sDst <= pEnd && *sTemp != 0) - *sDst++ = *sTemp++; - sDst--; - - - // TODO: при избавлении от нулей при сдвиге конец строки тоже нужно чистить - // пример число -00.90123 результат "-0.901234" - - while (sDst > sptr) - { - if (*sDst == '0') - *sDst = 0; - else { - if (*sDst == '.') - *sDst = 0; - break; - } - sDst--; - } - - return (*sDst == 0) ? sDst : ++sDst; - } - void UIntChangeBit(unsigned int& nValue, short nBit) - { - // работаем только с 4-байтовыми числами - if (nBit < 0 || nBit > 31) - return; - - unsigned int unBitNum = 1 << nBit; - if (nValue & unBitNum) - nValue ^= unBitNum; - else - nValue |= unBitNum; - } -} +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Utils.h" +#include + +namespace PdfWriter +{ + BYTE* MemCpy(BYTE* pDst, const BYTE *pSrc, unsigned int unLen) + { + if (unLen > 0) + memcpy(pDst, pSrc, unLen); + + return pDst; + } + int StrLen(const char* sString, int nMaxLen) + { + int nLen = 0; + + if (!sString) + return 0; + + while (*sString != 0 && (nMaxLen < 0 || nLen < nMaxLen)) + { + sString++; + nLen++; + } + + return nLen; + } + BYTE* StrCpy(char* sDst, const char* sSrc, char* pEnd) + { + if (NULL != sSrc) + { + while (pEnd > sDst && *sSrc != 0) + *sDst++ = *sSrc++; + } + + *sDst = 0; + + return (BYTE*)sDst; + } + void MemSet(void *pBuf, BYTE nChar, unsigned int unLen) + { + memset(pBuf, nChar, unLen); + } + char* ItoA (char *str, int nVal, char *eptr) + { + char* sTemp; + char sBuf[INT_LEN + 1]; + + if (nVal < 0) + { + if (nVal < LIMIT_MIN_INT) + nVal = LIMIT_MIN_INT; + *str++ = '-'; + nVal = -nVal; + } + else if (nVal > LIMIT_MAX_INT) + { + nVal = LIMIT_MAX_INT; + } + else if (nVal == 0) + { + *str++ = '0'; + } + + sTemp = sBuf + INT_LEN; + *sTemp-- = 0; + + while (nVal > 0) + { + *sTemp = (char)(nVal % 10) + '0'; + nVal /= 10; + sTemp--; + } + + sTemp++; + while (str < eptr && *sTemp != 0) + *str++ = *sTemp++; + + *str = 0; + + return str; + } + char* ItoA2 (char *str, unsigned int nVal, unsigned int nLen) + { + char* sT; + char* sU; + + if (nVal > LIMIT_MAX_INT) + nVal = LIMIT_MAX_INT; + + sU = str + nLen - 1; + *sU = 0; + sT = sU - 1; + while (nVal > 0 && sT >= str) + { + *sT = (char)(nVal % 10) + '0'; + nVal /= 10; + sT--; + } + + while (str <= sT) + *sT-- = '0'; + + return str + nLen - 1; + } + int StrCmp(const char* s1, const char* s2) + { + if (!s1 || !s2) + { + if (!s1 && !s2) + return 0; + if (!s1 && s2) + return -1; + else + return 1; + } + + while (*s1 == *s2) + { + s1++; + s2++; + if (*s1 == 0 || *s2 == 0) + break; + } + + return (BYTE)*s1 - (BYTE)*s2; + } + char* FtoA (char* sDst, double dVal, char* pEnd) + { + int nNPartVal = 0; + int nFPartVal = 0; + char sBuf[REAL_LEN + 1]; + char* sptr = sDst; + char* sTemp; + + unsigned int nIndex = 0; + + if (dVal > LIMIT_MAX_REAL) + dVal = LIMIT_MAX_REAL; + else if (dVal < LIMIT_MIN_REAL) + dVal = LIMIT_MIN_REAL; + + sTemp = sBuf + REAL_LEN; + *sTemp-- = 0; + + if (dVal < 0) + { + *sDst++ = '-'; + dVal = -dVal; + } + + // разделяем целую и дробную части + nNPartVal = (int)(dVal + 0.000005); + nFPartVal = (int)((float)(dVal - nNPartVal + 0.000005) * 100000); + + // пишем дробную часть + for (nIndex = 0; nIndex < 5; nIndex++) + { + *sTemp = (char)(nFPartVal % 10) + '0'; + nFPartVal /= 10; + sTemp--; + } + + // пишем целую часть + *sTemp-- = '.'; + *sTemp = '0'; + if (nNPartVal == 0) + sTemp--; + + while (nNPartVal > 0) + { + *sTemp = (char)(nNPartVal % 10) + '0'; + nNPartVal /= 10; + sTemp--; + } + + sTemp++; + + while (sDst <= pEnd && *sTemp != 0) + *sDst++ = *sTemp++; + sDst--; + + + // TODO: при избавлении от нулей при сдвиге конец строки тоже нужно чистить + // пример число -00.90123 результат "-0.901234" + + while (sDst > sptr) + { + if (*sDst == '0') + *sDst = 0; + else { + if (*sDst == '.') + *sDst = 0; + break; + } + sDst--; + } + + return (*sDst == 0) ? sDst : ++sDst; + } + void UIntChangeBit(unsigned int& nValue, short nBit) + { + // работаем только с 4-байтовыми числами + if (nBit < 0 || nBit > 31) + return; + + unsigned int unBitNum = 1 << nBit; + if (nValue & unBitNum) + nValue ^= unBitNum; + else + nValue |= unBitNum; + } +} diff --git a/PdfWriter/Src/Utils.h b/PdfFile/SrcWriter/Utils.h similarity index 96% rename from PdfWriter/Src/Utils.h rename to PdfFile/SrcWriter/Utils.h index d7bac3ca3f..4a0175dfcf 100644 --- a/PdfWriter/Src/Utils.h +++ b/PdfFile/SrcWriter/Utils.h @@ -1,138 +1,138 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_SRC_UTILS_H -#define _PDF_WRITER_SRC_UTILS_H - -#include "Types.h" - -#define NEEDS_ESCAPE(c) (c < 0x21 || \ - c > 0x7e || \ - c == '\\' || \ - c == '%' || \ - c == '#' || \ - c == '/' || \ - c == '(' || \ - c == ')' || \ - c == '<' || \ - c == '>' || \ - c == '[' || \ - c == ']' || \ - c == '{' || \ - c == '}') \ - -#define NEEDS_ESCAPE_DICTVALUE(c) (c != 0x9 && \ - c != 0xA && \ - (c < 0x20 || \ - c > 0x7e || \ - c == '\\' || \ - c == '%' || \ - c == '#' || \ - c == '/' )) \ - -#define IS_WHITE_SPACE(c) (c == 0x00 || \ - c == 0x09 || \ - c == 0x0A || \ - c == 0x0C || \ - c == 0x0D || \ - c == 0x20 ) \ - - -//----------------------------------------------------------------------------------------------------- -// CRC 32 -//----------------------------------------------------------------------------------------------------- -class CRC32 -{ - -public: - - CRC32() - { - const unsigned CRC_POLY = 0xEDB88320; - - for ( unsigned int i = 0; i < 256; i++ ) - { - unsigned int r, j; - for ( r = i, j = 8; j; j--) - r = r & 1? (r >> 1) ^ CRC_POLY: r >> 1; - - m_pTable[i] = r; - } - - m_nCRC32 = 0; - } - void Init(unsigned int nCRC = 0) - { - m_nCRC32 = nCRC; - } - void ProcessCRC(void* pData, int nLen) - { - const unsigned CRC_MASK = 0xD202EF8D; - register unsigned char *sData = reinterpret_cast(pData); - register unsigned int nCRC = m_nCRC32; - - while ( nLen-- ) - { - nCRC = m_pTable[static_cast(nCRC) ^ *sData++] ^ nCRC >> 8; - nCRC ^= CRC_MASK; - } - - m_nCRC32 = nCRC; - } - -protected: - - unsigned int m_pTable[256]; - -public: - - unsigned int m_nCRC32; - -}; - -namespace PdfWriter -{ - BYTE* MemCpy(BYTE* pDst, const BYTE *pSrc, unsigned int unLen); - void MemSet(void* pBuf, BYTE nChar, unsigned int unLen); - - BYTE* StrCpy(char* sDst, const char* sSrc, char* pEnd); - int StrLen(const char* sString, int nMaxLen); - char* ItoA (char* sDst, int nVal, char* pEnd); - char* ItoA2 (char* sDst, unsigned int unVal, unsigned int unLen); - int StrCmp(const char* s1, const char* s2); - char* FtoA (char* sDst, double dVal, char* pEnd); - - void UIntChangeBit(unsigned int& nValue, short nBit); - void UIntChangeBit2(unsigned int& nValue, short nBit); -} - -#endif // _PDF_WRITER_SRC_UTILS_H - +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#ifndef _PDF_WRITER_SRC_UTILS_H +#define _PDF_WRITER_SRC_UTILS_H + +#include "Types.h" + +#define NEEDS_ESCAPE(c) (c < 0x21 || \ + c > 0x7e || \ + c == '\\' || \ + c == '%' || \ + c == '#' || \ + c == '/' || \ + c == '(' || \ + c == ')' || \ + c == '<' || \ + c == '>' || \ + c == '[' || \ + c == ']' || \ + c == '{' || \ + c == '}') \ + +#define NEEDS_ESCAPE_DICTVALUE(c) (c != 0x9 && \ + c != 0xA && \ + (c < 0x20 || \ + c > 0x7e || \ + c == '\\' || \ + c == '%' || \ + c == '#' || \ + c == '/' )) \ + +#define IS_WHITE_SPACE(c) (c == 0x00 || \ + c == 0x09 || \ + c == 0x0A || \ + c == 0x0C || \ + c == 0x0D || \ + c == 0x20 ) \ + + +//----------------------------------------------------------------------------------------------------- +// CRC 32 +//----------------------------------------------------------------------------------------------------- +class CRC32 +{ + +public: + + CRC32() + { + const unsigned CRC_POLY = 0xEDB88320; + + for ( unsigned int i = 0; i < 256; i++ ) + { + unsigned int r, j; + for ( r = i, j = 8; j; j--) + r = r & 1? (r >> 1) ^ CRC_POLY: r >> 1; + + m_pTable[i] = r; + } + + m_nCRC32 = 0; + } + void Init(unsigned int nCRC = 0) + { + m_nCRC32 = nCRC; + } + void ProcessCRC(void* pData, int nLen) + { + const unsigned CRC_MASK = 0xD202EF8D; + register unsigned char *sData = reinterpret_cast(pData); + register unsigned int nCRC = m_nCRC32; + + while ( nLen-- ) + { + nCRC = m_pTable[static_cast(nCRC) ^ *sData++] ^ nCRC >> 8; + nCRC ^= CRC_MASK; + } + + m_nCRC32 = nCRC; + } + +protected: + + unsigned int m_pTable[256]; + +public: + + unsigned int m_nCRC32; + +}; + +namespace PdfWriter +{ + BYTE* MemCpy(BYTE* pDst, const BYTE *pSrc, unsigned int unLen); + void MemSet(void* pBuf, BYTE nChar, unsigned int unLen); + + BYTE* StrCpy(char* sDst, const char* sSrc, char* pEnd); + int StrLen(const char* sString, int nMaxLen); + char* ItoA (char* sDst, int nVal, char* pEnd); + char* ItoA2 (char* sDst, unsigned int unVal, unsigned int unLen); + int StrCmp(const char* s1, const char* s2); + char* FtoA (char* sDst, double dVal, char* pEnd); + + void UIntChangeBit(unsigned int& nValue, short nBit); + void UIntChangeBit2(unsigned int& nValue, short nBit); +} + +#endif // _PDF_WRITER_SRC_UTILS_H + diff --git a/PdfReader/lib/aconf.h b/PdfFile/lib/aconf.h similarity index 100% rename from PdfReader/lib/aconf.h rename to PdfFile/lib/aconf.h diff --git a/PdfReader/lib/fofi/FoFiBase.cc b/PdfFile/lib/fofi/FoFiBase.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiBase.cc rename to PdfFile/lib/fofi/FoFiBase.cc diff --git a/PdfReader/lib/fofi/FoFiBase.h b/PdfFile/lib/fofi/FoFiBase.h similarity index 100% rename from PdfReader/lib/fofi/FoFiBase.h rename to PdfFile/lib/fofi/FoFiBase.h diff --git a/PdfReader/lib/fofi/FoFiEncodings.cc b/PdfFile/lib/fofi/FoFiEncodings.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiEncodings.cc rename to PdfFile/lib/fofi/FoFiEncodings.cc diff --git a/PdfReader/lib/fofi/FoFiEncodings.h b/PdfFile/lib/fofi/FoFiEncodings.h similarity index 100% rename from PdfReader/lib/fofi/FoFiEncodings.h rename to PdfFile/lib/fofi/FoFiEncodings.h diff --git a/PdfReader/lib/fofi/FoFiIdentifier.cc b/PdfFile/lib/fofi/FoFiIdentifier.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiIdentifier.cc rename to PdfFile/lib/fofi/FoFiIdentifier.cc diff --git a/PdfReader/lib/fofi/FoFiIdentifier.h b/PdfFile/lib/fofi/FoFiIdentifier.h similarity index 100% rename from PdfReader/lib/fofi/FoFiIdentifier.h rename to PdfFile/lib/fofi/FoFiIdentifier.h diff --git a/PdfReader/lib/fofi/FoFiTrueType.cc b/PdfFile/lib/fofi/FoFiTrueType.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiTrueType.cc rename to PdfFile/lib/fofi/FoFiTrueType.cc diff --git a/PdfReader/lib/fofi/FoFiTrueType.h b/PdfFile/lib/fofi/FoFiTrueType.h similarity index 100% rename from PdfReader/lib/fofi/FoFiTrueType.h rename to PdfFile/lib/fofi/FoFiTrueType.h diff --git a/PdfReader/lib/fofi/FoFiType1.cc b/PdfFile/lib/fofi/FoFiType1.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiType1.cc rename to PdfFile/lib/fofi/FoFiType1.cc diff --git a/PdfReader/lib/fofi/FoFiType1.h b/PdfFile/lib/fofi/FoFiType1.h similarity index 100% rename from PdfReader/lib/fofi/FoFiType1.h rename to PdfFile/lib/fofi/FoFiType1.h diff --git a/PdfReader/lib/fofi/FoFiType1C.cc b/PdfFile/lib/fofi/FoFiType1C.cc similarity index 100% rename from PdfReader/lib/fofi/FoFiType1C.cc rename to PdfFile/lib/fofi/FoFiType1C.cc diff --git a/PdfReader/lib/fofi/FoFiType1C.h b/PdfFile/lib/fofi/FoFiType1C.h similarity index 100% rename from PdfReader/lib/fofi/FoFiType1C.h rename to PdfFile/lib/fofi/FoFiType1C.h diff --git a/PdfReader/lib/goo/FixedPoint.cc b/PdfFile/lib/goo/FixedPoint.cc similarity index 100% rename from PdfReader/lib/goo/FixedPoint.cc rename to PdfFile/lib/goo/FixedPoint.cc diff --git a/PdfReader/lib/goo/FixedPoint.h b/PdfFile/lib/goo/FixedPoint.h similarity index 100% rename from PdfReader/lib/goo/FixedPoint.h rename to PdfFile/lib/goo/FixedPoint.h diff --git a/PdfReader/lib/goo/GHash.cc b/PdfFile/lib/goo/GHash.cc similarity index 100% rename from PdfReader/lib/goo/GHash.cc rename to PdfFile/lib/goo/GHash.cc diff --git a/PdfReader/lib/goo/GHash.h b/PdfFile/lib/goo/GHash.h similarity index 100% rename from PdfReader/lib/goo/GHash.h rename to PdfFile/lib/goo/GHash.h diff --git a/PdfReader/lib/goo/GList.cc b/PdfFile/lib/goo/GList.cc similarity index 100% rename from PdfReader/lib/goo/GList.cc rename to PdfFile/lib/goo/GList.cc diff --git a/PdfReader/lib/goo/GList.h b/PdfFile/lib/goo/GList.h similarity index 100% rename from PdfReader/lib/goo/GList.h rename to PdfFile/lib/goo/GList.h diff --git a/PdfReader/lib/goo/GMutex.h b/PdfFile/lib/goo/GMutex.h similarity index 100% rename from PdfReader/lib/goo/GMutex.h rename to PdfFile/lib/goo/GMutex.h diff --git a/PdfReader/lib/goo/GString.cc b/PdfFile/lib/goo/GString.cc similarity index 100% rename from PdfReader/lib/goo/GString.cc rename to PdfFile/lib/goo/GString.cc diff --git a/PdfReader/lib/goo/GString.h b/PdfFile/lib/goo/GString.h similarity index 100% rename from PdfReader/lib/goo/GString.h rename to PdfFile/lib/goo/GString.h diff --git a/PdfReader/lib/goo/Trace.cc b/PdfFile/lib/goo/Trace.cc similarity index 100% rename from PdfReader/lib/goo/Trace.cc rename to PdfFile/lib/goo/Trace.cc diff --git a/PdfReader/lib/goo/Trace.h b/PdfFile/lib/goo/Trace.h similarity index 100% rename from PdfReader/lib/goo/Trace.h rename to PdfFile/lib/goo/Trace.h diff --git a/PdfReader/lib/goo/gfile.cc b/PdfFile/lib/goo/gfile.cc similarity index 100% rename from PdfReader/lib/goo/gfile.cc rename to PdfFile/lib/goo/gfile.cc diff --git a/PdfReader/lib/goo/gfile.h b/PdfFile/lib/goo/gfile.h similarity index 100% rename from PdfReader/lib/goo/gfile.h rename to PdfFile/lib/goo/gfile.h diff --git a/PdfReader/lib/goo/gmem.cc b/PdfFile/lib/goo/gmem.cc similarity index 100% rename from PdfReader/lib/goo/gmem.cc rename to PdfFile/lib/goo/gmem.cc diff --git a/PdfReader/lib/goo/gmem.h b/PdfFile/lib/goo/gmem.h similarity index 100% rename from PdfReader/lib/goo/gmem.h rename to PdfFile/lib/goo/gmem.h diff --git a/PdfReader/lib/goo/gmempp.cc b/PdfFile/lib/goo/gmempp.cc similarity index 100% rename from PdfReader/lib/goo/gmempp.cc rename to PdfFile/lib/goo/gmempp.cc diff --git a/PdfReader/lib/goo/gmempp.h b/PdfFile/lib/goo/gmempp.h similarity index 100% rename from PdfReader/lib/goo/gmempp.h rename to PdfFile/lib/goo/gmempp.h diff --git a/PdfReader/lib/goo/gtypes.h b/PdfFile/lib/goo/gtypes.h similarity index 100% rename from PdfReader/lib/goo/gtypes.h rename to PdfFile/lib/goo/gtypes.h diff --git a/PdfReader/lib/goo/parseargs.c b/PdfFile/lib/goo/parseargs.c similarity index 100% rename from PdfReader/lib/goo/parseargs.c rename to PdfFile/lib/goo/parseargs.c diff --git a/PdfReader/lib/goo/parseargs.h b/PdfFile/lib/goo/parseargs.h similarity index 100% rename from PdfReader/lib/goo/parseargs.h rename to PdfFile/lib/goo/parseargs.h diff --git a/PdfReader/lib/splash/Splash.cc b/PdfFile/lib/splash/Splash.cc similarity index 100% rename from PdfReader/lib/splash/Splash.cc rename to PdfFile/lib/splash/Splash.cc diff --git a/PdfReader/lib/splash/Splash.h b/PdfFile/lib/splash/Splash.h similarity index 100% rename from PdfReader/lib/splash/Splash.h rename to PdfFile/lib/splash/Splash.h diff --git a/PdfReader/lib/splash/SplashBitmap.cc b/PdfFile/lib/splash/SplashBitmap.cc similarity index 100% rename from PdfReader/lib/splash/SplashBitmap.cc rename to PdfFile/lib/splash/SplashBitmap.cc diff --git a/PdfReader/lib/splash/SplashBitmap.h b/PdfFile/lib/splash/SplashBitmap.h similarity index 100% rename from PdfReader/lib/splash/SplashBitmap.h rename to PdfFile/lib/splash/SplashBitmap.h diff --git a/PdfReader/lib/splash/SplashClip.cc b/PdfFile/lib/splash/SplashClip.cc similarity index 100% rename from PdfReader/lib/splash/SplashClip.cc rename to PdfFile/lib/splash/SplashClip.cc diff --git a/PdfReader/lib/splash/SplashClip.h b/PdfFile/lib/splash/SplashClip.h similarity index 100% rename from PdfReader/lib/splash/SplashClip.h rename to PdfFile/lib/splash/SplashClip.h diff --git a/PdfReader/lib/splash/SplashErrorCodes.h b/PdfFile/lib/splash/SplashErrorCodes.h similarity index 100% rename from PdfReader/lib/splash/SplashErrorCodes.h rename to PdfFile/lib/splash/SplashErrorCodes.h diff --git a/PdfReader/lib/splash/SplashFTFont.cc b/PdfFile/lib/splash/SplashFTFont.cc similarity index 100% rename from PdfReader/lib/splash/SplashFTFont.cc rename to PdfFile/lib/splash/SplashFTFont.cc diff --git a/PdfReader/lib/splash/SplashFTFont.h b/PdfFile/lib/splash/SplashFTFont.h similarity index 100% rename from PdfReader/lib/splash/SplashFTFont.h rename to PdfFile/lib/splash/SplashFTFont.h diff --git a/PdfReader/lib/splash/SplashFTFontEngine.cc b/PdfFile/lib/splash/SplashFTFontEngine.cc similarity index 100% rename from PdfReader/lib/splash/SplashFTFontEngine.cc rename to PdfFile/lib/splash/SplashFTFontEngine.cc diff --git a/PdfReader/lib/splash/SplashFTFontEngine.h b/PdfFile/lib/splash/SplashFTFontEngine.h similarity index 100% rename from PdfReader/lib/splash/SplashFTFontEngine.h rename to PdfFile/lib/splash/SplashFTFontEngine.h diff --git a/PdfReader/lib/splash/SplashFTFontFile.cc b/PdfFile/lib/splash/SplashFTFontFile.cc similarity index 100% rename from PdfReader/lib/splash/SplashFTFontFile.cc rename to PdfFile/lib/splash/SplashFTFontFile.cc diff --git a/PdfReader/lib/splash/SplashFTFontFile.h b/PdfFile/lib/splash/SplashFTFontFile.h similarity index 100% rename from PdfReader/lib/splash/SplashFTFontFile.h rename to PdfFile/lib/splash/SplashFTFontFile.h diff --git a/PdfReader/lib/splash/SplashFont.cc b/PdfFile/lib/splash/SplashFont.cc similarity index 100% rename from PdfReader/lib/splash/SplashFont.cc rename to PdfFile/lib/splash/SplashFont.cc diff --git a/PdfReader/lib/splash/SplashFont.h b/PdfFile/lib/splash/SplashFont.h similarity index 100% rename from PdfReader/lib/splash/SplashFont.h rename to PdfFile/lib/splash/SplashFont.h diff --git a/PdfReader/lib/splash/SplashFontEngine.cc b/PdfFile/lib/splash/SplashFontEngine.cc similarity index 100% rename from PdfReader/lib/splash/SplashFontEngine.cc rename to PdfFile/lib/splash/SplashFontEngine.cc diff --git a/PdfReader/lib/splash/SplashFontEngine.h b/PdfFile/lib/splash/SplashFontEngine.h similarity index 100% rename from PdfReader/lib/splash/SplashFontEngine.h rename to PdfFile/lib/splash/SplashFontEngine.h diff --git a/PdfReader/lib/splash/SplashFontFile.cc b/PdfFile/lib/splash/SplashFontFile.cc similarity index 100% rename from PdfReader/lib/splash/SplashFontFile.cc rename to PdfFile/lib/splash/SplashFontFile.cc diff --git a/PdfReader/lib/splash/SplashFontFile.h b/PdfFile/lib/splash/SplashFontFile.h similarity index 100% rename from PdfReader/lib/splash/SplashFontFile.h rename to PdfFile/lib/splash/SplashFontFile.h diff --git a/PdfReader/lib/splash/SplashFontFileID.cc b/PdfFile/lib/splash/SplashFontFileID.cc similarity index 100% rename from PdfReader/lib/splash/SplashFontFileID.cc rename to PdfFile/lib/splash/SplashFontFileID.cc diff --git a/PdfReader/lib/splash/SplashFontFileID.h b/PdfFile/lib/splash/SplashFontFileID.h similarity index 100% rename from PdfReader/lib/splash/SplashFontFileID.h rename to PdfFile/lib/splash/SplashFontFileID.h diff --git a/PdfReader/lib/splash/SplashGlyphBitmap.h b/PdfFile/lib/splash/SplashGlyphBitmap.h similarity index 100% rename from PdfReader/lib/splash/SplashGlyphBitmap.h rename to PdfFile/lib/splash/SplashGlyphBitmap.h diff --git a/PdfReader/lib/splash/SplashMath.h b/PdfFile/lib/splash/SplashMath.h similarity index 100% rename from PdfReader/lib/splash/SplashMath.h rename to PdfFile/lib/splash/SplashMath.h diff --git a/PdfReader/lib/splash/SplashPath.cc b/PdfFile/lib/splash/SplashPath.cc similarity index 100% rename from PdfReader/lib/splash/SplashPath.cc rename to PdfFile/lib/splash/SplashPath.cc diff --git a/PdfReader/lib/splash/SplashPath.h b/PdfFile/lib/splash/SplashPath.h similarity index 100% rename from PdfReader/lib/splash/SplashPath.h rename to PdfFile/lib/splash/SplashPath.h diff --git a/PdfReader/lib/splash/SplashPattern.cc b/PdfFile/lib/splash/SplashPattern.cc similarity index 100% rename from PdfReader/lib/splash/SplashPattern.cc rename to PdfFile/lib/splash/SplashPattern.cc diff --git a/PdfReader/lib/splash/SplashPattern.h b/PdfFile/lib/splash/SplashPattern.h similarity index 100% rename from PdfReader/lib/splash/SplashPattern.h rename to PdfFile/lib/splash/SplashPattern.h diff --git a/PdfReader/lib/splash/SplashScreen.cc b/PdfFile/lib/splash/SplashScreen.cc similarity index 100% rename from PdfReader/lib/splash/SplashScreen.cc rename to PdfFile/lib/splash/SplashScreen.cc diff --git a/PdfReader/lib/splash/SplashScreen.h b/PdfFile/lib/splash/SplashScreen.h similarity index 100% rename from PdfReader/lib/splash/SplashScreen.h rename to PdfFile/lib/splash/SplashScreen.h diff --git a/PdfReader/lib/splash/SplashState.cc b/PdfFile/lib/splash/SplashState.cc similarity index 100% rename from PdfReader/lib/splash/SplashState.cc rename to PdfFile/lib/splash/SplashState.cc diff --git a/PdfReader/lib/splash/SplashState.h b/PdfFile/lib/splash/SplashState.h similarity index 100% rename from PdfReader/lib/splash/SplashState.h rename to PdfFile/lib/splash/SplashState.h diff --git a/PdfReader/lib/splash/SplashTypes.h b/PdfFile/lib/splash/SplashTypes.h similarity index 100% rename from PdfReader/lib/splash/SplashTypes.h rename to PdfFile/lib/splash/SplashTypes.h diff --git a/PdfReader/lib/splash/SplashXPath.cc b/PdfFile/lib/splash/SplashXPath.cc similarity index 100% rename from PdfReader/lib/splash/SplashXPath.cc rename to PdfFile/lib/splash/SplashXPath.cc diff --git a/PdfReader/lib/splash/SplashXPath.h b/PdfFile/lib/splash/SplashXPath.h similarity index 100% rename from PdfReader/lib/splash/SplashXPath.h rename to PdfFile/lib/splash/SplashXPath.h diff --git a/PdfReader/lib/splash/SplashXPathScanner.cc b/PdfFile/lib/splash/SplashXPathScanner.cc similarity index 100% rename from PdfReader/lib/splash/SplashXPathScanner.cc rename to PdfFile/lib/splash/SplashXPathScanner.cc diff --git a/PdfReader/lib/splash/SplashXPathScanner.h b/PdfFile/lib/splash/SplashXPathScanner.h similarity index 100% rename from PdfReader/lib/splash/SplashXPathScanner.h rename to PdfFile/lib/splash/SplashXPathScanner.h diff --git a/PdfReader/lib/xpdf/AcroForm.cc b/PdfFile/lib/xpdf/AcroForm.cc similarity index 100% rename from PdfReader/lib/xpdf/AcroForm.cc rename to PdfFile/lib/xpdf/AcroForm.cc diff --git a/PdfReader/lib/xpdf/AcroForm.h b/PdfFile/lib/xpdf/AcroForm.h similarity index 100% rename from PdfReader/lib/xpdf/AcroForm.h rename to PdfFile/lib/xpdf/AcroForm.h diff --git a/PdfReader/lib/xpdf/Annot.cc b/PdfFile/lib/xpdf/Annot.cc similarity index 100% rename from PdfReader/lib/xpdf/Annot.cc rename to PdfFile/lib/xpdf/Annot.cc diff --git a/PdfReader/lib/xpdf/Annot.h b/PdfFile/lib/xpdf/Annot.h similarity index 100% rename from PdfReader/lib/xpdf/Annot.h rename to PdfFile/lib/xpdf/Annot.h diff --git a/PdfReader/lib/xpdf/Array.cc b/PdfFile/lib/xpdf/Array.cc similarity index 100% rename from PdfReader/lib/xpdf/Array.cc rename to PdfFile/lib/xpdf/Array.cc diff --git a/PdfReader/lib/xpdf/Array.h b/PdfFile/lib/xpdf/Array.h similarity index 100% rename from PdfReader/lib/xpdf/Array.h rename to PdfFile/lib/xpdf/Array.h diff --git a/PdfReader/lib/xpdf/BuiltinFont.cc b/PdfFile/lib/xpdf/BuiltinFont.cc similarity index 100% rename from PdfReader/lib/xpdf/BuiltinFont.cc rename to PdfFile/lib/xpdf/BuiltinFont.cc diff --git a/PdfReader/lib/xpdf/BuiltinFont.h b/PdfFile/lib/xpdf/BuiltinFont.h similarity index 100% rename from PdfReader/lib/xpdf/BuiltinFont.h rename to PdfFile/lib/xpdf/BuiltinFont.h diff --git a/PdfReader/lib/xpdf/BuiltinFontTables.cc b/PdfFile/lib/xpdf/BuiltinFontTables.cc similarity index 100% rename from PdfReader/lib/xpdf/BuiltinFontTables.cc rename to PdfFile/lib/xpdf/BuiltinFontTables.cc diff --git a/PdfReader/lib/xpdf/BuiltinFontTables.h b/PdfFile/lib/xpdf/BuiltinFontTables.h similarity index 100% rename from PdfReader/lib/xpdf/BuiltinFontTables.h rename to PdfFile/lib/xpdf/BuiltinFontTables.h diff --git a/PdfReader/lib/xpdf/CMap.cc b/PdfFile/lib/xpdf/CMap.cc similarity index 100% rename from PdfReader/lib/xpdf/CMap.cc rename to PdfFile/lib/xpdf/CMap.cc diff --git a/PdfReader/lib/xpdf/CMap.h b/PdfFile/lib/xpdf/CMap.h similarity index 100% rename from PdfReader/lib/xpdf/CMap.h rename to PdfFile/lib/xpdf/CMap.h diff --git a/PdfReader/lib/xpdf/Catalog.cc b/PdfFile/lib/xpdf/Catalog.cc similarity index 100% rename from PdfReader/lib/xpdf/Catalog.cc rename to PdfFile/lib/xpdf/Catalog.cc diff --git a/PdfReader/lib/xpdf/Catalog.h b/PdfFile/lib/xpdf/Catalog.h similarity index 100% rename from PdfReader/lib/xpdf/Catalog.h rename to PdfFile/lib/xpdf/Catalog.h diff --git a/PdfReader/lib/xpdf/CharCodeToUnicode.cc b/PdfFile/lib/xpdf/CharCodeToUnicode.cc similarity index 100% rename from PdfReader/lib/xpdf/CharCodeToUnicode.cc rename to PdfFile/lib/xpdf/CharCodeToUnicode.cc diff --git a/PdfReader/lib/xpdf/CharCodeToUnicode.h b/PdfFile/lib/xpdf/CharCodeToUnicode.h similarity index 100% rename from PdfReader/lib/xpdf/CharCodeToUnicode.h rename to PdfFile/lib/xpdf/CharCodeToUnicode.h diff --git a/PdfReader/lib/xpdf/CharTypes.h b/PdfFile/lib/xpdf/CharTypes.h similarity index 100% rename from PdfReader/lib/xpdf/CharTypes.h rename to PdfFile/lib/xpdf/CharTypes.h diff --git a/PdfReader/lib/xpdf/CompactFontTables.h b/PdfFile/lib/xpdf/CompactFontTables.h similarity index 100% rename from PdfReader/lib/xpdf/CompactFontTables.h rename to PdfFile/lib/xpdf/CompactFontTables.h diff --git a/PdfReader/lib/xpdf/Decrypt.cc b/PdfFile/lib/xpdf/Decrypt.cc similarity index 100% rename from PdfReader/lib/xpdf/Decrypt.cc rename to PdfFile/lib/xpdf/Decrypt.cc diff --git a/PdfReader/lib/xpdf/Decrypt.h b/PdfFile/lib/xpdf/Decrypt.h similarity index 100% rename from PdfReader/lib/xpdf/Decrypt.h rename to PdfFile/lib/xpdf/Decrypt.h diff --git a/PdfReader/lib/xpdf/Dict.cc b/PdfFile/lib/xpdf/Dict.cc similarity index 100% rename from PdfReader/lib/xpdf/Dict.cc rename to PdfFile/lib/xpdf/Dict.cc diff --git a/PdfReader/lib/xpdf/Dict.h b/PdfFile/lib/xpdf/Dict.h similarity index 100% rename from PdfReader/lib/xpdf/Dict.h rename to PdfFile/lib/xpdf/Dict.h diff --git a/PdfReader/lib/xpdf/DisplayState.cc b/PdfFile/lib/xpdf/DisplayState.cc similarity index 100% rename from PdfReader/lib/xpdf/DisplayState.cc rename to PdfFile/lib/xpdf/DisplayState.cc diff --git a/PdfReader/lib/xpdf/DisplayState.h b/PdfFile/lib/xpdf/DisplayState.h similarity index 100% rename from PdfReader/lib/xpdf/DisplayState.h rename to PdfFile/lib/xpdf/DisplayState.h diff --git a/PdfReader/lib/xpdf/Error.cc b/PdfFile/lib/xpdf/Error.cc similarity index 100% rename from PdfReader/lib/xpdf/Error.cc rename to PdfFile/lib/xpdf/Error.cc diff --git a/PdfReader/lib/xpdf/Error.h b/PdfFile/lib/xpdf/Error.h similarity index 100% rename from PdfReader/lib/xpdf/Error.h rename to PdfFile/lib/xpdf/Error.h diff --git a/PdfReader/lib/xpdf/ErrorCodes.h b/PdfFile/lib/xpdf/ErrorCodes.h similarity index 100% rename from PdfReader/lib/xpdf/ErrorCodes.h rename to PdfFile/lib/xpdf/ErrorCodes.h diff --git a/PdfReader/lib/xpdf/FontEncodingTables.cc b/PdfFile/lib/xpdf/FontEncodingTables.cc similarity index 100% rename from PdfReader/lib/xpdf/FontEncodingTables.cc rename to PdfFile/lib/xpdf/FontEncodingTables.cc diff --git a/PdfReader/lib/xpdf/FontEncodingTables.h b/PdfFile/lib/xpdf/FontEncodingTables.h similarity index 100% rename from PdfReader/lib/xpdf/FontEncodingTables.h rename to PdfFile/lib/xpdf/FontEncodingTables.h diff --git a/PdfReader/lib/xpdf/Function.cc b/PdfFile/lib/xpdf/Function.cc similarity index 100% rename from PdfReader/lib/xpdf/Function.cc rename to PdfFile/lib/xpdf/Function.cc diff --git a/PdfReader/lib/xpdf/Function.h b/PdfFile/lib/xpdf/Function.h similarity index 100% rename from PdfReader/lib/xpdf/Function.h rename to PdfFile/lib/xpdf/Function.h diff --git a/PdfReader/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc similarity index 100% rename from PdfReader/lib/xpdf/Gfx.cc rename to PdfFile/lib/xpdf/Gfx.cc diff --git a/PdfReader/lib/xpdf/Gfx.h b/PdfFile/lib/xpdf/Gfx.h similarity index 100% rename from PdfReader/lib/xpdf/Gfx.h rename to PdfFile/lib/xpdf/Gfx.h diff --git a/PdfReader/lib/xpdf/GfxFont.cc b/PdfFile/lib/xpdf/GfxFont.cc similarity index 100% rename from PdfReader/lib/xpdf/GfxFont.cc rename to PdfFile/lib/xpdf/GfxFont.cc diff --git a/PdfReader/lib/xpdf/GfxFont.h b/PdfFile/lib/xpdf/GfxFont.h similarity index 100% rename from PdfReader/lib/xpdf/GfxFont.h rename to PdfFile/lib/xpdf/GfxFont.h diff --git a/PdfReader/lib/xpdf/GfxState.cc b/PdfFile/lib/xpdf/GfxState.cc similarity index 100% rename from PdfReader/lib/xpdf/GfxState.cc rename to PdfFile/lib/xpdf/GfxState.cc diff --git a/PdfReader/lib/xpdf/GfxState.h b/PdfFile/lib/xpdf/GfxState.h similarity index 100% rename from PdfReader/lib/xpdf/GfxState.h rename to PdfFile/lib/xpdf/GfxState.h diff --git a/PdfReader/lib/xpdf/GlobalParams.cc b/PdfFile/lib/xpdf/GlobalParams.cc similarity index 100% rename from PdfReader/lib/xpdf/GlobalParams.cc rename to PdfFile/lib/xpdf/GlobalParams.cc diff --git a/PdfReader/lib/xpdf/GlobalParams.h b/PdfFile/lib/xpdf/GlobalParams.h similarity index 100% rename from PdfReader/lib/xpdf/GlobalParams.h rename to PdfFile/lib/xpdf/GlobalParams.h diff --git a/PdfReader/lib/xpdf/HTMLGen.cc b/PdfFile/lib/xpdf/HTMLGen.cc similarity index 100% rename from PdfReader/lib/xpdf/HTMLGen.cc rename to PdfFile/lib/xpdf/HTMLGen.cc diff --git a/PdfReader/lib/xpdf/HTMLGen.h b/PdfFile/lib/xpdf/HTMLGen.h similarity index 100% rename from PdfReader/lib/xpdf/HTMLGen.h rename to PdfFile/lib/xpdf/HTMLGen.h diff --git a/PdfReader/lib/xpdf/ImageOutputDev.cc b/PdfFile/lib/xpdf/ImageOutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/ImageOutputDev.cc rename to PdfFile/lib/xpdf/ImageOutputDev.cc diff --git a/PdfReader/lib/xpdf/ImageOutputDev.h b/PdfFile/lib/xpdf/ImageOutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/ImageOutputDev.h rename to PdfFile/lib/xpdf/ImageOutputDev.h diff --git a/PdfReader/lib/xpdf/JArithmeticDecoder.cc b/PdfFile/lib/xpdf/JArithmeticDecoder.cc similarity index 100% rename from PdfReader/lib/xpdf/JArithmeticDecoder.cc rename to PdfFile/lib/xpdf/JArithmeticDecoder.cc diff --git a/PdfReader/lib/xpdf/JArithmeticDecoder.h b/PdfFile/lib/xpdf/JArithmeticDecoder.h similarity index 100% rename from PdfReader/lib/xpdf/JArithmeticDecoder.h rename to PdfFile/lib/xpdf/JArithmeticDecoder.h diff --git a/PdfReader/lib/xpdf/JBIG2Stream.cc b/PdfFile/lib/xpdf/JBIG2Stream.cc similarity index 100% rename from PdfReader/lib/xpdf/JBIG2Stream.cc rename to PdfFile/lib/xpdf/JBIG2Stream.cc diff --git a/PdfReader/lib/xpdf/JBIG2Stream.h b/PdfFile/lib/xpdf/JBIG2Stream.h similarity index 100% rename from PdfReader/lib/xpdf/JBIG2Stream.h rename to PdfFile/lib/xpdf/JBIG2Stream.h diff --git a/PdfReader/lib/xpdf/JPXStream.cc b/PdfFile/lib/xpdf/JPXStream.cc similarity index 100% rename from PdfReader/lib/xpdf/JPXStream.cc rename to PdfFile/lib/xpdf/JPXStream.cc diff --git a/PdfReader/lib/xpdf/JPXStream.h b/PdfFile/lib/xpdf/JPXStream.h similarity index 100% rename from PdfReader/lib/xpdf/JPXStream.h rename to PdfFile/lib/xpdf/JPXStream.h diff --git a/PdfReader/lib/xpdf/Lexer.cc b/PdfFile/lib/xpdf/Lexer.cc similarity index 100% rename from PdfReader/lib/xpdf/Lexer.cc rename to PdfFile/lib/xpdf/Lexer.cc diff --git a/PdfReader/lib/xpdf/Lexer.h b/PdfFile/lib/xpdf/Lexer.h similarity index 100% rename from PdfReader/lib/xpdf/Lexer.h rename to PdfFile/lib/xpdf/Lexer.h diff --git a/PdfReader/lib/xpdf/Link.cc b/PdfFile/lib/xpdf/Link.cc similarity index 100% rename from PdfReader/lib/xpdf/Link.cc rename to PdfFile/lib/xpdf/Link.cc diff --git a/PdfReader/lib/xpdf/Link.h b/PdfFile/lib/xpdf/Link.h similarity index 100% rename from PdfReader/lib/xpdf/Link.h rename to PdfFile/lib/xpdf/Link.h diff --git a/PdfReader/lib/xpdf/NameToCharCode.cc b/PdfFile/lib/xpdf/NameToCharCode.cc similarity index 100% rename from PdfReader/lib/xpdf/NameToCharCode.cc rename to PdfFile/lib/xpdf/NameToCharCode.cc diff --git a/PdfReader/lib/xpdf/NameToCharCode.h b/PdfFile/lib/xpdf/NameToCharCode.h similarity index 100% rename from PdfReader/lib/xpdf/NameToCharCode.h rename to PdfFile/lib/xpdf/NameToCharCode.h diff --git a/PdfReader/lib/xpdf/NameToUnicodeTable.h b/PdfFile/lib/xpdf/NameToUnicodeTable.h similarity index 100% rename from PdfReader/lib/xpdf/NameToUnicodeTable.h rename to PdfFile/lib/xpdf/NameToUnicodeTable.h diff --git a/PdfReader/lib/xpdf/Object.cc b/PdfFile/lib/xpdf/Object.cc similarity index 100% rename from PdfReader/lib/xpdf/Object.cc rename to PdfFile/lib/xpdf/Object.cc diff --git a/PdfReader/lib/xpdf/Object.h b/PdfFile/lib/xpdf/Object.h similarity index 100% rename from PdfReader/lib/xpdf/Object.h rename to PdfFile/lib/xpdf/Object.h diff --git a/PdfReader/lib/xpdf/OptionalContent.cc b/PdfFile/lib/xpdf/OptionalContent.cc similarity index 100% rename from PdfReader/lib/xpdf/OptionalContent.cc rename to PdfFile/lib/xpdf/OptionalContent.cc diff --git a/PdfReader/lib/xpdf/OptionalContent.h b/PdfFile/lib/xpdf/OptionalContent.h similarity index 100% rename from PdfReader/lib/xpdf/OptionalContent.h rename to PdfFile/lib/xpdf/OptionalContent.h diff --git a/PdfReader/lib/xpdf/Outline.cc b/PdfFile/lib/xpdf/Outline.cc similarity index 100% rename from PdfReader/lib/xpdf/Outline.cc rename to PdfFile/lib/xpdf/Outline.cc diff --git a/PdfReader/lib/xpdf/Outline.h b/PdfFile/lib/xpdf/Outline.h similarity index 100% rename from PdfReader/lib/xpdf/Outline.h rename to PdfFile/lib/xpdf/Outline.h diff --git a/PdfReader/lib/xpdf/OutputDev.cc b/PdfFile/lib/xpdf/OutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/OutputDev.cc rename to PdfFile/lib/xpdf/OutputDev.cc diff --git a/PdfReader/lib/xpdf/OutputDev.h b/PdfFile/lib/xpdf/OutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/OutputDev.h rename to PdfFile/lib/xpdf/OutputDev.h diff --git a/PdfReader/lib/xpdf/PDF417Barcode.cc b/PdfFile/lib/xpdf/PDF417Barcode.cc similarity index 100% rename from PdfReader/lib/xpdf/PDF417Barcode.cc rename to PdfFile/lib/xpdf/PDF417Barcode.cc diff --git a/PdfReader/lib/xpdf/PDF417Barcode.h b/PdfFile/lib/xpdf/PDF417Barcode.h similarity index 100% rename from PdfReader/lib/xpdf/PDF417Barcode.h rename to PdfFile/lib/xpdf/PDF417Barcode.h diff --git a/PdfReader/lib/xpdf/PDFCore.cc b/PdfFile/lib/xpdf/PDFCore.cc similarity index 100% rename from PdfReader/lib/xpdf/PDFCore.cc rename to PdfFile/lib/xpdf/PDFCore.cc diff --git a/PdfReader/lib/xpdf/PDFCore.h b/PdfFile/lib/xpdf/PDFCore.h similarity index 100% rename from PdfReader/lib/xpdf/PDFCore.h rename to PdfFile/lib/xpdf/PDFCore.h diff --git a/PdfReader/lib/xpdf/PDFDoc.cc b/PdfFile/lib/xpdf/PDFDoc.cc similarity index 100% rename from PdfReader/lib/xpdf/PDFDoc.cc rename to PdfFile/lib/xpdf/PDFDoc.cc diff --git a/PdfReader/lib/xpdf/PDFDoc.h b/PdfFile/lib/xpdf/PDFDoc.h similarity index 100% rename from PdfReader/lib/xpdf/PDFDoc.h rename to PdfFile/lib/xpdf/PDFDoc.h diff --git a/PdfReader/lib/xpdf/PDFDocEncoding.cc b/PdfFile/lib/xpdf/PDFDocEncoding.cc similarity index 100% rename from PdfReader/lib/xpdf/PDFDocEncoding.cc rename to PdfFile/lib/xpdf/PDFDocEncoding.cc diff --git a/PdfReader/lib/xpdf/PDFDocEncoding.h b/PdfFile/lib/xpdf/PDFDocEncoding.h similarity index 100% rename from PdfReader/lib/xpdf/PDFDocEncoding.h rename to PdfFile/lib/xpdf/PDFDocEncoding.h diff --git a/PdfReader/lib/xpdf/PSOutputDev.cc b/PdfFile/lib/xpdf/PSOutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/PSOutputDev.cc rename to PdfFile/lib/xpdf/PSOutputDev.cc diff --git a/PdfReader/lib/xpdf/PSOutputDev.h b/PdfFile/lib/xpdf/PSOutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/PSOutputDev.h rename to PdfFile/lib/xpdf/PSOutputDev.h diff --git a/PdfReader/lib/xpdf/PSTokenizer.cc b/PdfFile/lib/xpdf/PSTokenizer.cc similarity index 100% rename from PdfReader/lib/xpdf/PSTokenizer.cc rename to PdfFile/lib/xpdf/PSTokenizer.cc diff --git a/PdfReader/lib/xpdf/PSTokenizer.h b/PdfFile/lib/xpdf/PSTokenizer.h similarity index 100% rename from PdfReader/lib/xpdf/PSTokenizer.h rename to PdfFile/lib/xpdf/PSTokenizer.h diff --git a/PdfReader/lib/xpdf/Page.cc b/PdfFile/lib/xpdf/Page.cc similarity index 100% rename from PdfReader/lib/xpdf/Page.cc rename to PdfFile/lib/xpdf/Page.cc diff --git a/PdfReader/lib/xpdf/Page.h b/PdfFile/lib/xpdf/Page.h similarity index 100% rename from PdfReader/lib/xpdf/Page.h rename to PdfFile/lib/xpdf/Page.h diff --git a/PdfReader/lib/xpdf/Parser.cc b/PdfFile/lib/xpdf/Parser.cc similarity index 100% rename from PdfReader/lib/xpdf/Parser.cc rename to PdfFile/lib/xpdf/Parser.cc diff --git a/PdfReader/lib/xpdf/Parser.h b/PdfFile/lib/xpdf/Parser.h similarity index 100% rename from PdfReader/lib/xpdf/Parser.h rename to PdfFile/lib/xpdf/Parser.h diff --git a/PdfReader/lib/xpdf/PreScanOutputDev.cc b/PdfFile/lib/xpdf/PreScanOutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/PreScanOutputDev.cc rename to PdfFile/lib/xpdf/PreScanOutputDev.cc diff --git a/PdfReader/lib/xpdf/PreScanOutputDev.h b/PdfFile/lib/xpdf/PreScanOutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/PreScanOutputDev.h rename to PdfFile/lib/xpdf/PreScanOutputDev.h diff --git a/PdfReader/lib/xpdf/SecurityHandler.cc b/PdfFile/lib/xpdf/SecurityHandler.cc similarity index 100% rename from PdfReader/lib/xpdf/SecurityHandler.cc rename to PdfFile/lib/xpdf/SecurityHandler.cc diff --git a/PdfReader/lib/xpdf/SecurityHandler.h b/PdfFile/lib/xpdf/SecurityHandler.h similarity index 100% rename from PdfReader/lib/xpdf/SecurityHandler.h rename to PdfFile/lib/xpdf/SecurityHandler.h diff --git a/PdfReader/lib/xpdf/ShadingImage.cc b/PdfFile/lib/xpdf/ShadingImage.cc similarity index 100% rename from PdfReader/lib/xpdf/ShadingImage.cc rename to PdfFile/lib/xpdf/ShadingImage.cc diff --git a/PdfReader/lib/xpdf/ShadingImage.h b/PdfFile/lib/xpdf/ShadingImage.h similarity index 100% rename from PdfReader/lib/xpdf/ShadingImage.h rename to PdfFile/lib/xpdf/ShadingImage.h diff --git a/PdfReader/lib/xpdf/SplashOutputDev.cc b/PdfFile/lib/xpdf/SplashOutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/SplashOutputDev.cc rename to PdfFile/lib/xpdf/SplashOutputDev.cc diff --git a/PdfReader/lib/xpdf/SplashOutputDev.h b/PdfFile/lib/xpdf/SplashOutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/SplashOutputDev.h rename to PdfFile/lib/xpdf/SplashOutputDev.h diff --git a/PdfReader/lib/xpdf/Stream-CCITT.h b/PdfFile/lib/xpdf/Stream-CCITT.h similarity index 100% rename from PdfReader/lib/xpdf/Stream-CCITT.h rename to PdfFile/lib/xpdf/Stream-CCITT.h diff --git a/PdfReader/lib/xpdf/Stream.cc b/PdfFile/lib/xpdf/Stream.cc similarity index 99% rename from PdfReader/lib/xpdf/Stream.cc rename to PdfFile/lib/xpdf/Stream.cc index 1992ab30d4..32c85e18f3 100644 --- a/PdfReader/lib/xpdf/Stream.cc +++ b/PdfFile/lib/xpdf/Stream.cc @@ -40,7 +40,7 @@ #include "Stream-CCITT.h" #ifdef USE_EXTERNAL_JPEG2000 -#include "../../Src/JPXStream2.h" +#include "../../SrcReader/JPXStream2.h" #endif #ifdef __DJGPP__ diff --git a/PdfReader/lib/xpdf/Stream.h b/PdfFile/lib/xpdf/Stream.h similarity index 100% rename from PdfReader/lib/xpdf/Stream.h rename to PdfFile/lib/xpdf/Stream.h diff --git a/PdfReader/lib/xpdf/TextOutputDev.cc b/PdfFile/lib/xpdf/TextOutputDev.cc similarity index 100% rename from PdfReader/lib/xpdf/TextOutputDev.cc rename to PdfFile/lib/xpdf/TextOutputDev.cc diff --git a/PdfReader/lib/xpdf/TextOutputDev.h b/PdfFile/lib/xpdf/TextOutputDev.h similarity index 100% rename from PdfReader/lib/xpdf/TextOutputDev.h rename to PdfFile/lib/xpdf/TextOutputDev.h diff --git a/PdfReader/lib/xpdf/TextString.cc b/PdfFile/lib/xpdf/TextString.cc similarity index 100% rename from PdfReader/lib/xpdf/TextString.cc rename to PdfFile/lib/xpdf/TextString.cc diff --git a/PdfReader/lib/xpdf/TextString.h b/PdfFile/lib/xpdf/TextString.h similarity index 100% rename from PdfReader/lib/xpdf/TextString.h rename to PdfFile/lib/xpdf/TextString.h diff --git a/PdfReader/lib/xpdf/TileCache.cc b/PdfFile/lib/xpdf/TileCache.cc similarity index 100% rename from PdfReader/lib/xpdf/TileCache.cc rename to PdfFile/lib/xpdf/TileCache.cc diff --git a/PdfReader/lib/xpdf/TileCache.h b/PdfFile/lib/xpdf/TileCache.h similarity index 100% rename from PdfReader/lib/xpdf/TileCache.h rename to PdfFile/lib/xpdf/TileCache.h diff --git a/PdfReader/lib/xpdf/TileCompositor.cc b/PdfFile/lib/xpdf/TileCompositor.cc similarity index 100% rename from PdfReader/lib/xpdf/TileCompositor.cc rename to PdfFile/lib/xpdf/TileCompositor.cc diff --git a/PdfReader/lib/xpdf/TileCompositor.h b/PdfFile/lib/xpdf/TileCompositor.h similarity index 100% rename from PdfReader/lib/xpdf/TileCompositor.h rename to PdfFile/lib/xpdf/TileCompositor.h diff --git a/PdfReader/lib/xpdf/TileMap.cc b/PdfFile/lib/xpdf/TileMap.cc similarity index 100% rename from PdfReader/lib/xpdf/TileMap.cc rename to PdfFile/lib/xpdf/TileMap.cc diff --git a/PdfReader/lib/xpdf/TileMap.h b/PdfFile/lib/xpdf/TileMap.h similarity index 100% rename from PdfReader/lib/xpdf/TileMap.h rename to PdfFile/lib/xpdf/TileMap.h diff --git a/PdfReader/lib/xpdf/UTF8.cc b/PdfFile/lib/xpdf/UTF8.cc similarity index 100% rename from PdfReader/lib/xpdf/UTF8.cc rename to PdfFile/lib/xpdf/UTF8.cc diff --git a/PdfReader/lib/xpdf/UTF8.h b/PdfFile/lib/xpdf/UTF8.h similarity index 100% rename from PdfReader/lib/xpdf/UTF8.h rename to PdfFile/lib/xpdf/UTF8.h diff --git a/PdfReader/lib/xpdf/UnicodeMap.cc b/PdfFile/lib/xpdf/UnicodeMap.cc similarity index 100% rename from PdfReader/lib/xpdf/UnicodeMap.cc rename to PdfFile/lib/xpdf/UnicodeMap.cc diff --git a/PdfReader/lib/xpdf/UnicodeMap.h b/PdfFile/lib/xpdf/UnicodeMap.h similarity index 100% rename from PdfReader/lib/xpdf/UnicodeMap.h rename to PdfFile/lib/xpdf/UnicodeMap.h diff --git a/PdfReader/lib/xpdf/UnicodeMapTables.h b/PdfFile/lib/xpdf/UnicodeMapTables.h similarity index 100% rename from PdfReader/lib/xpdf/UnicodeMapTables.h rename to PdfFile/lib/xpdf/UnicodeMapTables.h diff --git a/PdfReader/lib/xpdf/UnicodeRemapping.cc b/PdfFile/lib/xpdf/UnicodeRemapping.cc similarity index 100% rename from PdfReader/lib/xpdf/UnicodeRemapping.cc rename to PdfFile/lib/xpdf/UnicodeRemapping.cc diff --git a/PdfReader/lib/xpdf/UnicodeRemapping.h b/PdfFile/lib/xpdf/UnicodeRemapping.h similarity index 100% rename from PdfReader/lib/xpdf/UnicodeRemapping.h rename to PdfFile/lib/xpdf/UnicodeRemapping.h diff --git a/PdfReader/lib/xpdf/UnicodeTypeTable.cc b/PdfFile/lib/xpdf/UnicodeTypeTable.cc similarity index 100% rename from PdfReader/lib/xpdf/UnicodeTypeTable.cc rename to PdfFile/lib/xpdf/UnicodeTypeTable.cc diff --git a/PdfReader/lib/xpdf/UnicodeTypeTable.h b/PdfFile/lib/xpdf/UnicodeTypeTable.h similarity index 100% rename from PdfReader/lib/xpdf/UnicodeTypeTable.h rename to PdfFile/lib/xpdf/UnicodeTypeTable.h diff --git a/PdfReader/lib/xpdf/WebFont.cc b/PdfFile/lib/xpdf/WebFont.cc similarity index 100% rename from PdfReader/lib/xpdf/WebFont.cc rename to PdfFile/lib/xpdf/WebFont.cc diff --git a/PdfReader/lib/xpdf/WebFont.h b/PdfFile/lib/xpdf/WebFont.h similarity index 100% rename from PdfReader/lib/xpdf/WebFont.h rename to PdfFile/lib/xpdf/WebFont.h diff --git a/PdfReader/lib/xpdf/XFAScanner.cc b/PdfFile/lib/xpdf/XFAScanner.cc similarity index 100% rename from PdfReader/lib/xpdf/XFAScanner.cc rename to PdfFile/lib/xpdf/XFAScanner.cc diff --git a/PdfReader/lib/xpdf/XFAScanner.h b/PdfFile/lib/xpdf/XFAScanner.h similarity index 100% rename from PdfReader/lib/xpdf/XFAScanner.h rename to PdfFile/lib/xpdf/XFAScanner.h diff --git a/PdfReader/lib/xpdf/XRef.cc b/PdfFile/lib/xpdf/XRef.cc similarity index 100% rename from PdfReader/lib/xpdf/XRef.cc rename to PdfFile/lib/xpdf/XRef.cc diff --git a/PdfReader/lib/xpdf/XRef.h b/PdfFile/lib/xpdf/XRef.h similarity index 100% rename from PdfReader/lib/xpdf/XRef.h rename to PdfFile/lib/xpdf/XRef.h diff --git a/PdfReader/lib/xpdf/Zoox.cc b/PdfFile/lib/xpdf/Zoox.cc similarity index 100% rename from PdfReader/lib/xpdf/Zoox.cc rename to PdfFile/lib/xpdf/Zoox.cc diff --git a/PdfReader/lib/xpdf/Zoox.h b/PdfFile/lib/xpdf/Zoox.h similarity index 100% rename from PdfReader/lib/xpdf/Zoox.h rename to PdfFile/lib/xpdf/Zoox.h diff --git a/PdfReader/lib/xpdf/config.h b/PdfFile/lib/xpdf/config.h similarity index 100% rename from PdfReader/lib/xpdf/config.h rename to PdfFile/lib/xpdf/config.h diff --git a/PdfReader/lib/xpdf/pdfdetach.cc b/PdfFile/lib/xpdf/pdfdetach.cc similarity index 100% rename from PdfReader/lib/xpdf/pdfdetach.cc rename to PdfFile/lib/xpdf/pdfdetach.cc diff --git a/PdfReader/lib/xpdf/pdffonts.cc b/PdfFile/lib/xpdf/pdffonts.cc similarity index 100% rename from PdfReader/lib/xpdf/pdffonts.cc rename to PdfFile/lib/xpdf/pdffonts.cc diff --git a/PdfReader/lib/xpdf/pdfimages.cc b/PdfFile/lib/xpdf/pdfimages.cc similarity index 100% rename from PdfReader/lib/xpdf/pdfimages.cc rename to PdfFile/lib/xpdf/pdfimages.cc diff --git a/PdfReader/lib/xpdf/pdfinfo.cc b/PdfFile/lib/xpdf/pdfinfo.cc similarity index 100% rename from PdfReader/lib/xpdf/pdfinfo.cc rename to PdfFile/lib/xpdf/pdfinfo.cc diff --git a/PdfReader/lib/xpdf/pdftohtml.cc b/PdfFile/lib/xpdf/pdftohtml.cc similarity index 100% rename from PdfReader/lib/xpdf/pdftohtml.cc rename to PdfFile/lib/xpdf/pdftohtml.cc diff --git a/PdfReader/lib/xpdf/pdftopng.cc b/PdfFile/lib/xpdf/pdftopng.cc similarity index 100% rename from PdfReader/lib/xpdf/pdftopng.cc rename to PdfFile/lib/xpdf/pdftopng.cc diff --git a/PdfReader/lib/xpdf/pdftoppm.cc b/PdfFile/lib/xpdf/pdftoppm.cc similarity index 100% rename from PdfReader/lib/xpdf/pdftoppm.cc rename to PdfFile/lib/xpdf/pdftoppm.cc diff --git a/PdfReader/lib/xpdf/pdftops.cc b/PdfFile/lib/xpdf/pdftops.cc similarity index 100% rename from PdfReader/lib/xpdf/pdftops.cc rename to PdfFile/lib/xpdf/pdftops.cc diff --git a/PdfReader/lib/xpdf/pdftotext.cc b/PdfFile/lib/xpdf/pdftotext.cc similarity index 100% rename from PdfReader/lib/xpdf/pdftotext.cc rename to PdfFile/lib/xpdf/pdftotext.cc diff --git a/PdfReader/Mac/PdfReader.xcodeproj/project.pbxproj b/PdfReader/Mac/PdfReader.xcodeproj/project.pbxproj deleted file mode 100644 index 14bc345ae2..0000000000 --- a/PdfReader/Mac/PdfReader.xcodeproj/project.pbxproj +++ /dev/null @@ -1,570 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 6967B1E91E27BD4000A129E2 /* PdfReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1E71E27BD4000A129E2 /* PdfReader.cpp */; }; - 6967B2461E27BD4A00A129E2 /* Annot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1EB1E27BD4A00A129E2 /* Annot.cpp */; }; - 6967B2471E27BD4A00A129E2 /* Array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1ED1E27BD4A00A129E2 /* Array.cpp */; }; - 6967B2481E27BD4A00A129E2 /* Catalog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1F11E27BD4A00A129E2 /* Catalog.cpp */; }; - 6967B2491E27BD4A00A129E2 /* CharCodeToUnicode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1F41E27BD4A00A129E2 /* CharCodeToUnicode.cpp */; }; - 6967B24A1E27BD4A00A129E2 /* CMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1F71E27BD4A00A129E2 /* CMap.cpp */; }; - 6967B24B1E27BD4A00A129E2 /* Decrypt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1FA1E27BD4A00A129E2 /* Decrypt.cpp */; }; - 6967B24C1E27BD4A00A129E2 /* Dict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B1FC1E27BD4A00A129E2 /* Dict.cpp */; }; - 6967B24D1E27BD4A00A129E2 /* ExtractImageOutputDev.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2001E27BD4A00A129E2 /* ExtractImageOutputDev.cpp */; }; - 6967B24E1E27BD4A00A129E2 /* FontFileBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2031E27BD4A00A129E2 /* FontFileBase.cpp */; }; - 6967B24F1E27BD4A00A129E2 /* FontFileTrueType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2061E27BD4A00A129E2 /* FontFileTrueType.cpp */; }; - 6967B2501E27BD4A00A129E2 /* FontFileType1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2081E27BD4A00A129E2 /* FontFileType1.cpp */; }; - 6967B2511E27BD4A00A129E2 /* FontFileType1C.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B20A1E27BD4A00A129E2 /* FontFileType1C.cpp */; }; - 6967B2521E27BD4A00A129E2 /* Function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B20C1E27BD4A00A129E2 /* Function.cpp */; }; - 6967B2531E27BD4A00A129E2 /* GFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B20E1E27BD4A00A129E2 /* GFont.cpp */; }; - 6967B2541E27BD4A00A129E2 /* GlobalParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2101E27BD4A00A129E2 /* GlobalParams.cpp */; }; - 6967B2551E27BD4A00A129E2 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2121E27BD4A00A129E2 /* Graphics.cpp */; }; - 6967B2561E27BD4A00A129E2 /* GState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2141E27BD4A00A129E2 /* GState.cpp */; }; - 6967B2571E27BD4A00A129E2 /* Hash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2161E27BD4A00A129E2 /* Hash.cpp */; }; - 6967B2581E27BD4A00A129E2 /* JArithmeticDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2181E27BD4A00A129E2 /* JArithmeticDecoder.cpp */; }; - 6967B2591E27BD4A00A129E2 /* JBIG2Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B21A1E27BD4A00A129E2 /* JBIG2Stream.cpp */; }; - 6967B25A1E27BD4A00A129E2 /* JPXStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B21C1E27BD4A00A129E2 /* JPXStream.cpp */; }; - 6967B25B1E27BD4A00A129E2 /* Lexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B21E1E27BD4A00A129E2 /* Lexer.cpp */; }; - 6967B25C1E27BD4A00A129E2 /* Link.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2201E27BD4A00A129E2 /* Link.cpp */; }; - 6967B25D1E27BD4A00A129E2 /* List.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2221E27BD4A00A129E2 /* List.cpp */; }; - 6967B25E1E27BD4A00A129E2 /* NameToCharCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2251E27BD4A00A129E2 /* NameToCharCode.cpp */; }; - 6967B25F1E27BD4A00A129E2 /* Object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2281E27BD4A00A129E2 /* Object.cpp */; }; - 6967B2601E27BD4A00A129E2 /* Outline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B22A1E27BD4A00A129E2 /* Outline.cpp */; }; - 6967B2611E27BD4A00A129E2 /* OutputDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B22C1E27BD4A00A129E2 /* OutputDevice.cpp */; }; - 6967B2621E27BD4A00A129E2 /* Page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B22E1E27BD4A00A129E2 /* Page.cpp */; }; - 6967B2631E27BD4A00A129E2 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2301E27BD4A00A129E2 /* Parser.cpp */; }; - 6967B2641E27BD4A00A129E2 /* PDFDoc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2321E27BD4A00A129E2 /* PDFDoc.cpp */; }; - 6967B2651E27BD4A00A129E2 /* PSLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2351E27BD4A00A129E2 /* PSLexer.cpp */; }; - 6967B2661E27BD4A00A129E2 /* RendererOutputDev.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2371E27BD4A00A129E2 /* RendererOutputDev.cpp */; }; - 6967B2671E27BD4A00A129E2 /* SecurityHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2391E27BD4A00A129E2 /* SecurityHandler.cpp */; }; - 6967B2681E27BD4A00A129E2 /* Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B23B1E27BD4A00A129E2 /* Stream.cpp */; }; - 6967B2691E27BD4A00A129E2 /* StringExt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B23D1E27BD4A00A129E2 /* StringExt.cpp */; }; - 6967B26A1E27BD4A00A129E2 /* UnicodeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B23F1E27BD4A00A129E2 /* UnicodeMap.cpp */; }; - 6967B26B1E27BD4A00A129E2 /* XRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6967B2441E27BD4A00A129E2 /* XRef.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 6967B1D91E27BD1D00A129E2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 6967B1DB1E27BD1D00A129E2 /* libPdfReader.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPdfReader.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6967B1E71E27BD4000A129E2 /* PdfReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PdfReader.cpp; path = ../../PdfReader.cpp; sourceTree = ""; }; - 6967B1E81E27BD4000A129E2 /* PdfReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PdfReader.h; path = ../../PdfReader.h; sourceTree = ""; }; - 6967B1EB1E27BD4A00A129E2 /* Annot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Annot.cpp; sourceTree = ""; }; - 6967B1EC1E27BD4A00A129E2 /* Annot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Annot.h; sourceTree = ""; }; - 6967B1ED1E27BD4A00A129E2 /* Array.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Array.cpp; sourceTree = ""; }; - 6967B1EE1E27BD4A00A129E2 /* Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Array.h; sourceTree = ""; }; - 6967B1EF1E27BD4A00A129E2 /* BuiltinFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinFont.h; sourceTree = ""; }; - 6967B1F01E27BD4A00A129E2 /* BuiltinFontTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinFontTables.h; sourceTree = ""; }; - 6967B1F11E27BD4A00A129E2 /* Catalog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Catalog.cpp; sourceTree = ""; }; - 6967B1F21E27BD4A00A129E2 /* Catalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Catalog.h; sourceTree = ""; }; - 6967B1F31E27BD4A00A129E2 /* CCITT-Tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CCITT-Tables.h"; sourceTree = ""; }; - 6967B1F41E27BD4A00A129E2 /* CharCodeToUnicode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharCodeToUnicode.cpp; sourceTree = ""; }; - 6967B1F51E27BD4A00A129E2 /* CharCodeToUnicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharCodeToUnicode.h; sourceTree = ""; }; - 6967B1F61E27BD4A00A129E2 /* CharTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharTypes.h; sourceTree = ""; }; - 6967B1F71E27BD4A00A129E2 /* CMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CMap.cpp; sourceTree = ""; }; - 6967B1F81E27BD4A00A129E2 /* CMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMap.h; sourceTree = ""; }; - 6967B1F91E27BD4A00A129E2 /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = ""; }; - 6967B1FA1E27BD4A00A129E2 /* Decrypt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decrypt.cpp; sourceTree = ""; }; - 6967B1FB1E27BD4A00A129E2 /* Decrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Decrypt.h; sourceTree = ""; }; - 6967B1FC1E27BD4A00A129E2 /* Dict.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dict.cpp; sourceTree = ""; }; - 6967B1FD1E27BD4A00A129E2 /* Dict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dict.h; sourceTree = ""; }; - 6967B1FE1E27BD4A00A129E2 /* EncodingTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodingTables.h; sourceTree = ""; }; - 6967B1FF1E27BD4A00A129E2 /* ErrorConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorConstants.h; sourceTree = ""; }; - 6967B2001E27BD4A00A129E2 /* ExtractImageOutputDev.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtractImageOutputDev.cpp; sourceTree = ""; }; - 6967B2011E27BD4A00A129E2 /* ExtractImageOutputDev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtractImageOutputDev.h; sourceTree = ""; }; - 6967B2021E27BD4A00A129E2 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = ""; }; - 6967B2031E27BD4A00A129E2 /* FontFileBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFileBase.cpp; sourceTree = ""; }; - 6967B2041E27BD4A00A129E2 /* FontFileBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFileBase.h; sourceTree = ""; }; - 6967B2051E27BD4A00A129E2 /* FontFileEncodings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFileEncodings.h; sourceTree = ""; }; - 6967B2061E27BD4A00A129E2 /* FontFileTrueType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFileTrueType.cpp; sourceTree = ""; }; - 6967B2071E27BD4A00A129E2 /* FontFileTrueType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFileTrueType.h; sourceTree = ""; }; - 6967B2081E27BD4A00A129E2 /* FontFileType1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFileType1.cpp; sourceTree = ""; }; - 6967B2091E27BD4A00A129E2 /* FontFileType1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFileType1.h; sourceTree = ""; }; - 6967B20A1E27BD4A00A129E2 /* FontFileType1C.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontFileType1C.cpp; sourceTree = ""; }; - 6967B20B1E27BD4A00A129E2 /* FontFileType1C.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontFileType1C.h; sourceTree = ""; }; - 6967B20C1E27BD4A00A129E2 /* Function.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Function.cpp; sourceTree = ""; }; - 6967B20D1E27BD4A00A129E2 /* Function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Function.h; sourceTree = ""; }; - 6967B20E1E27BD4A00A129E2 /* GFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GFont.cpp; sourceTree = ""; }; - 6967B20F1E27BD4A00A129E2 /* GFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GFont.h; sourceTree = ""; }; - 6967B2101E27BD4A00A129E2 /* GlobalParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalParams.cpp; sourceTree = ""; }; - 6967B2111E27BD4A00A129E2 /* GlobalParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalParams.h; sourceTree = ""; }; - 6967B2121E27BD4A00A129E2 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = ""; }; - 6967B2131E27BD4A00A129E2 /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = ""; }; - 6967B2141E27BD4A00A129E2 /* GState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GState.cpp; sourceTree = ""; }; - 6967B2151E27BD4A00A129E2 /* GState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GState.h; sourceTree = ""; }; - 6967B2161E27BD4A00A129E2 /* Hash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hash.cpp; sourceTree = ""; }; - 6967B2171E27BD4A00A129E2 /* Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hash.h; sourceTree = ""; }; - 6967B2181E27BD4A00A129E2 /* JArithmeticDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JArithmeticDecoder.cpp; sourceTree = ""; }; - 6967B2191E27BD4A00A129E2 /* JArithmeticDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JArithmeticDecoder.h; sourceTree = ""; }; - 6967B21A1E27BD4A00A129E2 /* JBIG2Stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JBIG2Stream.cpp; sourceTree = ""; }; - 6967B21B1E27BD4A00A129E2 /* JBIG2Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JBIG2Stream.h; sourceTree = ""; }; - 6967B21C1E27BD4A00A129E2 /* JPXStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JPXStream.cpp; sourceTree = ""; }; - 6967B21D1E27BD4A00A129E2 /* JPXStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JPXStream.h; sourceTree = ""; }; - 6967B21E1E27BD4A00A129E2 /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = ""; }; - 6967B21F1E27BD4A00A129E2 /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = ""; }; - 6967B2201E27BD4A00A129E2 /* Link.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Link.cpp; sourceTree = ""; }; - 6967B2211E27BD4A00A129E2 /* Link.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Link.h; sourceTree = ""; }; - 6967B2221E27BD4A00A129E2 /* List.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = List.cpp; sourceTree = ""; }; - 6967B2231E27BD4A00A129E2 /* List.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = List.h; sourceTree = ""; }; - 6967B2241E27BD4A00A129E2 /* MemoryUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryUtils.h; sourceTree = ""; }; - 6967B2251E27BD4A00A129E2 /* NameToCharCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameToCharCode.cpp; sourceTree = ""; }; - 6967B2261E27BD4A00A129E2 /* NameToCharCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameToCharCode.h; sourceTree = ""; }; - 6967B2271E27BD4A00A129E2 /* NameToUnicodeTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameToUnicodeTable.h; sourceTree = ""; }; - 6967B2281E27BD4A00A129E2 /* Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = ""; }; - 6967B2291E27BD4A00A129E2 /* Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Object.h; sourceTree = ""; }; - 6967B22A1E27BD4A00A129E2 /* Outline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Outline.cpp; sourceTree = ""; }; - 6967B22B1E27BD4A00A129E2 /* Outline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Outline.h; sourceTree = ""; }; - 6967B22C1E27BD4A00A129E2 /* OutputDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputDevice.cpp; sourceTree = ""; }; - 6967B22D1E27BD4A00A129E2 /* OutputDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputDevice.h; sourceTree = ""; }; - 6967B22E1E27BD4A00A129E2 /* Page.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Page.cpp; sourceTree = ""; }; - 6967B22F1E27BD4A00A129E2 /* Page.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Page.h; sourceTree = ""; }; - 6967B2301E27BD4A00A129E2 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = ""; }; - 6967B2311E27BD4A00A129E2 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = ""; }; - 6967B2321E27BD4A00A129E2 /* PDFDoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PDFDoc.cpp; sourceTree = ""; }; - 6967B2331E27BD4A00A129E2 /* PDFDoc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFDoc.h; sourceTree = ""; }; - 6967B2341E27BD4A00A129E2 /* PDFDocEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFDocEncoding.h; sourceTree = ""; }; - 6967B2351E27BD4A00A129E2 /* PSLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PSLexer.cpp; sourceTree = ""; }; - 6967B2361E27BD4A00A129E2 /* PSLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSLexer.h; sourceTree = ""; }; - 6967B2371E27BD4A00A129E2 /* RendererOutputDev.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RendererOutputDev.cpp; sourceTree = ""; }; - 6967B2381E27BD4A00A129E2 /* RendererOutputDev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RendererOutputDev.h; sourceTree = ""; }; - 6967B2391E27BD4A00A129E2 /* SecurityHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecurityHandler.cpp; sourceTree = ""; }; - 6967B23A1E27BD4A00A129E2 /* SecurityHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityHandler.h; sourceTree = ""; }; - 6967B23B1E27BD4A00A129E2 /* Stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stream.cpp; sourceTree = ""; }; - 6967B23C1E27BD4A00A129E2 /* Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stream.h; sourceTree = ""; }; - 6967B23D1E27BD4A00A129E2 /* StringExt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringExt.cpp; sourceTree = ""; }; - 6967B23E1E27BD4A00A129E2 /* StringExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringExt.h; sourceTree = ""; }; - 6967B23F1E27BD4A00A129E2 /* UnicodeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnicodeMap.cpp; sourceTree = ""; }; - 6967B2401E27BD4A00A129E2 /* UnicodeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeMap.h; sourceTree = ""; }; - 6967B2411E27BD4A00A129E2 /* UnicodeMapTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeMapTables.h; sourceTree = ""; }; - 6967B2421E27BD4A00A129E2 /* UTF8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTF8.h; sourceTree = ""; }; - 6967B2431E27BD4A00A129E2 /* XmlUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlUtils.h; sourceTree = ""; }; - 6967B2441E27BD4A00A129E2 /* XRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XRef.cpp; sourceTree = ""; }; - 6967B2451E27BD4A00A129E2 /* XRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XRef.h; sourceTree = ""; }; - 6967B26D1E27BD5100A129E2 /* Fontd050000l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontd050000l.h; sourceTree = ""; }; - 6967B26E1E27BD5100A129E2 /* Fontn019003l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn019003l.h; sourceTree = ""; }; - 6967B26F1E27BD5100A129E2 /* Fontn019004l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn019004l.h; sourceTree = ""; }; - 6967B2701E27BD5100A129E2 /* Fontn019023l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn019023l.h; sourceTree = ""; }; - 6967B2711E27BD5100A129E2 /* Fontn019024l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn019024l.h; sourceTree = ""; }; - 6967B2721E27BD5100A129E2 /* Fontn021003l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn021003l.h; sourceTree = ""; }; - 6967B2731E27BD5100A129E2 /* Fontn021004l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn021004l.h; sourceTree = ""; }; - 6967B2741E27BD5100A129E2 /* Fontn021023l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn021023l.h; sourceTree = ""; }; - 6967B2751E27BD5100A129E2 /* Fontn021024l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn021024l.h; sourceTree = ""; }; - 6967B2761E27BD5100A129E2 /* Fontn022003l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn022003l.h; sourceTree = ""; }; - 6967B2771E27BD5100A129E2 /* Fontn022004l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn022004l.h; sourceTree = ""; }; - 6967B2781E27BD5100A129E2 /* Fontn022023l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn022023l.h; sourceTree = ""; }; - 6967B2791E27BD5100A129E2 /* Fontn022024l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fontn022024l.h; sourceTree = ""; }; - 6967B2A71E27BD5100A129E2 /* Fonts050000l.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fonts050000l.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6967B1D81E27BD1D00A129E2 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6967B1D21E27BD1D00A129E2 = { - isa = PBXGroup; - children = ( - 6967B1DD1E27BD1D00A129E2 /* PdfReader */, - 6967B1DC1E27BD1D00A129E2 /* Products */, - ); - sourceTree = ""; - }; - 6967B1DC1E27BD1D00A129E2 /* Products */ = { - isa = PBXGroup; - children = ( - 6967B1DB1E27BD1D00A129E2 /* libPdfReader.a */, - ); - name = Products; - sourceTree = ""; - }; - 6967B1DD1E27BD1D00A129E2 /* PdfReader */ = { - isa = PBXGroup; - children = ( - 6967B1E71E27BD4000A129E2 /* PdfReader.cpp */, - 6967B1E81E27BD4000A129E2 /* PdfReader.h */, - 6967B26C1E27BD5100A129E2 /* Resources */, - 6967B1EA1E27BD4A00A129E2 /* Src */, - ); - path = PdfReader; - sourceTree = ""; - }; - 6967B1EA1E27BD4A00A129E2 /* Src */ = { - isa = PBXGroup; - children = ( - 6967B1EB1E27BD4A00A129E2 /* Annot.cpp */, - 6967B1EC1E27BD4A00A129E2 /* Annot.h */, - 6967B1ED1E27BD4A00A129E2 /* Array.cpp */, - 6967B1EE1E27BD4A00A129E2 /* Array.h */, - 6967B1EF1E27BD4A00A129E2 /* BuiltinFont.h */, - 6967B1F01E27BD4A00A129E2 /* BuiltinFontTables.h */, - 6967B1F11E27BD4A00A129E2 /* Catalog.cpp */, - 6967B1F21E27BD4A00A129E2 /* Catalog.h */, - 6967B1F31E27BD4A00A129E2 /* CCITT-Tables.h */, - 6967B1F41E27BD4A00A129E2 /* CharCodeToUnicode.cpp */, - 6967B1F51E27BD4A00A129E2 /* CharCodeToUnicode.h */, - 6967B1F61E27BD4A00A129E2 /* CharTypes.h */, - 6967B1F71E27BD4A00A129E2 /* CMap.cpp */, - 6967B1F81E27BD4A00A129E2 /* CMap.h */, - 6967B1F91E27BD4A00A129E2 /* Constants.h */, - 6967B1FA1E27BD4A00A129E2 /* Decrypt.cpp */, - 6967B1FB1E27BD4A00A129E2 /* Decrypt.h */, - 6967B1FC1E27BD4A00A129E2 /* Dict.cpp */, - 6967B1FD1E27BD4A00A129E2 /* Dict.h */, - 6967B1FE1E27BD4A00A129E2 /* EncodingTables.h */, - 6967B1FF1E27BD4A00A129E2 /* ErrorConstants.h */, - 6967B2001E27BD4A00A129E2 /* ExtractImageOutputDev.cpp */, - 6967B2011E27BD4A00A129E2 /* ExtractImageOutputDev.h */, - 6967B2021E27BD4A00A129E2 /* File.h */, - 6967B2031E27BD4A00A129E2 /* FontFileBase.cpp */, - 6967B2041E27BD4A00A129E2 /* FontFileBase.h */, - 6967B2051E27BD4A00A129E2 /* FontFileEncodings.h */, - 6967B2061E27BD4A00A129E2 /* FontFileTrueType.cpp */, - 6967B2071E27BD4A00A129E2 /* FontFileTrueType.h */, - 6967B2081E27BD4A00A129E2 /* FontFileType1.cpp */, - 6967B2091E27BD4A00A129E2 /* FontFileType1.h */, - 6967B20A1E27BD4A00A129E2 /* FontFileType1C.cpp */, - 6967B20B1E27BD4A00A129E2 /* FontFileType1C.h */, - 6967B20C1E27BD4A00A129E2 /* Function.cpp */, - 6967B20D1E27BD4A00A129E2 /* Function.h */, - 6967B20E1E27BD4A00A129E2 /* GFont.cpp */, - 6967B20F1E27BD4A00A129E2 /* GFont.h */, - 6967B2101E27BD4A00A129E2 /* GlobalParams.cpp */, - 6967B2111E27BD4A00A129E2 /* GlobalParams.h */, - 6967B2121E27BD4A00A129E2 /* Graphics.cpp */, - 6967B2131E27BD4A00A129E2 /* Graphics.h */, - 6967B2141E27BD4A00A129E2 /* GState.cpp */, - 6967B2151E27BD4A00A129E2 /* GState.h */, - 6967B2161E27BD4A00A129E2 /* Hash.cpp */, - 6967B2171E27BD4A00A129E2 /* Hash.h */, - 6967B2181E27BD4A00A129E2 /* JArithmeticDecoder.cpp */, - 6967B2191E27BD4A00A129E2 /* JArithmeticDecoder.h */, - 6967B21A1E27BD4A00A129E2 /* JBIG2Stream.cpp */, - 6967B21B1E27BD4A00A129E2 /* JBIG2Stream.h */, - 6967B21C1E27BD4A00A129E2 /* JPXStream.cpp */, - 6967B21D1E27BD4A00A129E2 /* JPXStream.h */, - 6967B21E1E27BD4A00A129E2 /* Lexer.cpp */, - 6967B21F1E27BD4A00A129E2 /* Lexer.h */, - 6967B2201E27BD4A00A129E2 /* Link.cpp */, - 6967B2211E27BD4A00A129E2 /* Link.h */, - 6967B2221E27BD4A00A129E2 /* List.cpp */, - 6967B2231E27BD4A00A129E2 /* List.h */, - 6967B2241E27BD4A00A129E2 /* MemoryUtils.h */, - 6967B2251E27BD4A00A129E2 /* NameToCharCode.cpp */, - 6967B2261E27BD4A00A129E2 /* NameToCharCode.h */, - 6967B2271E27BD4A00A129E2 /* NameToUnicodeTable.h */, - 6967B2281E27BD4A00A129E2 /* Object.cpp */, - 6967B2291E27BD4A00A129E2 /* Object.h */, - 6967B22A1E27BD4A00A129E2 /* Outline.cpp */, - 6967B22B1E27BD4A00A129E2 /* Outline.h */, - 6967B22C1E27BD4A00A129E2 /* OutputDevice.cpp */, - 6967B22D1E27BD4A00A129E2 /* OutputDevice.h */, - 6967B22E1E27BD4A00A129E2 /* Page.cpp */, - 6967B22F1E27BD4A00A129E2 /* Page.h */, - 6967B2301E27BD4A00A129E2 /* Parser.cpp */, - 6967B2311E27BD4A00A129E2 /* Parser.h */, - 6967B2321E27BD4A00A129E2 /* PDFDoc.cpp */, - 6967B2331E27BD4A00A129E2 /* PDFDoc.h */, - 6967B2341E27BD4A00A129E2 /* PDFDocEncoding.h */, - 6967B2351E27BD4A00A129E2 /* PSLexer.cpp */, - 6967B2361E27BD4A00A129E2 /* PSLexer.h */, - 6967B2371E27BD4A00A129E2 /* RendererOutputDev.cpp */, - 6967B2381E27BD4A00A129E2 /* RendererOutputDev.h */, - 6967B2391E27BD4A00A129E2 /* SecurityHandler.cpp */, - 6967B23A1E27BD4A00A129E2 /* SecurityHandler.h */, - 6967B23B1E27BD4A00A129E2 /* Stream.cpp */, - 6967B23C1E27BD4A00A129E2 /* Stream.h */, - 6967B23D1E27BD4A00A129E2 /* StringExt.cpp */, - 6967B23E1E27BD4A00A129E2 /* StringExt.h */, - 6967B23F1E27BD4A00A129E2 /* UnicodeMap.cpp */, - 6967B2401E27BD4A00A129E2 /* UnicodeMap.h */, - 6967B2411E27BD4A00A129E2 /* UnicodeMapTables.h */, - 6967B2421E27BD4A00A129E2 /* UTF8.h */, - 6967B2431E27BD4A00A129E2 /* XmlUtils.h */, - 6967B2441E27BD4A00A129E2 /* XRef.cpp */, - 6967B2451E27BD4A00A129E2 /* XRef.h */, - ); - name = Src; - path = ../../Src; - sourceTree = ""; - }; - 6967B26C1E27BD5100A129E2 /* Resources */ = { - isa = PBXGroup; - children = ( - 6967B26D1E27BD5100A129E2 /* Fontd050000l.h */, - 6967B26E1E27BD5100A129E2 /* Fontn019003l.h */, - 6967B26F1E27BD5100A129E2 /* Fontn019004l.h */, - 6967B2701E27BD5100A129E2 /* Fontn019023l.h */, - 6967B2711E27BD5100A129E2 /* Fontn019024l.h */, - 6967B2721E27BD5100A129E2 /* Fontn021003l.h */, - 6967B2731E27BD5100A129E2 /* Fontn021004l.h */, - 6967B2741E27BD5100A129E2 /* Fontn021023l.h */, - 6967B2751E27BD5100A129E2 /* Fontn021024l.h */, - 6967B2761E27BD5100A129E2 /* Fontn022003l.h */, - 6967B2771E27BD5100A129E2 /* Fontn022004l.h */, - 6967B2781E27BD5100A129E2 /* Fontn022023l.h */, - 6967B2791E27BD5100A129E2 /* Fontn022024l.h */, - 6967B2A71E27BD5100A129E2 /* Fonts050000l.h */, - ); - name = Resources; - path = ../../Resources; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6967B1DA1E27BD1D00A129E2 /* PdfReader */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6967B1E41E27BD1D00A129E2 /* Build configuration list for PBXNativeTarget "PdfReader" */; - buildPhases = ( - 6967B1D71E27BD1D00A129E2 /* Sources */, - 6967B1D81E27BD1D00A129E2 /* Frameworks */, - 6967B1D91E27BD1D00A129E2 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = PdfReader; - productName = PdfReader; - productReference = 6967B1DB1E27BD1D00A129E2 /* libPdfReader.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6967B1D31E27BD1D00A129E2 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0820; - ORGANIZATIONNAME = OnlyOffce; - TargetAttributes = { - 6967B1DA1E27BD1D00A129E2 = { - CreatedOnToolsVersion = 8.2; - DevelopmentTeam = 2WH24U26GJ; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 6967B1D61E27BD1D00A129E2 /* Build configuration list for PBXProject "PdfReader" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 6967B1D21E27BD1D00A129E2; - productRefGroup = 6967B1DC1E27BD1D00A129E2 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6967B1DA1E27BD1D00A129E2 /* PdfReader */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 6967B1D71E27BD1D00A129E2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6967B26A1E27BD4A00A129E2 /* UnicodeMap.cpp in Sources */, - 6967B24F1E27BD4A00A129E2 /* FontFileTrueType.cpp in Sources */, - 6967B24A1E27BD4A00A129E2 /* CMap.cpp in Sources */, - 6967B2461E27BD4A00A129E2 /* Annot.cpp in Sources */, - 6967B2561E27BD4A00A129E2 /* GState.cpp in Sources */, - 6967B2521E27BD4A00A129E2 /* Function.cpp in Sources */, - 6967B24D1E27BD4A00A129E2 /* ExtractImageOutputDev.cpp in Sources */, - 6967B2591E27BD4A00A129E2 /* JBIG2Stream.cpp in Sources */, - 6967B2501E27BD4A00A129E2 /* FontFileType1.cpp in Sources */, - 6967B26B1E27BD4A00A129E2 /* XRef.cpp in Sources */, - 6967B2671E27BD4A00A129E2 /* SecurityHandler.cpp in Sources */, - 6967B25A1E27BD4A00A129E2 /* JPXStream.cpp in Sources */, - 6967B2551E27BD4A00A129E2 /* Graphics.cpp in Sources */, - 6967B2541E27BD4A00A129E2 /* GlobalParams.cpp in Sources */, - 6967B2641E27BD4A00A129E2 /* PDFDoc.cpp in Sources */, - 6967B1E91E27BD4000A129E2 /* PdfReader.cpp in Sources */, - 6967B2601E27BD4A00A129E2 /* Outline.cpp in Sources */, - 6967B2491E27BD4A00A129E2 /* CharCodeToUnicode.cpp in Sources */, - 6967B2571E27BD4A00A129E2 /* Hash.cpp in Sources */, - 6967B25B1E27BD4A00A129E2 /* Lexer.cpp in Sources */, - 6967B25C1E27BD4A00A129E2 /* Link.cpp in Sources */, - 6967B25E1E27BD4A00A129E2 /* NameToCharCode.cpp in Sources */, - 6967B25F1E27BD4A00A129E2 /* Object.cpp in Sources */, - 6967B2471E27BD4A00A129E2 /* Array.cpp in Sources */, - 6967B2691E27BD4A00A129E2 /* StringExt.cpp in Sources */, - 6967B2581E27BD4A00A129E2 /* JArithmeticDecoder.cpp in Sources */, - 6967B24C1E27BD4A00A129E2 /* Dict.cpp in Sources */, - 6967B2611E27BD4A00A129E2 /* OutputDevice.cpp in Sources */, - 6967B24B1E27BD4A00A129E2 /* Decrypt.cpp in Sources */, - 6967B2621E27BD4A00A129E2 /* Page.cpp in Sources */, - 6967B2681E27BD4A00A129E2 /* Stream.cpp in Sources */, - 6967B2481E27BD4A00A129E2 /* Catalog.cpp in Sources */, - 6967B2531E27BD4A00A129E2 /* GFont.cpp in Sources */, - 6967B24E1E27BD4A00A129E2 /* FontFileBase.cpp in Sources */, - 6967B2661E27BD4A00A129E2 /* RendererOutputDev.cpp in Sources */, - 6967B2511E27BD4A00A129E2 /* FontFileType1C.cpp in Sources */, - 6967B2631E27BD4A00A129E2 /* Parser.cpp in Sources */, - 6967B2651E27BD4A00A129E2 /* PSLexer.cpp in Sources */, - 6967B25D1E27BD4A00A129E2 /* List.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 6967B1E21E27BD1D00A129E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 6967B1E31E27BD1D00A129E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.2; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6967B1E51E27BD1D00A129E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = _IOS; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 6967B1E61E27BD1D00A129E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEVELOPMENT_TEAM = 2WH24U26GJ; - GCC_PREPROCESSOR_DEFINITIONS = _IOS; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6967B1D61E27BD1D00A129E2 /* Build configuration list for PBXProject "PdfReader" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6967B1E21E27BD1D00A129E2 /* Debug */, - 6967B1E31E27BD1D00A129E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6967B1E41E27BD1D00A129E2 /* Build configuration list for PBXNativeTarget "PdfReader" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6967B1E51E27BD1D00A129E2 /* Debug */, - 6967B1E61E27BD1D00A129E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6967B1D31E27BD1D00A129E2 /* Project object */; -} diff --git a/PdfReader/Mac/PdfReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PdfReader/Mac/PdfReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 80ceefe65b..0000000000 --- a/PdfReader/Mac/PdfReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/PdfReader/Mac/PdfReader/NOTE.txt b/PdfReader/Mac/PdfReader/NOTE.txt deleted file mode 100644 index 70fa9cd654..0000000000 --- a/PdfReader/Mac/PdfReader/NOTE.txt +++ /dev/null @@ -1 +0,0 @@ -DO NOT REMOVE FOLDER FOR XCODE \ No newline at end of file diff --git a/PdfReader/PdfReader.cpp b/PdfReader/PdfReader.cpp deleted file mode 100644 index e1990feec9..0000000000 --- a/PdfReader/PdfReader.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#define errMemory 12 - -#include "../DesktopEditor/graphics/pro/Graphics.h" -#include "PdfReader.h" - -#include "Src/Adaptors.h" -#include "lib/xpdf/ErrorCodes.h" - -#include "../Common/OfficeDefines.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include "../DesktopEditor/graphics/IRenderer.h" -#include "../DesktopEditor/common/Directory.h" -#include "../DesktopEditor/common/StringExt.h" -#include "../DesktopEditor/common/Path.h" -#include "../PdfWriter/PdfRenderer.h" - -#include "lib/xpdf/PDFDoc.h" -#include "lib/xpdf/GlobalParams.h" -#include "lib/xpdf/ErrorCodes.h" -#include "lib/xpdf/ImageOutputDev.h" -#include "lib/xpdf/TextString.h" -#include "lib/xpdf/SecurityHandler.h" -#include "lib/xpdf/Lexer.h" -#include "lib/xpdf/Parser.h" -#include "lib/xpdf/AcroForm.h" -#include "Src/RendererOutputDev.h" -#include "Src/Adaptors.h" - -#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" -#include "lib/xpdf/Outline.h" -#include "lib/xpdf/Link.h" -#include "lib/xpdf/TextOutputDev.h" -#include "lib/goo/GList.h" -#include - -namespace PdfReader -{ - class CPdfReader_Private - { - public: - PDFDoc* m_pPDFDocument; - std::wstring m_wsTempFolder; - std::wstring m_wsCMapFolder; - std::wstring m_wsSrcPath; - NSFonts::IApplicationFonts* m_pAppFonts; - NSFonts::IFontManager* m_pFontManager; - CFontList* m_pFontList; - DWORD m_nFileLength; - }; - - CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) - { - m_pInternal = new CPdfReader_Private(); - - m_pInternal->m_wsTempFolder = L""; - m_pInternal->m_wsCMapFolder = L""; - m_pInternal->m_wsSrcPath = L""; - - m_pInternal->m_pPDFDocument = NULL; - m_pInternal->m_pFontManager = NULL; - m_pInternal->m_nFileLength = 0; - - globalParams = new GlobalParamsAdaptor(NULL); -#ifndef _DEBUG - globalParams->setErrQuiet(gTrue); -#endif - - m_pInternal->m_pFontList = new CFontList(); - - m_pInternal->m_pAppFonts = pAppFonts; - - // Создаем менеджер шрифтов с собственным кэшем - m_pInternal->m_pFontManager = pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(pAppFonts->GetStreams()); - m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager); - #ifndef BUILDING_WASM_MODULE - globalParams->setupBaseFonts(NULL); - #endif - -#ifdef CMAP_USE_MEMORY - SetCMapMemory(); -#endif - - m_eError = errNone; - } - CPdfReader::~CPdfReader() - { - if (m_pInternal->m_pFontList) - { - m_pInternal->m_pFontList->Clear(); - delete m_pInternal->m_pFontList; - } - - m_pInternal->m_wsCMapFolder = L""; - - if (!m_pInternal->m_wsTempFolder.empty()) - { - NSDirectory::DeleteDirectory(m_pInternal->m_wsTempFolder); - m_pInternal->m_wsTempFolder = L""; - } - - RELEASEOBJECT((m_pInternal->m_pPDFDocument)); - RELEASEOBJECT((globalParams)); - RELEASEINTERFACE((m_pInternal->m_pFontManager)); - } - bool CPdfReader::LoadFromFile(const std::wstring& wsSrcPath, const std::wstring& wsOptions, - const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) - { -// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем -// FontManager, потому что сейчас в нем кэш без ограничения. -//------------------------------------------------------ - RELEASEINTERFACE((m_pInternal->m_pFontManager)); - m_pInternal->m_pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams()); - m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager); -//------------------------------------------------------ - - if (m_pInternal->m_pPDFDocument) - delete m_pInternal->m_pPDFDocument; - - if (GetTempDirectory() == L"") - { - SetTempDirectory(NSDirectory::GetTempPath()); - } - - m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword); - GString* user_pswd = NSStrings::CreateString(wsUserPassword); - - // конвертим путь в utf8 - под виндой они сконвертят в юникод, а на остальных - так и надо - m_pInternal->m_wsSrcPath = wsSrcPath; - std::string sPathUtf8 = U_TO_UTF8(wsSrcPath); - m_pInternal->m_pPDFDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); - - delete owner_pswd; - delete user_pswd; - - NSFile::CFileBinary oFile; - if (oFile.OpenFile(wsSrcPath)) - { - m_pInternal->m_nFileLength = oFile.GetFileSize(); - oFile.CloseFile(); - } - - if (m_pInternal->m_pPDFDocument) - m_eError = m_pInternal->m_pPDFDocument->getErrorCode(); - else - m_eError = errMemory; - - if (!m_pInternal->m_pPDFDocument || !m_pInternal->m_pPDFDocument->isOk()) - { - RELEASEOBJECT(m_pInternal->m_pPDFDocument); - return false; - } - - m_pInternal->m_pFontList->Clear(); - - return true; - } - bool CPdfReader::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options, - const std::wstring& owner_password, const std::wstring& user_password) - { -// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем -// FontManager, потому что сейчас в нем кэш без ограничения. -//------------------------------------------------------ - RELEASEINTERFACE((m_pInternal->m_pFontManager)); - m_pInternal->m_pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams()); - m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager); -//------------------------------------------------------ - - RELEASEOBJECT(m_pInternal->m_pPDFDocument); - m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(owner_password); - GString* user_pswd = NSStrings::CreateString(user_password); - - Object obj; - obj.initNull(); - // будет освобожден в деструкторе PDFDoc - BaseStream *str = new MemStream((char*)data, 0, length, &obj); - m_pInternal->m_pPDFDocument = new PDFDoc(str, owner_pswd, user_pswd); - m_pInternal->m_nFileLength = length; - - delete owner_pswd; - delete user_pswd; - - m_eError = m_pInternal->m_pPDFDocument ? m_pInternal->m_pPDFDocument->getErrorCode() : errMemory; - - if (!m_pInternal->m_pPDFDocument || !m_pInternal->m_pPDFDocument->isOk()) - { - RELEASEOBJECT(m_pInternal->m_pPDFDocument); - return false; - } - - m_pInternal->m_pFontList->Clear(); - - return true; - } - void CPdfReader::Close() - { - RELEASEOBJECT((m_pInternal->m_pPDFDocument)); - } - NSFonts::IApplicationFonts* CPdfReader::GetFonts() - { - return m_pInternal->m_pAppFonts; - } - - OfficeDrawingFileType CPdfReader::GetType() - { - return odftPDF; - } - int CPdfReader::GetError() - { - if (!m_pInternal->m_pPDFDocument) - return m_eError; - - if (m_pInternal->m_pPDFDocument->isOk()) - return 0; - - return m_pInternal->m_pPDFDocument->getErrorCode(); - } - int CPdfReader::GetPagesCount() - { - if (!m_pInternal->m_pPDFDocument) - return 0; - - return m_pInternal->m_pPDFDocument->getNumPages(); - } - double CPdfReader::GetVersion() - { - if (!m_pInternal->m_pPDFDocument) - return 0; - - return m_pInternal->m_pPDFDocument->getPDFVersion(); - } - int CPdfReader::GetPermissions() - { - if (!m_pInternal->m_pPDFDocument) - return 0; - - int nPermissions = 0; - - if (m_pInternal->m_pPDFDocument->okToPrint()) - nPermissions += PERMISSION_PRINT; - if (m_pInternal->m_pPDFDocument->okToCopy()) - nPermissions += PERMISSION_COPY; - if (m_pInternal->m_pPDFDocument->okToChange()) - nPermissions += PERMISSION_CHANGE; - - return nPermissions; - } - std::wstring CPdfReader::GetPageLabel(int nPageIndex) - { - if (!m_pInternal->m_pPDFDocument) - return std::wstring(); -// todo label -// StringExt* seLabel = m_pInternal->m_pPDFDocument->GetPageLabels()->GetLabel(nPageIndex); -// if (seLabel) -// { -// std::wstring wsResult(seLabel->GetWString()); -// delete seLabel; -// return wsResult; -// } - - return std::wstring(); - } - bool CPdfReader::ExtractAllImages(const wchar_t* wsDstPath, const wchar_t* wsPrefix) - { - std::wstring sDstPath(wsDstPath); - if (sDstPath.empty()) - return false; - - // check last symbol (directory) - wchar_t nLastSymbol = sDstPath[sDstPath.length() - 1]; - if ('\\' != nLastSymbol && '/' != nLastSymbol) - sDstPath += '/'; - // prefix for each file - if (NULL != wsPrefix) - sDstPath += std::wstring(wsPrefix); - - std::string sDstPathA = U_TO_UTF8(sDstPath); - ImageOutputDev *pOutputDev = new ImageOutputDev((char*)sDstPathA.c_str(), true, false, false); - if (!pOutputDev) - return false; - - int nPagesCount = GetPagesCount(); - for (int nIndex = 1; nIndex <= nPagesCount; nIndex++) - { - m_pInternal->m_pPDFDocument->displayPage(pOutputDev, nIndex, 72, 72, 0, false, false, false); - } - - delete pOutputDev; - - return true; - } - void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) - { - int nPageIndex = _nPageIndex + 1; - - if (!m_pInternal->m_pPDFDocument) - return; - - const double c_dInch = 25.399; // Миллиметров в дюйме - const double c_dXResolution = 154.0; - const double c_dYResolution = 154.0; - - double dKoefX = c_dInch / c_dXResolution; - double dKoefY = c_dInch / c_dYResolution; - - int nRotate = m_pInternal->m_pPDFDocument->getPageRotate(nPageIndex); - - while (nRotate >= 360) - nRotate -= 360; - - while (nRotate < 0) - nRotate += 360; - - if (0 != nRotate && 180 != nRotate) - { - *pdHeight = m_pInternal->m_pPDFDocument->getPageCropWidth(nPageIndex); - *pdWidth = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex); - } - else - { - *pdWidth = m_pInternal->m_pPDFDocument->getPageCropWidth(nPageIndex); - *pdHeight = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex); - } - - *pdDpiX = 72; - *pdDpiY = 72; - } - void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak) - { - int nPageIndex = _nPageIndex + 1; - - if (m_pInternal->m_pPDFDocument && pRenderer) - { - RendererOutputDev oRendererOut(pRenderer, m_pInternal->m_pFontManager, m_pInternal->m_pFontList); - oRendererOut.NewPDF(m_pInternal->m_pPDFDocument->getXRef()); - oRendererOut.SetBreak(pbBreak); - m_pInternal->m_pPDFDocument->displayPage(&oRendererOut, nPageIndex, 72.0, 72.0, 0, false, true, false); - } - } - int CPdfReader::GetImagesCount() - { -// ImageOutputDev *pOutputDev = new ImageOutputDev(NULL, true, true, false); -// if (!pOutputDev) -// return 0; -// -// for (int nIndex = 1; nIndex <= m_pInternal->m_pPDFDocument->GetPagesCount(); nIndex++) -// { -// m_pInternal->m_pPDFDocument->displayPage(pOutputDev, nIndex, 72, 72, 0, false, false, false); -// } -// -// return pOutputDev-> -return 0; - } - void CPdfReader::SetTempDirectory(const std::wstring& wsTempFolder) - { - if (!m_pInternal->m_wsTempFolder.empty()) - { - NSDirectory::DeleteDirectory(m_pInternal->m_wsTempFolder); - m_pInternal->m_wsTempFolder = wsTempFolder; - } - - if (!wsTempFolder.empty()) - { - std::wstring wsFolderName = std::wstring(wsTempFolder) + L"//pdftemp"; - std::wstring wsFolder = wsFolderName; - int nCounter = 0; - while (NSDirectory::Exists(wsFolder)) - { - nCounter++; - wsFolder = wsFolderName + L"_" + std::to_wstring(nCounter); - } - NSDirectory::CreateDirectory(wsFolder); - m_pInternal->m_wsTempFolder = wsFolder; - } - else - m_pInternal->m_wsTempFolder = L""; - - if (globalParams) - ((GlobalParamsAdaptor*)globalParams)->SetTempFolder(m_pInternal->m_wsTempFolder.c_str()); - } - std::wstring CPdfReader::GetTempDirectory() - { - return m_pInternal->m_wsTempFolder; - } - - void CPdfReader::SetCMapFolder(const wchar_t* wsCMapFolder) - { - m_pInternal->m_wsCMapFolder = std::wstring(wsCMapFolder); - - if (globalParams) - ((GlobalParamsAdaptor*)globalParams)->SetCMapFolder(m_pInternal->m_wsCMapFolder.c_str()); - } - void CPdfReader::SetCMapMemory() - { - if (globalParams) - ((GlobalParamsAdaptor*)globalParams)->SetCMapMemory(); - } - NSFonts::IFontManager* CPdfReader::GetFontManager() - { - return m_pInternal->m_pFontManager; - } - std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStream) - { - XMLConverter oConverter(m_pInternal->m_pPDFDocument->getXRef(), isPrintStream); - std::wstring wsXml = oConverter.GetXml(); - - if (wsFilePath != L"") - { - NSFile::CFileBinary oFile; - if (!oFile.CreateFileW(wsFilePath)) - return wsXml; - - oFile.WriteStringUTF8(wsXml); - oFile.CloseFile(); - } - - return wsXml; - } - PDFDoc* CPdfReader::GetPDFDocument() - { - return m_pInternal->m_pPDFDocument; - } - void CPdfReader::ChangeLength(DWORD nLength) - { - m_pInternal->m_nFileLength = nLength; - } - -#define DICT_LOOKUP(sName, wsName) \ - if (info.dictLookup(sName, &obj1)->isString())\ - {\ - TextString* s = new TextString(obj1.getString());\ - sRes += L"\"";\ - sRes += wsName;\ - sRes += L"\":\"";\ - std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\ - NSStringExt::Replace(sValue, L"\"", L"\\\"");\ - sRes += sValue;\ - sRes += L"\",";\ - delete s;\ - }\ - -#define DICT_LOOKUP_DATE(sName, wsName) \ - if (info.dictLookup(sName, &obj1)->isString())\ - {\ - char* str = obj1.getString()->getCString();\ - if (str)\ - {\ - TextString* s = new TextString(obj1.getString());\ - std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\ - if (sNoDate.length() > 16)\ - {\ - std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' +\ - sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2);\ - if (sNoDate.length() > 21)\ - sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2));\ - else\ - sDate += L"Z";\ - NSStringExt::Replace(sDate, L"\"", L"\\\"");\ - sRes += L"\"";\ - sRes += wsName;\ - sRes += L"\":\"";\ - sRes += sDate;\ - sRes += L"\",";\ - }\ - delete s;\ - }\ - }\ - - std::wstring CPdfReader::GetInfo() - { - if (!m_pInternal->m_pPDFDocument) - return NULL; - XRef* xref = m_pInternal->m_pPDFDocument->getXRef(); - BaseStream* str = m_pInternal->m_pPDFDocument->getBaseStream(); - if (!xref || !str) - return NULL; - - std::wstring sRes = L"{"; - - Object info, obj1; - m_pInternal->m_pPDFDocument->getDocInfo(&info); - if (info.isDict()) - { - DICT_LOOKUP("Title", L"Title"); - DICT_LOOKUP("Author", L"Author"); - DICT_LOOKUP("Subject", L"Subject"); - DICT_LOOKUP("Keywords", L"Keywords"); - DICT_LOOKUP("Creator", L"Creator"); - DICT_LOOKUP("Producer", L"Producer"); - - DICT_LOOKUP_DATE("CreationDate", L"CreationDate"); - DICT_LOOKUP_DATE("ModDate", L"ModDate"); - } - - info.free(); - obj1.free(); - - std::wstring version = std::to_wstring(GetVersion()); - std::wstring::size_type posDot = version.find('.'); - if (posDot != std::wstring::npos) - version = version.substr(0, posDot + 2); - - sRes += L"\"Version\":"; - sRes += version; - double nW = 0; - double nH = 0; - double nDpi = 0; - GetPageInfo(0, &nW, &nH, &nDpi, &nDpi); - sRes += L",\"PageWidth\":"; - sRes += std::to_wstring((int)(nW * 100)); - sRes += L",\"PageHeight\":"; - sRes += std::to_wstring((int)(nH * 100)); - sRes += L",\"NumberOfPages\":"; - sRes += std::to_wstring(GetPagesCount()); - sRes += L",\"FastWebView\":"; - - Object obj2, obj3, obj4, obj5, obj6; - bool bLinearized = false; - obj1.initNull(); - Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue); - parser->getObj(&obj1); - parser->getObj(&obj2); - parser->getObj(&obj3); - parser->getObj(&obj4); - if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict()) - { - obj4.dictLookup("Linearized", &obj5); - obj4.dictLookup("L", &obj6); - if (obj5.isNum() && obj5.getNum() > 0 && obj6.isNum()) - { - unsigned long size = obj6.getNum(); - bLinearized = size == m_pInternal->m_nFileLength; - } - obj6.free(); - obj5.free(); - } - obj4.free(); - obj3.free(); - obj2.free(); - obj1.free(); - delete parser; - - sRes += bLinearized ? L"true" : L"false"; - sRes += L",\"Tagged\":"; - - bool bTagged = false; - Object catDict, markInfoObj; - if (xref->getCatalog(&catDict) && catDict.isDict() && catDict.dictLookup("MarkInfo", &markInfoObj) && markInfoObj.isDict()) - { - Object marked, suspects; - if (markInfoObj.dictLookup("Marked", &marked) && marked.isBool() && marked.getBool()) - { - bTagged = true; - // If Suspects is true, the document may not completely conform to Tagged PDF conventions. - if (markInfoObj.dictLookup("Suspects", &suspects) && suspects.isBool() && suspects.getBool()) - bTagged = false; - } - marked.free(); - suspects.free(); - } - markInfoObj.free(); - catDict.free(); - - sRes += bTagged ? L"true" : L"false"; - sRes += L"}"; - - return sRes; - } - void getBookmars(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level) - { - int nLengthTitle = pOutlineItem->getTitleLength(); - Unicode* pTitle = pOutlineItem->getTitle(); - std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pTitle, nLengthTitle); - - LinkAction* pLinkAction = pOutlineItem->getAction(); - if (!pLinkAction) - return; - LinkActionKind kind = pLinkAction->getKind(); - if (kind != actionGoTo) - return; - - GString* str = ((LinkGoTo*)pLinkAction)->getNamedDest(); - LinkDest* pLinkDest = str ? pdfDoc->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest(); - if (!pLinkDest) - return; - int pg; - if (pLinkDest->isPageRef()) - { - Ref pageRef = pLinkDest->getPageRef(); - pg = pdfDoc->findPage(pageRef.num, pageRef.gen); - } - else - pg = pLinkDest->getPageNum(); - if (pg == 0) - pg = 1; - double dy = 0; - double dTop = pLinkDest->getTop(); - double dHeight = pdfDoc->getPageCropHeight(pg); - if (dTop > 0 && dTop < dHeight) - dy = dHeight - dTop; - if (str) - RELEASEOBJECT(pLinkDest); - - out.AddInt(pg - 1); - out.AddInt(level); - out.AddDouble(dy); - out.WriteString((BYTE*)sTitle.c_str(), sTitle.length()); - - pOutlineItem->open(); - GList* pList = pOutlineItem->getKids(); - if (!pList) - return; - int num = pList->getLength(); - for (int i = 0; i < num; i++) - { - OutlineItem* pOutlineItemKid = (OutlineItem*)pList->get(i); - if (!pOutlineItemKid) - continue; - getBookmars(pdfDoc, pOutlineItemKid, out, level + 1); - } - pOutlineItem->close(); - } - BYTE* CPdfReader::GetStructure() - { - if (!m_pInternal->m_pPDFDocument) - return NULL; - Outline* pOutline = m_pInternal->m_pPDFDocument->getOutline(); - if (!pOutline) - return NULL; - GList* pList = pOutline->getItems(); - if (!pList) - return NULL; - - NSWasm::CData oRes; - oRes.SkipLen(); - int num = pList->getLength(); - for (int i = 0; i < num; i++) - { - OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i); - if (pOutlineItem) - getBookmars(m_pInternal->m_pPDFDocument, pOutlineItem, oRes, 1); - } - oRes.WriteLen(); - - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; - } - BYTE* CPdfReader::GetLinks(int nPageIndex) - { - if (!m_pInternal->m_pPDFDocument) - return NULL; - - nPageIndex++; - - NSWasm::CPageLink oLinks; - double height = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex); - - // Гиперссылка - Links* pLinks = m_pInternal->m_pPDFDocument->getLinks(nPageIndex); - if (!pLinks) - return NULL; - - int num = pLinks->getNumLinks(); - for (int i = 0; i < num; i++) - { - Link* pLink = pLinks->getLink(i); - if (!pLink) - continue; - - GString* str = NULL; - double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, dy = 0.0; - pLink->getRect(&x1, &y1, &x2, &y2); - y1 = height - y1; - y2 = height - y2; - - LinkAction* pLinkAction = pLink->getAction(); - if (!pLinkAction) - continue; - LinkActionKind kind = pLinkAction->getKind(); - if (kind == actionGoTo) - { - str = ((LinkGoTo*)pLinkAction)->getNamedDest(); - LinkDest* pLinkDest = str ? m_pInternal->m_pPDFDocument->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy(); - if (pLinkDest) - { - int pg; - if (pLinkDest->isPageRef()) - { - Ref pageRef = pLinkDest->getPageRef(); - pg = m_pInternal->m_pPDFDocument->findPage(pageRef.num, pageRef.gen); - } - else - pg = pLinkDest->getPageNum(); - std::string sLink = "#" + std::to_string(pg - 1); - str = new GString(sLink.c_str()); - dy = m_pInternal->m_pPDFDocument->getPageCropHeight(pg) - pLinkDest->getTop(); - } - RELEASEOBJECT(pLinkDest); - } - else if (kind == actionURI) - str = ((LinkURI*)pLinkAction)->getURI()->copy(); - - oLinks.m_arLinks.push_back({str ? std::string(str->getCString(), str->getLength()) : "", dy, x1, y2, x2 - x1, y1 - y2}); - RELEASEOBJECT(str); - } - RELEASEOBJECT(pLinks); - - // Текст-ссылка - TextOutputControl textOutControl; - textOutControl.mode = textOutReadingOrder; - TextOutputDev* pTextOut = new TextOutputDev(NULL, &textOutControl, gFalse); - m_pInternal->m_pPDFDocument->displayPage(pTextOut, nPageIndex, 72, 72, 0, gFalse, gTrue, gFalse); - m_pInternal->m_pPDFDocument->processLinks(pTextOut, nPageIndex); - TextWordList* pWordList = pTextOut->makeWordList(); - for (int i = 0; i < pWordList->getLength(); i++) - { - TextWord* pWord = pWordList->get(i); - if (!pWord) - continue; - GString* sLink = pWord->getText(); - if (!sLink) - continue; - std::string link(sLink->getCString(), sLink->getLength()); - size_t find = link.find("http://"); - if (find == std::string::npos) - find = link.find("https://"); - if (find == std::string::npos) - find = link.find("www."); - if (find != std::string::npos) - { - link.erase(0, find); - double x1, y1, x2, y2; - pWord->getBBox(&x1, &y1, &x2, &y2); - oLinks.m_arLinks.push_back({link, 0, x1, y1, x2 - x1, y2 - y1}); - } - } - RELEASEOBJECT(pTextOut); - - return oLinks.Serialize(); - } -} diff --git a/PdfReader/PdfReader.h b/PdfReader/PdfReader.h deleted file mode 100644 index 85bc9d909f..0000000000 --- a/PdfReader/PdfReader.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_H -#define _PDF_READER_H - -#ifndef PDFREADER_USE_DYNAMIC_LIBRARY -#define PDFREADER_DECL_EXPORT -#else -#include "../DesktopEditor/common/base_export.h" -#define PDFREADER_DECL_EXPORT Q_DECL_EXPORT -#endif -#include "../DesktopEditor/graphics/pro/officedrawingfile.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" - -class PDFDoc; -namespace PdfReader -{ - typedef enum - { - errorNone = 0, // Нет ошибок - errorOpenFile = 1, // Ошибка при открытии PDF файла - errorBadCatalog = 2, // couldn't read the page catalog - errorDamaged = 3, // PDF файл был поврежден и его невозможно восстановить - errorEncrypted = 4, // Файл зашифрован, авторизация не пройдена - errorHighlightFile = 5, // nonexistent or invalid highlight file - errorBadPrinter = 6, // плохой принтер - errorPrinting = 7, // ошибка во время печати - errorPermission = 8, // Ошибка связанная с ограничениями наложенными на файл - errorBadPageNum = 9, // Неверное количество страниц - errorFileIO = 10, // Ошибка при чтении/записи - errorMemory = 11 // Memory exceed - } EError; - - class CPdfReader_Private; - class PDFREADER_DECL_EXPORT CPdfReader : public IOfficeDrawingFile - { - public: - - CPdfReader(NSFonts::IApplicationFonts* fonts); - virtual ~CPdfReader(); - - virtual bool LoadFromFile(const std::wstring& file, const std::wstring& options = L"", - const std::wstring& owner_password = L"", const std::wstring& user_password = L""); - virtual bool LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options = L"", - const std::wstring& owner_password = L"", const std::wstring& user_password = L""); - - virtual void Close(); - - virtual NSFonts::IApplicationFonts* GetFonts(); - - virtual OfficeDrawingFileType GetType(); - - virtual std::wstring GetTempDirectory(); - virtual void SetTempDirectory(const std::wstring& directory); - - virtual int GetPagesCount(); - virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); - virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); - virtual std::wstring GetInfo(); - - int GetError(); - double GetVersion(); - int GetPermissions(); - std::wstring GetPageLabel(int nPageIndex); - - bool ExtractAllImages(const wchar_t* wsDstPath, const wchar_t* wsPrefix = 0); - int GetImagesCount(); - - void SetCMapFolder(const wchar_t* wsCMapFolder); - void SetCMapMemory(); - NSFonts::IFontManager* GetFontManager(); - - std::wstring ToXml(const std::wstring& wsXmlPath, bool isPrintStreams = false); - PDFDoc* GetPDFDocument(); - void ChangeLength(DWORD nLength); - - virtual BYTE* GetStructure(); - virtual BYTE* GetLinks(int nPageIndex); - - private: - CPdfReader_Private* m_pInternal; - int m_eError; - }; -} - -#endif // _PDF_READER_H diff --git a/PdfReader/PdfReader.pro b/PdfReader/PdfReader.pro deleted file mode 100644 index a748ca3909..0000000000 --- a/PdfReader/PdfReader.pro +++ /dev/null @@ -1,119 +0,0 @@ -QT -= core gui - -VERSION = 1.0.0.4 -TARGET = PdfReader -TEMPLATE = lib - -CONFIG += shared -CONFIG += plugin -CONFIG += warn_off - -CONFIG += core_static_link_libstd - -CORE_ROOT_DIR = $$PWD/.. -PWD_ROOT_DIR = $$PWD -include(../Common/base.pri) - -DEFINES += PDFREADER_USE_DYNAMIC_LIBRARY - -CONFIG += use_cmap_memory - -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter) - -core_windows { -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -core_android:DEFINES += ANDROID - -INCLUDEPATH += \ - $$PWD/lib/goo \ - $$PWD/lib/fofi \ - $$PWD/lib/splash \ - $$PWD/lib - -HEADERS += \ - $$PWD/lib/aconf.h \ - $$$files($$PWD/lib/*.h) - -SOURCES += $$files($$PWD/lib/*.c, true) -SOURCES += $$files($$PWD/lib/*.cc, true) - -SOURCES -= \ - $$PWD/lib/xpdf/HTMLGen.cc \ - $$PWD/lib/xpdf/pdftohtml.cc \ - $$PWD/lib/xpdf/pdftopng.cc \ - $$PWD/lib/xpdf/pdftoppm.cc \ - $$PWD/lib/xpdf/pdftops.cc \ - $$PWD/lib/xpdf/pdftotext.cc \ - $$PWD/lib/xpdf/pdfdetach.cc \ - $$PWD/lib/xpdf/pdffonts.cc \ - $$PWD/lib/xpdf/pdfimages.cc \ - $$PWD/lib/xpdf/pdfinfo.cc - -SOURCES += \ - Src/RendererOutputDev.cpp \ - Src/Adaptors.cpp \ - Src/GfxClip.cpp \ - PdfReader.cpp - -HEADERS += \ - Src/RendererOutputDev.h \ - Src/Adaptors.h \ - Src/MemoryUtils.h \ - Src/GfxClip.h \ - PdfReader.h - -# Base fonts -HEADERS += \ - Resources/Fontd050000l.h \ - Resources/Fontn019003l.h \ - Resources/Fontn019004l.h \ - Resources/Fontn019023l.h \ - Resources/Fontn019024l.h \ - Resources/Fontn021003l.h \ - Resources/Fontn021004l.h \ - Resources/Fontn021023l.h \ - Resources/Fontn021024l.h \ - Resources/Fontn022003l.h \ - Resources/Fontn022004l.h \ - Resources/Fontn022023l.h \ - Resources/Fontn022024l.h \ - Resources/Fonts050000l.h \ - Resources/BaseFonts.h - -SOURCES += \ - Resources/BaseFonts.cpp - -core_windows:LIBS += -lOle32 - -CONFIG += use_external_jpeg2000 -use_external_jpeg2000 { - DEFINES += USE_EXTERNAL_JPEG2000 - CONFIG += use_openjpeg2000 - use_openjpeg2000 { - include($$PWD/../DesktopEditor/raster/Jp2/openjpeg/openjpeg.pri) - } else { - DEFINES += USE_GRAPHICS_JPEG2000 - } - HEADERS += Src/JPXStream2.h - SOURCES += Src/JPXStream2.cpp -} - -#CONFIG += build_viewer_module -build_viewer_module { - DEFINES += BUILDING_WASM_MODULE - DEFINES += TEST_AS_EXECUTABLE - - HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h - SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp -} - -use_cmap_memory { - DEFINES += CMAP_USE_MEMORY - HEADERS += Resources/CMapMemory/cmap_memory.h - SOURCES += Resources/CMapMemory/cmap_memory.cpp -} diff --git a/PdfReader/PdfReader.sln b/PdfReader/PdfReader.sln deleted file mode 100644 index 1f66d922dc..0000000000 --- a/PdfReader/PdfReader.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfReader", "PdfReader.vcxproj", "{4EA2BD9F-7F41-482B-9BD8-2102C703D912}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfReaderTest", "PdfReaderTest\PdfReaderTest.vcxproj", "{29C4FC88-8442-46E1-A94B-6C3284DE13C0}" - ProjectSection(ProjectDependencies) = postProject - {4EA2BD9F-7F41-482B-9BD8-2102C703D912} = {4EA2BD9F-7F41-482B-9BD8-2102C703D912} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|Win32.ActiveCfg = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|Win32.Build.0 = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|x64.ActiveCfg = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Debug|x64.Build.0 = Debug|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|Mixed Platforms.Build.0 = Release|Win32 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|Win32.ActiveCfg = Release|Win32 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|Win32.Build.0 = Release|Win32 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|x64.ActiveCfg = Release|x64 - {4EA2BD9F-7F41-482B-9BD8-2102C703D912}.Release|x64.Build.0 = Release|x64 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|Win32.ActiveCfg = Debug|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|Win32.Build.0 = Debug|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|x64.ActiveCfg = Debug|x64 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Debug|x64.Build.0 = Debug|x64 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|Mixed Platforms.Build.0 = Release|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|Win32.ActiveCfg = Release|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|Win32.Build.0 = Release|Win32 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|x64.ActiveCfg = Release|x64 - {29C4FC88-8442-46E1-A94B-6C3284DE13C0}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PdfReader/PdfReader.vcproj b/PdfReader/PdfReader.vcproj deleted file mode 100644 index 51c394629c..0000000000 --- a/PdfReader/PdfReader.vcproj +++ /dev/null @@ -1,531 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PdfReader/PdfReader.vcxproj b/PdfReader/PdfReader.vcxproj deleted file mode 100644 index dff40dbce5..0000000000 --- a/PdfReader/PdfReader.vcxproj +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {62C7E428-E07C-4C13-A92B-2536D6442C9D} - PdfReader - Win32Proj - - - - StaticLibrary - v140 - Unicode - true - - - StaticLibrary - v140 - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>14.0.25431.1 - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - - - - Disabled - WIN32;_DEBUG;_LIB;CRYPTOPP_DISABLE_ASM;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - Level3 - EditAndContinue - - - - - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - - Level3 - ProgramDatabase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PdfReader/PdfReader.vcxproj.filters b/PdfReader/PdfReader.vcxproj.filters deleted file mode 100644 index 6e8c5bede8..0000000000 --- a/PdfReader/PdfReader.vcxproj.filters +++ /dev/null @@ -1,302 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Source Files - - - \ No newline at end of file diff --git a/PdfReader/PdfReaderTest/PdfReaderTest.cpp b/PdfReader/PdfReaderTest/PdfReaderTest.cpp deleted file mode 100644 index 2e1aca3937..0000000000 --- a/PdfReader/PdfReaderTest/PdfReaderTest.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -// PdfReaderTest.cpp : Defines the entry point for the console application. -// - -#include -#include -#include -#include - -#include "../PdfReader.h" -#include "../../DesktopEditor/fontengine/ApplicationFonts.h" - -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/common/Directory.h" - -#if defined(_WIN64) - #pragma comment(lib, "../../build/bin/icu/win_64/icuuc.lib") -#elif defined (_WIN32) - - #if defined(_DEBUG) - #pragma comment(lib, "../../build/lib/win_32/DEBUG/HtmlRenderer.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/graphics.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/kernel.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/UnicodeConverter.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/CryptoPPLib.lib") - #else - #pragma comment(lib, "../../build/lib/win_32/HtmlRenderer.lib") - #pragma comment(lib, "../../build/lib/win_32/graphics.lib") - #pragma comment(lib, "../../build/lib/win_32/kernel.lib") - #pragma comment(lib, "../../build/lib/win_32/UnicodeConverter.lib") - #pragma comment(lib, "../../build/lib/win_32/CryptoPPLib.lib") - #endif - #pragma comment(lib, "../../build/bin/icu/win_32/icuuc.lib") -#endif - -HRESULT convert_single(PdfReader::CPdfReader& oReader, const std::wstring & srcFileName, const std::wstring & sPassword) -{ - if (oReader.LoadFromFile(srcFileName.c_str(), L"", sPassword, sPassword)) - { - int nPagesCount = oReader.GetPagesCount(); - - for (int nPageIndex = 0; nPageIndex < nPagesCount; nPageIndex++) - { - int nRasterWCur = 1000; - int nRasterHCur = 1000; - - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - oReader.GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - double dKoef1 = nRasterWCur / dWidth; - double dKoef2 = nRasterHCur / dHeight; - if (dKoef1 > dKoef2) - dKoef1 = dKoef2; - - nRasterWCur = (int)(dWidth * dKoef1 + 0.5); - nRasterHCur = (int)(dHeight * dKoef1 + 0.5); - - std::wstring wsFilePathName = NSFile::GetDirectoryName(srcFileName); - std::wstring wsDstFilePath = srcFileName + L"_" + std::to_wstring(nPageIndex + 1) + L".png"; - - oReader.ConvertToRaster(nPageIndex, wsDstFilePath.c_str(), 4, nRasterWCur, nRasterHCur); - } - oReader.Close(); - - return S_OK; - } - - return S_FALSE; -} -HRESULT convert_directory(PdfReader::CPdfReader& oReader, std::wstring pathName, const std::wstring & sPassword) -{ - HRESULT hr = S_OK; - - std::vector arFiles = NSDirectory::GetFiles(pathName, false); - - for (size_t i = 0; i < arFiles.size(); i++) - { - hr = convert_single(oReader, arFiles[i], sPassword); - - printf("%d of %d %S \tresult = %d\n", i + 1, arFiles.size(), arFiles[i].c_str(), hr); - - } - return S_OK; -} - -int _tmain(int argc, _TCHAR* argv[]) -{ - if (argc < 2) return 1; - - NSFonts::IApplicationFonts* pApplicationFonts = NSFonts::NSApplication::Create(); - pApplicationFonts->Initialize(); - - PdfReader::CPdfReader oPdfReader(pApplicationFonts); - - HRESULT hr = S_FALSE; - - std::wstring sPassword = argc > 2 ? argv[2] : L""; - - if (NSFile::CFileBinary::Exists(argv[1])) - { - hr = convert_single(oPdfReader, argv[1], sPassword); - } - else if (NSDirectory::Exists(argv[1])) - { - hr = convert_directory(oPdfReader, argv[1], sPassword); - } - return hr; -} - diff --git a/PdfReader/PdfReaderTest/PdfReaderTest.sln b/PdfReader/PdfReaderTest/PdfReaderTest.sln deleted file mode 100644 index 4928beee22..0000000000 --- a/PdfReader/PdfReaderTest/PdfReaderTest.sln +++ /dev/null @@ -1,50 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfReaderTest", "PdfReaderTest.vcxproj", "{5F337F52-E630-456E-9081-730A62A89684}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfReader", "..\PdfReader.vcxproj", "{62C7E428-E07C-4C13-A92B-2536D6442C9D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - DLL-Import Debug|Win32 = DLL-Import Debug|Win32 - DLL-Import Debug|x64 = DLL-Import Debug|x64 - DLL-Import Release|Win32 = DLL-Import Release|Win32 - DLL-Import Release|x64 = DLL-Import Release|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5F337F52-E630-456E-9081-730A62A89684}.Debug|Win32.ActiveCfg = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.Debug|Win32.Build.0 = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.Debug|x64.ActiveCfg = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Debug|Win32.ActiveCfg = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Debug|Win32.Build.0 = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Debug|x64.ActiveCfg = Debug|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Release|Win32.ActiveCfg = Release|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Release|Win32.Build.0 = Release|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.DLL-Import Release|x64.ActiveCfg = Release|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.Release|Win32.ActiveCfg = Release|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.Release|Win32.Build.0 = Release|Win32 - {5F337F52-E630-456E-9081-730A62A89684}.Release|x64.ActiveCfg = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Debug|Win32.ActiveCfg = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Debug|Win32.Build.0 = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Debug|x64.ActiveCfg = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Debug|Win32.ActiveCfg = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Debug|Win32.Build.0 = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Debug|x64.ActiveCfg = Debug|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Release|Win32.ActiveCfg = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Release|Win32.Build.0 = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.DLL-Import Release|x64.ActiveCfg = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Release|Win32.ActiveCfg = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Release|Win32.Build.0 = Release|Win32 - {62C7E428-E07C-4C13-A92B-2536D6442C9D}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PdfReader/PdfReaderTest/PdfReaderTest.vcproj b/PdfReader/PdfReaderTest/PdfReaderTest.vcproj deleted file mode 100644 index 9c50ced899..0000000000 --- a/PdfReader/PdfReaderTest/PdfReaderTest.vcproj +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj b/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj deleted file mode 100644 index 5b41616caa..0000000000 --- a/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj +++ /dev/null @@ -1,99 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {5F337F52-E630-456E-9081-730A62A89684} - PdfReaderTest - Win32Proj - - - - Application - v140 - Unicode - true - - - Application - v140 - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>14.0.25431.1 - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - - - - Disabled - D:\_Work\core\DesktopEditor\freetype-2.10.4\include;D:\_Work\core\DesktopEditor\freetype-2.10.4\include\freetype;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CRYPTOPP_DISABLE_ASM;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - Level3 - EditAndContinue - - - true - Console - MachineX86 - - - - - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - - Level3 - ProgramDatabase - - - true - Console - true - true - MachineX86 - - - - - - - - {62c7e428-e07c-4c13-a92b-2536d6442c9d} - false - - - - - - \ No newline at end of file diff --git a/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj.filters b/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj.filters deleted file mode 100644 index 814c2a82db..0000000000 --- a/PdfReader/PdfReaderTest/PdfReaderTest.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/PdfReader/PdfReaderTest/targetver.h b/PdfReader/PdfReaderTest/targetver.h deleted file mode 100644 index 1200ab1d1b..0000000000 --- a/PdfReader/PdfReaderTest/targetver.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/PdfReader/Src/XmlUtils.h b/PdfReader/Src/XmlUtils.h deleted file mode 100644 index bc7079e2e2..0000000000 --- a/PdfReader/Src/XmlUtils.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_XML_UTILS_H -#define _PDF_READER_XML_UTILS_H - -#include -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Base64.h" -#include - -namespace PdfReader -{ - class CXmlWriter - { - public: - - CXmlWriter() - { - m_wsXml.clear(); - } - - const wchar_t* GetXmlString() - { - return m_wsXml.c_str(); - } - void SetXmlString(const std::wstring& wsXml) - { - m_wsXml = wsXml; - } - bool SaveToFile(const std::wstring& wsFilePath, bool bEncodingToUTF8 = false) - { - return NSFile::CFileBinary::SaveToFile(wsFilePath, m_wsXml); - } - void WriteString(const std::wstring& wsString) - { - m_wsXml += wsString; - } - void WriteInteger(int nValue, int Base = 10) - { - m_wsXml += std::to_wstring(nValue); - } - void WriteDouble(double dValue) - { - m_wsXml += std::to_wstring(dValue); - } - void WriteBoolean(bool bValue) - { - if (bValue) - m_wsXml += L"true"; - else - m_wsXml += L"false"; - } - void WriteNodeBegin(const std::wstring& wsNodeName, bool bAttributed = false) - { - m_wsXml += L"<" + wsNodeName; - - if (!bAttributed) - m_wsXml += L">"; - } - void WriteNodeEnd(const std::wstring& wsNodeName, bool bEmptyNode = false, bool bEndNode = true) - { - if (bEmptyNode) - { - if (bEndNode) - m_wsXml += L" />"; - else - m_wsXml += L">"; - } - else - m_wsXml += L""; - } - void WriteNode(const std::wstring& wsNodeName, const std::wstring& wsNodeValue) - { - if (0 == wsNodeValue.length()) - m_wsXml += L"<" + wsNodeName + L"/>"; - else - m_wsXml += L"<" + wsNodeName + L">" + wsNodeValue + L""; - } - void WriteNode(const std::wstring& wsNodeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") - { - WriteNodeBegin(wsNodeName); - WriteString(wsTextBeforeValue); - WriteInteger(nValue, nBase); - WriteString(wsTextAfterValue); - WriteNodeEnd(wsNodeName); - } - void WriteNode(const std::wstring& wsNodeName, double dValue) - { - WriteNodeBegin(wsNodeName); - WriteDouble(dValue); - WriteNodeEnd(wsNodeName); - } - void WriteAttribute(const std::wstring& wsAttributeName, const std::wstring& wsAttributeValue) - { - m_wsXml += L" " + wsAttributeName + L"=\"" + wsAttributeValue + L"\""; - } - void WriteAttribute(const std::wstring& wsAttributeName, int nValue, int nBase = 10, const std::wstring& wsTextBeforeValue = L"", const std::wstring& wsTextAfterValue = L"") - { - WriteString(L" " + wsAttributeName + L"="); - WriteString(L"\""); - WriteString(wsTextBeforeValue); - WriteInteger(nValue, nBase); - WriteString(wsTextAfterValue); - WriteString(L"\""); - } - void WriteAttribute(const std::wstring& wsAttributeName, double dValue) - { - WriteString(L" " + wsAttributeName + L"="); - WriteString(L"\""); - WriteDouble(dValue); - WriteString(L"\""); - } - public: - static void ReplaceSpecialCharacters(std::wstring& wsString) - { - ReplaceAll(wsString, L"&", L"&"); - ReplaceAll(wsString, L"<", L"<"); - ReplaceAll(wsString, L">", L">"); - ReplaceAll(wsString, L"\"", L"""); - ReplaceAll(wsString, L"'", L"'"); - } - static void ReplaceAll(std::wstring& wsSrc, const std::wstring& wsFrom, const std::wstring& wsTo) - { - if (wsFrom.empty()) - return; - - int nFromLen = wsFrom.length(); - int nToLen = wsTo.length(); - - size_t nStartPos = 0; - while (std::string::npos != (nStartPos = wsSrc.find(wsFrom, nStartPos))) - { - wsSrc.replace(nStartPos, nFromLen, wsTo); - nStartPos += nToLen; - } - } - - private: - - std::wstring m_wsXml; - - }; - - class CBase64 - { - public: - - void Encode(unsigned char* pSrc, int nSrcLen) - { - m_sBuffer.clear(); - int nRequiredLen = NSBase64::Base64EncodeGetRequiredLength(nSrcLen); - if (0 == nRequiredLen) - return; - - unsigned char* pDst = new unsigned char[nRequiredLen + 1]; - if (!pDst) - return; - - pDst[nRequiredLen] = 0x00; - - int nDstLen; - NSBase64::Base64Encode(pSrc, nSrcLen, pDst, &nDstLen); - m_sBuffer.append((char*)pDst); - delete[] pDst; - } - std::string& GetString() - { - return m_sBuffer; - } - const char* GetCString() - { - return m_sBuffer.c_str(); - } - - private: - - std::string m_sBuffer; - }; -} - -#endif // _PDF_READER_XML_UTILS_H \ No newline at end of file diff --git a/PdfReader/old/Annot.cpp b/PdfReader/old/Annot.cpp deleted file mode 100644 index 5e5de46705..0000000000 --- a/PdfReader/old/Annot.cpp +++ /dev/null @@ -1,1826 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "List.h" -#include "Object.h" -#include "Catalog.h" -#include "Graphics.h" -#include "GFont.h" -#include "Lexer.h" -#include "Annot.h" -#include "Dict.h" - -//------------------------------------------------------------------------------------------------------------------------------- - -#define annotFlagHidden 0x0002 -#define annotFlagPrint 0x0004 -#define annotFlagNoView 0x0020 - -#define fieldFlagReadOnly 0x00000001 -#define fieldFlagRequired 0x00000002 -#define fieldFlagNoExport 0x00000004 -#define fieldFlagMultiline 0x00001000 -#define fieldFlagPassword 0x00002000 -#define fieldFlagNoToggleToOff 0x00004000 -#define fieldFlagRadio 0x00008000 -#define fieldFlagPushbutton 0x00010000 -#define fieldFlagCombo 0x00020000 -#define fieldFlagEdit 0x00040000 -#define fieldFlagSort 0x00080000 -#define fieldFlagFileSelect 0x00100000 -#define fieldFlagMultiSelect 0x00200000 -#define fieldFlagDoNotSpellCheck 0x00400000 -#define fieldFlagDoNotScroll 0x00800000 -#define fieldFlagComb 0x01000000 -#define fieldFlagRichText 0x02000000 -#define fieldFlagRadiosInUnison 0x02000000 -#define fieldFlagCommitOnSelChange 0x04000000 - -#define fieldQuadLeft 0 -#define fieldQuadCenter 1 -#define fieldQuadRight 2 - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // AnnotBorderStyle - //------------------------------------------------------------------------------------------------------------------------------- - AnnotBorderStyle::AnnotBorderStyle(AnnotBorderType eType, double dWidth, double *pDash, int nDashLength, double dR, double dG, double dB) - { - m_eType = eType; - m_dWidth = dWidth; - m_pDash = pDash; - m_nDashLength = nDashLength; - m_dR = dR; - m_dG = dG; - m_dB = dB; - } - AnnotBorderStyle::~AnnotBorderStyle() - { - MemUtilsFree(m_pDash); - } - //------------------------------------------------------------------------------------------------------------------------------- - // Annot - //------------------------------------------------------------------------------------------------------------------------------- - Annot::Annot(GlobalParams *pGlobalParams, XRef *pXref, Dict *pAcroForm, Dict *pDict, Ref *pRef) - { - m_pGlobalParams = pGlobalParams; - - m_bValid = true; - m_pXref = pXref; - m_oRef = *pRef; - m_seType = NULL; - m_seAppBuffer = NULL; - m_pBorderStyle = NULL; - - // SubType - Object oDictItem; - if (pDict->Search("Subtype", &oDictItem)->IsName()) - { - m_seType = new StringExt(oDictItem.GetName()); - } - oDictItem.Free(); - - // Rect - if (pDict->Search("Rect", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4) - { - Object oTemp; - m_dMinX = m_dMinY = m_dMaxX = m_dMaxY = 0; - if (oDictItem.ArrayGet(0, &oTemp)->IsNum()) - { - m_dMinX = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.ArrayGet(1, &oTemp)->IsNum()) - { - m_dMinY = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.ArrayGet(2, &oTemp)->IsNum()) - { - m_dMaxX = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.ArrayGet(3, &oTemp)->IsNum()) - { - m_dMaxY = oTemp.GetNum(); - } - oTemp.Free(); - - if (m_dMinX > m_dMaxX) - { - double dTemp = m_dMinX; - m_dMinX = m_dMaxX; - m_dMaxX = dTemp; - } - - if (m_dMinY > m_dMaxY) - { - double dTemp = m_dMinY; - m_dMinY = m_dMaxY; - m_dMaxY = dTemp; - } - } - else - { - // TO DO: Error "Bad bounding box for annotation" - m_bValid = false; - } - oDictItem.Free(); - - // F (flags) - if (pDict->Search("F", &oDictItem)->IsInt()) - { - m_nFlags = oDictItem.GetInt(); - } - else - { - m_nFlags = 0; - } - oDictItem.Free(); - - //Border style - AnnotBorderType eBorderType = annotBorderSolid; - double dBorderWidth = 1; - double *pBorderDash = NULL; - int nBorderDashLength = 0; - double dBorderR = 0; - double dBorderG = 0; - double dBorderB = 1; - if (pDict->Search("BS", &oDictItem)->IsDict()) - { - Object oTemp; - if (oDictItem.DictLookup("S", &oTemp)->IsName()) - { - if (oTemp.IsName("S")) - { - eBorderType = annotBorderSolid; - } - else if (oTemp.IsName("D")) - { - eBorderType = annotBorderDashed; - } - else if (oTemp.IsName("B")) - { - eBorderType = annotBorderBeveled; - } - else if (oTemp.IsName("I")) - { - eBorderType = annotBorderInset; - } - else if (oTemp.IsName("U")) - { - eBorderType = annotBorderUnderlined; - } - } - oTemp.Free(); - - if (oDictItem.DictLookup("W", &oTemp)->IsNum()) - { - dBorderWidth = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.DictLookup("D", &oTemp)->IsArray()) - { - nBorderDashLength = oTemp.ArrayGetLength(); - pBorderDash = (double *)MemUtilsMallocArray(nBorderDashLength, sizeof(double)); - - for (int nIndex = 0; nIndex < nBorderDashLength; ++nIndex) - { - Object oArrayItem; - if (oTemp.ArrayGet(nIndex, &oArrayItem)->IsNum()) - { - pBorderDash[nIndex] = oArrayItem.GetNum(); - } - else - { - pBorderDash[nIndex] = 1; - } - oArrayItem.Free(); - } - } - oTemp.Free(); - } - else - { - oDictItem.Free(); - if (pDict->Search("Border", &oDictItem)->IsArray()) - { - Object oTemp; - if (oDictItem.ArrayGetLength() >= 3) - { - if (oDictItem.ArrayGet(2, &oTemp)->IsNum()) - { - dBorderWidth = oTemp.GetNum(); - } - oTemp.Free(); - if (oDictItem.ArrayGetLength() >= 4) - { - if (oDictItem.ArrayGet(3, &oTemp)->IsArray()) - { - eBorderType = annotBorderDashed; - nBorderDashLength = oTemp.ArrayGetLength(); - pBorderDash = (double *)MemUtilsMallocArray(nBorderDashLength, sizeof(double)); - - for (int nIndex = 0; nIndex < nBorderDashLength; ++nIndex) - { - Object oArrayItem; - if (oTemp.ArrayGet(nIndex, &oArrayItem)->IsNum()) - { - pBorderDash[nIndex] = oArrayItem.GetNum(); - } - else - { - pBorderDash[nIndex] = 1; - } - oArrayItem.Free(); - } - } - else - { - dBorderWidth = 0; - } - oTemp.Free(); - } - } - } - } - oDictItem.Free(); - - // C (border color) - // TO DO: надо сделать чтение случаев, когда в массике не только 3 элемента, а 0, 1, 3, 4 - if (pDict->Search("C", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 3) - { - Object oTemp; - if (oDictItem.ArrayGet(0, &oTemp)->IsNum()) - { - dBorderR = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.ArrayGet(1, &oTemp)->IsNum()) - { - dBorderG = oTemp.GetNum(); - } - oTemp.Free(); - - if (oDictItem.ArrayGet(2, &oTemp)->IsNum()) - { - dBorderB = oTemp.GetNum(); - } - oTemp.Free(); - } - oDictItem.Free(); - - m_pBorderStyle = new AnnotBorderStyle(eBorderType, dBorderWidth, pBorderDash, nBorderDashLength, dBorderR, dBorderG, dBorderB); - - // AP (appereance) - Object oAP; - if (pDict->Search("AP", &oAP)->IsDict()) - { - Object oAS; - if (pDict->Search("AS", &oAS)->IsName()) - { - Object oItem; - if (oAP.DictLookup("N", &oItem)->IsDict()) - { - Object oTemp; - if (oItem.DictLookupAndCopy(oAS.GetName(), &oTemp)->IsRef()) - { - oTemp.Copy(&m_oAppearance); - m_bValid = true; - } - else - { - oTemp.Free(); - if (oItem.DictLookupAndCopy("Off", &oTemp)->IsRef()) - { - oTemp.Copy(&m_oAppearance); - } - } - oTemp.Free(); - } - oItem.Free(); - } - else - { - Object oItem; - if (oAP.DictLookupAndCopy("N", &oItem)->IsRef()) - { - oItem.Copy(&m_oAppearance); - } - oItem.Free(); - } - oAS.Free(); - } - oAP.Free(); - } - Annot::~Annot() - { - if (m_seType) - { - delete m_seType; - } - m_oAppearance.Free(); - - if (m_seAppBuffer) - { - delete m_seAppBuffer; - } - if (m_pBorderStyle) - { - delete m_pBorderStyle; - } - } - void Annot::GenerateFieldAppearance(Dict *pField, Dict *pAnnot, Dict *pAcroForm) - { - // Тип Annotation должен быть Widget - if (m_seType->Compare("Widget")) - { - return; - } - - m_seAppBuffer = new StringExt(); - - // Appearance characteristics (MK) dictionary - Object oMKObject; - Dict *pMKDict; - if (pAnnot->Search("MK", &oMKObject)->IsDict()) - { - pMKDict = oMKObject.GetDict(); - } - else - { - pMKDict = NULL; - } - - // Рисуем фон (BackGround) - Object oDictItem; - if (pMKDict) - { - if (pMKDict->Search("BG", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() > 0) - { - SetColor(oDictItem.GetArray(), true, 0); - m_seAppBuffer->AppendFormat("0 0 {0:.2f} {1:.2f} re f\n", m_dMaxX - m_dMinX, m_dMaxY - m_dMinY); - } - oDictItem.Free(); - } - - // Считываем тип поля - // FT (File Type) - Object oFTobject; - FieldLookup(pField, "FT", &oFTobject); - - // Ff (Filed flags) - int nFiledFlags = 0; - if (FieldLookup(pField, "Ff", &oDictItem)->IsInt()) - { - nFiledFlags = oDictItem.GetInt(); - } - else - { - nFiledFlags = 0; - } - oDictItem.Free(); - - // Рисуем рамку - if (pMKDict) - { - double dWidth = m_pBorderStyle->GetWidth(); - if (dWidth > 0) - { - // BC (Border Color), если такого поля нет, тогда используем цвет из BG - pMKDict->Search("BC", &oDictItem); - if (!(oDictItem.IsArray() && oDictItem.ArrayGetLength() > 0)) - { - pMKDict->Search("BG", &oDictItem); - } - if (oDictItem.IsArray() && oDictItem.ArrayGetLength() > 0) - { - double dDx = m_dMaxX - m_dMinX; - double dDy = m_dMaxY - m_dMinY; - double *pDash; - int nDashLength = 0; - - Object oTemp; - bool bHasCaption = pMKDict->Search("CA", &oTemp)->IsString(); - oTemp.Free(); - - if (oFTobject.IsName("Btn") && (nFiledFlags & fieldFlagRadio) && !bHasCaption) - { - double dRad = 0.5 * (dDx < dDy ? dDx : dDy); - switch (m_pBorderStyle->GetType()) - { - case annotBorderDashed: - m_seAppBuffer->Append("["); - m_pBorderStyle->GetDash(&pDash, &nDashLength); - for (int nIndex = 0; nIndex < nDashLength; ++nIndex) - { - m_seAppBuffer->AppendFormat(" {0:.2f}", pDash[nIndex]); - } - m_seAppBuffer->Append("] 0 d\n"); - // Дальше как в случае не пунктирной линии - case annotBorderSolid: - case annotBorderUnderlined: - m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth); - SetColor(oDictItem.GetArray(), false, 0); - DrawCircle(0.5 * dDx, 0.5 * dDy, dRad - 0.5 * dWidth, false); - break; - case annotBorderBeveled: - case annotBorderInset: - m_seAppBuffer->AppendFormat("{0:.2f} w\n", 0.5 * dWidth); - - SetColor(oDictItem.GetArray(), false, 0); - DrawCircle(0.5 * dDx, 0.5 * dDy, dRad - 0.25 * dWidth, false); - - SetColor(oDictItem.GetArray(), false, m_pBorderStyle->GetType() == annotBorderBeveled ? 1 : -1); - DrawCircleTopLeft(0.5 * dDx, 0.5 * dDy, dRad - 0.75 * dWidth); - - SetColor(oDictItem.GetArray(), false, m_pBorderStyle->GetType() == annotBorderBeveled ? -1 : 1); - DrawCircleBottomRight(0.5 * dDx, 0.5 * dDy, dRad - 0.75 * dWidth); - break; - } - } - else - { - switch (m_pBorderStyle->GetType()) - { - case annotBorderDashed: - m_seAppBuffer->Append("["); - m_pBorderStyle->GetDash(&pDash, &nDashLength); - for (int nIndex = 0; nIndex < nDashLength; ++nIndex) - { - m_seAppBuffer->AppendFormat(" {0:.2f}", pDash[nIndex]); - } - m_seAppBuffer->Append("] 0 d\n"); - // Дальше как в случае не пунктирной линии - case annotBorderSolid: - m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth); - SetColor(oDictItem.GetArray(), false, 0); - m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n", 0.5 * dWidth, dDx - dWidth, dDy - dWidth); - break; - case annotBorderBeveled: - case annotBorderInset: - - SetColor(oDictItem.GetArray(), true, m_pBorderStyle->GetType() == annotBorderBeveled ? 1 : -1); - m_seAppBuffer->Append("0 0 m\n"); - m_seAppBuffer->AppendFormat("0 {0:.2f} l\n", dDy); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx, dDy); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dDy - dWidth); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dWidth, dDy - dWidth); - m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} l\n", dWidth); - m_seAppBuffer->Append("f\n"); - - SetColor(oDictItem.GetArray(), true, m_pBorderStyle->GetType() == annotBorderBeveled ? -1 : 1); - m_seAppBuffer->Append("0 0 m\n"); - m_seAppBuffer->AppendFormat("{0:.2f} 0 l\n", dDx); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx, dDy); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dDy - dWidth); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} l\n", dDx - dWidth, dWidth); - m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} l\n", dWidth); - m_seAppBuffer->Append("f\n"); - break; - case annotBorderUnderlined: - m_seAppBuffer->AppendFormat("{0:.2f} w\n", dWidth); - SetColor(oDictItem.GetArray(), false, 0); - m_seAppBuffer->AppendFormat("0 0 m {0:.2f} 0 l s\n", dDx); - break; - } - m_seAppBuffer->AppendFormat("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", dWidth, dDx - 2 * dWidth, dDy - 2 * dWidth); - } - } - oDictItem.Free(); - } - } - - // DR - Object oDRobject; - pAcroForm->Search("DR", &oDRobject); - - // Font dictionary - GrFontDict *pFontDict; - if (oDRobject.IsDict() && oDRobject.DictLookup("Font", &oDictItem)->IsDict()) - { - pFontDict = new GrFontDict(m_pXref, NULL, oDictItem.GetDict(), m_pGlobalParams); - } - else - { - pFontDict = NULL; - } - oDictItem.Free(); - - // DA (Default appereance string) - StringExt *seDA; - if (FieldLookup(pField, "DA", &oDictItem)->IsNull()) - { - oDictItem.Free(); - pAcroForm->Search("DA", &oDictItem); - } - if (oDictItem.IsString()) - { - seDA = oDictItem.GetString()->Copy(); - } - else - { - seDA = NULL; - } - oDictItem.Free(); - - // Рисуем содержимео Filed - if (oFTobject.IsName("Btn")) - { - StringExt *seCaption = NULL; - if (pMKDict) - { - if (pMKDict->Search("CA", &oDictItem)->IsString()) - { - seCaption = oDictItem.GetString()->Copy(); - } - oDictItem.Free(); - } - - // Radio button - if (nFiledFlags & fieldFlagRadio) - { - // Акробат не рисует Caption, если нет AP - if (FieldLookup(pField, "V", &oDictItem)->IsName()) - { - Object oAppStream; - if (pAnnot->Search("AS", &oAppStream)->IsName(oDictItem.GetName())) - { - if (seCaption) - { - DrawText(seCaption, seDA, pFontDict, false, 0, fieldQuadCenter, false, true); - } - else - { - if (pMKDict) - { - Object oTemp; - if (pMKDict->Search("BC", &oTemp)->IsArray() && oTemp.ArrayGetLength() > 0) - { - double dDx = m_dMaxX - m_dMinX; - double dDy = m_dMaxY - m_dMinY; - SetColor(oTemp.GetArray(), true, 0); - DrawCircle(0.5 * dDx, 0.5 * dDy, 0.2 * (dDx < dDy ? dDx : dDy), true); - } - oTemp.Free(); - } - } - } - oAppStream.Free(); - } - oDictItem.Free(); - } - else if (nFiledFlags & fieldFlagPushbutton) // PushButton - { - if (seCaption) - { - DrawText(seCaption, seDA, pFontDict, false, 0, fieldQuadCenter, false, false); - } - } - else // CheckBox - { - // "Yes" - для включенного состояние, "off" - для выключенного. - if (FieldLookup(pField, "V", &oDictItem)->IsName("Yes")) - { - if (!seCaption) - { - seCaption = new StringExt("3"); // ZapfDingbats checkmark - } - DrawText(seCaption, seDA, pFontDict, false, 0, fieldQuadCenter, false, true); - } - oDictItem.Free(); - } - if (seCaption) - { - delete seCaption; - } - } - else if (oFTobject.IsName("Tx")) - { - // Строковые значения могут быть юникодными - Object oValue; - if (FieldLookup(pField, "V", &oValue)->IsString()) - { - Object oTemp; - bool isDefault = (FieldLookup(pField, "DV", &oTemp)->IsString() && !oTemp.GetString()->Compare(oValue.GetString())); - oTemp.Free(); - if (!isDefault) - { - int nQuadding = 0; - if (FieldLookup(pField, "Q", &oTemp)->IsInt()) - { - nQuadding = oTemp.GetInt(); - } - else - { - nQuadding = fieldQuadLeft; - } - oTemp.Free(); - int nComb = 0; - if (nFiledFlags & fieldFlagComb) - { - if (FieldLookup(pField, "MaxLen", &oTemp)->IsInt()) - { - nComb = oTemp.GetInt(); - } - oTemp.Free(); - } - DrawText(oValue.GetString(), seDA, pFontDict, 0 != (nFiledFlags & fieldFlagMultiline), nComb, nQuadding, true, false); - } - } - oValue.Free(); - } - else if (oFTobject.IsName("Ch")) - { - // Строковые значения могут быть юникодными - int nQuadding = 0; - Object oTemp; - if (FieldLookup(pField, "Q", &oTemp)->IsInt()) - { - nQuadding = oTemp.GetInt(); - } - else - { - nQuadding = fieldQuadLeft; - } - oTemp.Free(); - - // ComboBox - if (nFiledFlags & fieldFlagCombo) - { - Object oValue; - if (FieldLookup(pField, "V", &oValue)->IsString()) - { - DrawText(oValue.GetString(), seDA, pFontDict, false, 0, nQuadding, true, false); - //~ Acrobat draws a popup icon on the right side - } - oValue.Free(); - } - else // ListBox - { - Object oOptions; - if (pField->Search("Opt", &oOptions)->IsArray()) - { - int nOptionsCount = oOptions.ArrayGetLength(); - // Option text - StringExt **ppText = (StringExt **)MemUtilsMallocArray(nOptionsCount, sizeof(StringExt *)); - for (int nIndex = 0; nIndex < nOptionsCount; ++nIndex) - { - ppText[nIndex] = NULL; - Object oTemp; - oOptions.ArrayGet(nIndex, &oTemp); - if (oTemp.IsString()) - { - ppText[nIndex] = oTemp.GetString()->Copy(); - } - else if (oTemp.IsArray() && oTemp.ArrayGetLength() == 2) - { - Object oArrayItem; - if (oTemp.ArrayGet(1, &oArrayItem)->IsString()) - { - ppText[nIndex] = oArrayItem.GetString()->Copy(); - } - oArrayItem.Free(); - } - oTemp.Free(); - if (!ppText[nIndex]) - { - ppText[nIndex] = new StringExt(); - } - } - // Selected option(s) - bool *pSelection = (bool *)MemUtilsMallocArray(nOptionsCount, sizeof(bool)); - //~ need to use the I field in addition to the V field - Object oValue; - FieldLookup(pField, "V", &oValue); - for (int nIndex = 0; nIndex < nOptionsCount; ++nIndex) - { - pSelection[nIndex] = false; - if (oValue.IsString()) - { - if (!oValue.GetString()->Compare(ppText[nIndex])) - { - pSelection[nIndex] = true; - } - } - else if (oValue.IsArray()) - { - for (int nJ = 0; nJ < oValue.ArrayGetLength(); ++nJ) - { - Object oTemp; - if (oValue.ArrayGet(nJ, &oTemp)->IsString() && !oTemp.GetString()->Compare(ppText[nIndex])) - { - pSelection[nIndex] = true; - } - oTemp.Free(); - } - } - } - oValue.Free(); - - // TI (Top Index) - int nTopIndex = 0; - if (pField->Search("TI", &oValue)->IsInt()) - { - nTopIndex = oValue.GetInt(); - } - else - { - nTopIndex = 0; - } - oValue.Free(); - - DrawListBox(ppText, pSelection, nOptionsCount, nTopIndex, seDA, pFontDict, nQuadding); - for (int nIndex = 0; nIndex < nOptionsCount; ++nIndex) - { - delete ppText[nIndex]; - } - MemUtilsFree(ppText); - MemUtilsFree(pSelection); - } - oOptions.Free(); - } - } - else if (oFTobject.IsName("Sig")) - { - //~unimp - } - else - { - // TO DO: Error "Unknown field type" - } - - if (seDA) - { - delete seDA; - } - - // Appearance stream dictionary - Object oAppearanceDict; - - oAppearanceDict.InitDict(m_pXref); - oAppearanceDict.DictAdd(CopyString("Length"), oDictItem.InitInt(m_seAppBuffer->GetLength())); - oAppearanceDict.DictAdd(CopyString("Subtype"), oDictItem.InitName("Form")); - oDictItem.InitArray(m_pXref); - Object oTemp; - oDictItem.ArrayAdd(oTemp.InitReal(0)); - oDictItem.ArrayAdd(oTemp.InitReal(0)); - oDictItem.ArrayAdd(oTemp.InitReal(m_dMaxX - m_dMinX)); - oDictItem.ArrayAdd(oTemp.InitReal(m_dMaxY - m_dMinY)); - oAppearanceDict.DictAdd(CopyString("BBox"), &oDictItem); - - // Resource dictionary - if (oDRobject.IsDict()) - { - oAppearanceDict.DictAdd(CopyString("Resources"), oDRobject.Copy(&oDictItem)); - } - oDRobject.Free(); - - // Appearance stream - MemoryStream *pAppearStream = new MemoryStream(m_seAppBuffer->GetBuffer(), 0, m_seAppBuffer->GetLength(), &oAppearanceDict); - m_oAppearance.Free(); - m_oAppearance.InitStream(pAppearStream); - - if (pFontDict) - { - delete pFontDict; - } - oFTobject.Free(); - oMKObject.Free(); - } - - // Устанавливаем цвет для заливки или обводки; цвет здается массиом (в котором должно быть - // 1, 3, или 4 элемента). Если равно +1, цвет color is высветляется, если равно - // -1, цвет затемняется, в противном случае, цвет не меняется. - void Annot::SetColor(Array *pArray, bool bFill, int nAdjust) - { - double arrColor[4]; - - int nComponentsCount = pArray->GetCount(); - if (nComponentsCount > 4) - { - nComponentsCount = 4; - } - for (int nIndex = 0; nIndex < nComponentsCount && nIndex < 4; ++nIndex) - { - Object oTemp; - if (pArray->Get(nIndex, &oTemp)->IsNum()) - { - arrColor[nIndex] = oTemp.GetNum(); - } - else - { - arrColor[nIndex] = 0; - } - oTemp.Free(); - } - if (4 == nComponentsCount) - { - nAdjust = -nAdjust; - } - if (nAdjust > 0) - { - for (int nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - arrColor[nIndex] = 0.5 * arrColor[nIndex] + 0.5; - } - } - else if (nAdjust < 0) - { - for (int nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - arrColor[nIndex] = 0.5 * arrColor[nIndex]; - } - } - if (4 == nComponentsCount) - { - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n", arrColor[0], arrColor[1], arrColor[2], arrColor[3], bFill ? 'k' : 'K'); - } - else if (3 == nComponentsCount) - { - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:s}\n", arrColor[0], arrColor[1], arrColor[2], bFill ? "rg" : "RG"); - } - else - { - m_seAppBuffer->AppendFormat("{0:.2f} {1:c}\n", arrColor[0], bFill ? 'g' : 'G'); - } - } - - // Рисуем текст или название для Field. - void Annot::DrawText(StringExt *seText, StringExt *seDA, GrFontDict *pFontDict, bool bMultiline, int nComb, int nQuadding, bool bTextField, bool bForceZapfDingbats) - { - CList *pListDA; - StringExt *seToken; - double dX, dY, dWidth; - int i, j, k, nChar; - - // Парсим Default Appearance string - - int nTfPos = -1, nTmPos = -1; - if (seDA) - { - pListDA = new CList(); - i = 0; - while (i < seDA->GetLength()) - { - while (i < seDA->GetLength() && Lexer::IsSpace(seDA->GetAt(i))) - { - ++i; - } - if (i < seDA->GetLength()) - { - for (j = i + 1; j < seDA->GetLength() && !Lexer::IsSpace(seDA->GetAt(j)); ++j); - pListDA->Append(new StringExt(seDA, i, j - i)); - i = j; - } - } - for (i = 2; i < pListDA->GetLength(); ++i) - { - if (i >= 2 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tf")) - { - nTfPos = i - 2; - } - else if (i >= 6 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tm")) - { - nTmPos = i - 6; - } - } - } - else - { - pListDA = NULL; - } - - // ZapfDingbats - if (bForceZapfDingbats) - { - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos); - if (seToken->Compare("/ZaDb")) - { - seToken->Clear(); - seToken->Append("/ZaDb"); - } - } - } - - // Считываем шрифт и размер шрифта - GrFont *pFont = NULL; - double dFontSize = 0; - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos); - if (seToken->GetLength() >= 1 && seToken->GetAt(0) == '/') - { - if (!pFontDict || !(pFont = pFontDict->Search(seToken->GetBuffer() + 1))) - { - // TO DO: Error "Unknown font in field's DA string" - } - } - else - { - // TO DO: Error "Invalid font name in 'Tf' operator in field's DA string" - } - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - dFontSize = atof(seToken->GetBuffer()); - } - else - { - // TO DO: Error "Missing 'Tf' operator in field's DA string" - } - - // Border Width - double dBorderWidth = m_pBorderStyle->GetWidth(); - - if (bTextField) - { - m_seAppBuffer->Append("/Tx BMC\n"); - } - m_seAppBuffer->Append("q\n"); - m_seAppBuffer->Append("BT\n"); - - // Многострочный текст - if (bMultiline) - { - // Флаги nComb игнорируются в многострочном тексте - - double dWMax = m_dMaxX - m_dMinX - 2 * dBorderWidth - 4; - - // Вычислим размер шрифта (если он не был установлен) - if (0 == dFontSize) - { - for (dFontSize = 20; dFontSize > 1; --dFontSize) - { - dY = m_dMaxY - m_dMinY; - double dMaxLineWidth = 0; - i = 0; - while (i < seText->GetLength()) - { - GetNextLine(seText, i, pFont, dFontSize, dWMax, &j, &dWidth, &k); - if (dWidth > dMaxLineWidth) - { - dMaxLineWidth = dWidth; - } - i = k; - dY -= dFontSize; - } - - if (dY >= 0.33 * dFontSize) - { - break; - } - } - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dFontSize); - } - } - - // Начальная координата Y - // (Каждая новая линий начинается с оператора Td) - dY = m_dMaxY - m_dMinY; - - // Font Matrix - if (nTmPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 4); - seToken->Clear(); - seToken->Append('0'); - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 5); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dY); - } - - // Пишем DA-string - if (pListDA) - { - for (i = 0; i < pListDA->GetLength(); ++i) - { - m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' '); - } - } - - // Пишем Font Matrix (если она не была уже в DA-string) - if (nTmPos < 0) - { - m_seAppBuffer->AppendFormat("1 0 0 1 0 {0:.2f} Tm\n", dY); - } - - i = 0; - double dPrevX = 0; - while (i < seText->GetLength()) - { - GetNextLine(seText, i, pFont, dFontSize, dWMax, &j, &dWidth, &k); - // Вычислим начальную позицию текста - switch (nQuadding) - { - case fieldQuadLeft: - default: - dX = dBorderWidth + 2; - break; - case fieldQuadCenter: - dX = (m_dMaxX - m_dMinX - dWidth) / 2; - break; - case fieldQuadRight: - dX = m_dMaxX - m_dMinX - dBorderWidth - 2 - dWidth; - break; - } - - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} Td\n", dX - dPrevX, -dFontSize); - m_seAppBuffer->Append('('); - for (; i < j; ++i) - { - nChar = seText->GetAt(i) & 0xff; - if (nChar == '(' || nChar == ')' || nChar == '\\') - { - m_seAppBuffer->Append('\\'); - m_seAppBuffer->Append(nChar); - } - else if (nChar < 0x20 || nChar >= 0x80) - { - m_seAppBuffer->AppendFormat("\\{0:03o}", nChar); - } - else - { - m_seAppBuffer->Append(nChar); - } - } - m_seAppBuffer->Append(") Tj\n"); - - // Следующая строка - i = k; - dPrevX = dX; - } - - } - else // Однострочный текст - { - if (nComb > 0) - { - dWidth = (m_dMaxX - m_dMinX - 2 * dBorderWidth) / nComb; - - // Вычислим размер шрифта (если он не был установлен) - if (0 == dFontSize) - { - dFontSize = m_dMaxY - m_dMinY - 2 * dBorderWidth; - if (dWidth < dFontSize) - { - dFontSize = dWidth; - } - dFontSize = floor(dFontSize); - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dFontSize); - } - } - - // Вычислим начальную позицию текста - switch (nQuadding) - { - case fieldQuadLeft: - default: - dX = dBorderWidth + 2; - break; - case fieldQuadCenter: - dX = dBorderWidth + 2 + 0.5 * (nComb - seText->GetLength()) * dWidth; - break; - case fieldQuadRight: - dX = dBorderWidth + 2 + (nComb - seText->GetLength()) * dWidth; - break; - } - dY = 0.5 * (m_dMaxY - m_dMinY) - 0.4 * dFontSize; - - // Font Matrix - if (nTmPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 4); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dX); - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 5); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dY); - } - - // DA-string - if (pListDA) - { - for (i = 0; i < pListDA->GetLength(); ++i) - { - m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' '); - } - } - - // Пишем Font Matrix (если она не была уже в DA-string) - if (nTmPos < 0) - { - m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY); - } - - // write the text string - //~ this should center (instead of left-justify) each character within - //~ its comb cell - for (i = 0; i < seText->GetLength(); ++i) - { - if (i > 0) - { - m_seAppBuffer->AppendFormat("{0:.2f} 0 Td\n", dWidth); - } - m_seAppBuffer->Append('('); - nChar = seText->GetAt(i) & 0xff; - if (nChar == '(' || nChar == ')' || nChar == '\\') - { - m_seAppBuffer->Append('\\'); - m_seAppBuffer->Append(nChar); - } - else if (nChar < 0x20 || nChar >= 0x80) - { - m_seAppBuffer->AppendFormat("{0:.2f} 0 Td\n", dWidth); - } - else - { - m_seAppBuffer->Append(nChar); - } - m_seAppBuffer->Append(") Tj\n"); - } - } - else // обычное форматирование (non-comb) - { - // Вычислим ширину строки - if (pFont && !pFont->IsCIDFont()) - { - dWidth = 0; - for (i = 0; i < seText->GetLength(); ++i) - { - dWidth += ((Gr8BitFont *)pFont)->GetWidth(seText->GetAt(i)); - } - } - else - { - dWidth = seText->GetLength() * 0.5; - } - - // Вычислим размер шрифта (если он не был установлен) - if (0 == dFontSize) - { - dFontSize = m_dMaxY - m_dMinY - 2 * dBorderWidth; - double dTempFontSize = (m_dMaxX - m_dMinX - 4 - 2 * dBorderWidth) / dWidth; - if (dTempFontSize < dFontSize) - { - dFontSize = dTempFontSize; - } - dFontSize = floor(dFontSize); - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dFontSize); - } - } - - // Вычислим начальную позицию текста - dWidth *= dFontSize; - switch (nQuadding) - { - case fieldQuadLeft: - default: - dX = dBorderWidth + 2; - break; - case fieldQuadCenter: - dX = (m_dMaxX - m_dMinX - dWidth) / 2; - break; - case fieldQuadRight: - dX = m_dMaxX - m_dMinX - dBorderWidth - 2 - dWidth; - break; - } - dY = 0.5 * (m_dMaxY - m_dMinY) - 0.4 * dFontSize; - - // Font Matrix - if (nTmPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 4); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dX); - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 5); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dY); - } - - // DA-string - if (pListDA) - { - for (i = 0; i < pListDA->GetLength(); ++i) - { - m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(i))->Append(' '); - } - } - - // Пишем Font Matrix (если она не была уже в DA-string) - if (nTmPos < 0) - { - m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY); - } - - // Пишем текст - m_seAppBuffer->Append('('); - for (i = 0; i < seText->GetLength(); ++i) - { - nChar = seText->GetAt(i) & 0xff; - if (nChar == '(' || nChar == ')' || nChar == '\\') - { - m_seAppBuffer->Append('\\'); - m_seAppBuffer->Append(nChar); - } - else if (nChar < 0x20 || nChar >= 0x80) - { - m_seAppBuffer->AppendFormat("\\{0:03o}", nChar); - } - else - { - m_seAppBuffer->Append(nChar); - } - } - m_seAppBuffer->Append(") Tj\n"); - } - } - - m_seAppBuffer->Append("ET\n"); - m_seAppBuffer->Append("Q\n"); - - if (bTextField) - { - m_seAppBuffer->Append("EMC\n"); - } - - if (pListDA) - { - DeleteCList(pListDA, StringExt); - } - } - - // Рисуем текст или название для Field. - void Annot::DrawListBox(StringExt **ppText, bool *pSelection, int nOptionsCount, int nTopIndex, StringExt *seDA, GrFontDict *pFontDict, int nQuadding) - { - CList *pListDA; - StringExt *seToken; - int i, j; - - // Парсим Default appearance string - int nTfPos = -1, nTmPos = -1; - if (seDA) - { - pListDA = new CList(); - i = 0; - while (i < seDA->GetLength()) - { - while (i < seDA->GetLength() && Lexer::IsSpace(seDA->GetAt(i))) - { - ++i; - } - if (i < seDA->GetLength()) - { - for (j = i + 1; j < seDA->GetLength() && !Lexer::IsSpace(seDA->GetAt(j)); ++j); - pListDA->Append(new StringExt(seDA, i, j - i)); - i = j; - } - } - for (i = 2; i < pListDA->GetLength(); ++i) - { - if (i >= 2 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tf")) - { - nTfPos = i - 2; - } - else if (i >= 6 && !((StringExt *)pListDA->GetByIndex(i))->Compare("Tm")) - { - nTmPos = i - 6; - } - } - } - else - { - pListDA = NULL; - } - - // Считываем шрифт и размер шрифта - GrFont *pFont = NULL; - double dFontSize = 0; - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos); - if (seToken->GetLength() >= 1 && seToken->GetAt(0) == '/') - { - if (!pFontDict || !(pFont = pFontDict->Search(seToken->GetBuffer() + 1))) - { - // TO DO: Error "Unknown font in field's DA string" - } - } - else - { - // TO DO: Error "Invalid font name in 'Tf' operator in field's DA string" - } - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - dFontSize = atof(seToken->GetBuffer()); - } - else - { - // TO DO: Error "Missing 'Tf' operator in field's DA string" - } - - // Border width - double dBorder = m_pBorderStyle->GetWidth(); - - // Вычислим размер фонта, если он не был задан - double dWidth = 0; - if (0 == dFontSize) - { - double dMaxW = 0; - for (i = 0; i < nOptionsCount; ++i) - { - if (pFont && !pFont->IsCIDFont()) - { - dWidth = 0; - for (j = 0; j < ppText[i]->GetLength(); ++j) - { - dWidth += ((Gr8BitFont *)pFont)->GetWidth(ppText[i]->GetAt(j)); - } - } - else - { - // грубая оценка - dWidth = ppText[i]->GetLength() * 0.5; - } - if (dWidth > dMaxW) - { - dMaxW = dWidth; - } - } - dFontSize = m_dMaxY - m_dMinY - 2 * dBorder; - double dFontSize2 = (m_dMaxX - m_dMinX - 4 - 2 * dBorder) / dMaxW; - - if (dFontSize2 < dFontSize) - { - dFontSize = dFontSize2; - } - dFontSize = floor(dFontSize); - - if (nTfPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTfPos + 1); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dFontSize); - } - } - - // Рисуем текст - double dY = m_dMaxY - m_dMinY - 1.1 * dFontSize; - - for (i = nTopIndex; i < nOptionsCount; ++i) - { - m_seAppBuffer->Append("q\n"); - - // Background - if (pSelection[i]) - { - m_seAppBuffer->Append("0 g f\n"); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n", dBorder, dY - 0.2 * dFontSize, m_dMaxX - m_dMinX - 2 * dBorder, 1.1 * dFontSize); - } - - m_seAppBuffer->Append("BT\n"); - - // Вычислим ширину строки - if (pFont && !pFont->IsCIDFont()) - { - dWidth = 0; - for (j = 0; j < ppText[i]->GetLength(); ++j) - { - dWidth += ((Gr8BitFont *)pFont)->GetWidth(ppText[i]->GetAt(j)); - } - } - else - { - // грубая оценка - dWidth = ppText[i]->GetLength() * 0.5; - } - - // Вычислим начальную позицию текста - double dX = 0; - dWidth *= dFontSize; - switch (nQuadding) - { - case fieldQuadLeft: - default: - dX = dBorder + 2; - break; - case fieldQuadCenter: - dX = (m_dMaxX - m_dMinX - dWidth) / 2; - break; - case fieldQuadRight: - dX = m_dMaxX - m_dMinX - dBorder - 2 - dWidth; - break; - } - - // Font Matrix - if (nTmPos >= 0) - { - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 4); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dX); - seToken = (StringExt *)pListDA->GetByIndex(nTmPos + 5); - seToken->Clear(); - seToken->AppendFormat("{0:.2f}", dY); - } - - // DA string - if (pListDA) - { - for (j = 0; j < pListDA->GetLength(); ++j) - { - m_seAppBuffer->Append((StringExt *)pListDA->GetByIndex(j))->Append(' '); - } - } - - // Пишем Font Matrix (если он не был частью DA-string) - if (nTmPos < 0) - { - m_seAppBuffer->AppendFormat("1 0 0 1 {0:.2f} {1:.2f} Tm\n", dX, dY); - } - - if (pSelection[i]) - { - m_seAppBuffer->Append("1 g\n"); - } - - // Пишем текст - m_seAppBuffer->Append('('); - for (j = 0; j < ppText[i]->GetLength(); ++j) - { - int nChar = ppText[i]->GetAt(j) & 0xff; - if (nChar == '(' || nChar == ')' || nChar == '\\') - { - m_seAppBuffer->Append('\\'); - m_seAppBuffer->Append(nChar); - } - else if (nChar < 0x20 || nChar >= 0x80) - { - m_seAppBuffer->AppendFormat("\\{0:03o}", nChar); - } - else - { - m_seAppBuffer->Append(nChar); - } - } - m_seAppBuffer->Append(") Tj\n"); - - m_seAppBuffer->Append("ET\n"); - m_seAppBuffer->Append("Q\n"); - - // Следующая строка - dY -= 1.1 * dFontSize; - } - - if (pListDA) - { - DeleteCList(pListDA, StringExt); - } - } - - void Annot::GetNextLine(StringExt *seText, int nStart, GrFont *pFont, double dFontSize, double dMaxW, int *pEnd, double *pWidth, int *pNext) - { - double dWidth = 0, dTempWidth; - int j, k; - - - for (j = nStart; j < seText->GetLength() && dWidth <= dMaxW; ++j) - { - int nChar = seText->GetAt(j) & 0xff; - if (nChar == 0x0a || nChar == 0x0d) - { - break; - } - if (pFont && !pFont->IsCIDFont()) - { - dTempWidth = ((Gr8BitFont *)pFont)->GetWidth(nChar) * dFontSize; - } - else - { - // грубая оценка - dTempWidth = 0.5 * dFontSize; - } - dWidth += dTempWidth; - } - if (dWidth > dMaxW) - { - for (k = j; k > nStart && seText->GetAt(k - 1) != ' '; --k); - for (; k > nStart && seText->GetAt(k - 1) == ' '; --k); - if (k > nStart) - { - j = k; - } - - if (j == nStart) - { - // Обрабатываем странный случай, когда первый символ слишком широкий для первой строки - j = nStart + 1; - } - } - *pEnd = j; - - // Вычисляем ширину - dWidth = 0; - for (k = nStart; k < j; ++k) - { - if (pFont && !pFont->IsCIDFont()) - { - dTempWidth = ((Gr8BitFont *)pFont)->GetWidth(seText->GetAt(k)) * dFontSize; - } - else - { - dTempWidth = 0.5 * dFontSize; - } - dWidth += dTempWidth; - } - *pWidth = dWidth; - - while (j < seText->GetLength() && seText->GetAt(j) == ' ') - { - ++j; - } - if (j < seText->GetLength() && seText->GetAt(j) == 0x0d) - { - ++j; - } - if (j < seText->GetLength() && seText->GetAt(j) == 0x0a) - { - ++j; - } - *pNext = j; - } - - - // Расстояние от центра до контрольных точек кривой Безье - // = (4 * (sqrt(2) - 1) / 3) * r - #define Kappa 0.55228475 - - // Рисуем окружность с помощью кривых Безье. (dX, dY) - центр, dRad - радиус. - // bFill - будем заливать или обводить? - void Annot::DrawCircle(double dX, double dY, double dRad, bool bFill) - { - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX + dRad, dY); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + dRad, dY + Kappa * dRad, dX + Kappa * dRad, dY + dRad, dX, dY + dRad); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - Kappa * dRad, dY + dRad, dX - dRad, dY + Kappa * dRad, dX - dRad, dY); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - dRad, dY - Kappa * dRad, dX - Kappa * dRad, dY - dRad, dX, dY - dRad); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + Kappa * dRad, dY - dRad, dX + dRad, dY - Kappa * dRad, dX + dRad, dY); - m_seAppBuffer->Append(bFill ? "f\n" : "s\n"); - } - - // Рисуем половину окружности (левую верхнюю) с помощью кривых Безье. (dX, dY) - центр, dRad - радиус. - void Annot::DrawCircleTopLeft(double dX, double dY, double dRad) - { - double dRad2 = dRad / sqrt(2.0); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX + dRad2, dY + dRad2); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + (1 - Kappa) * dRad2, dY + (1 + Kappa) * dRad2, dX - (1 - Kappa) * dRad2, dY + (1 + Kappa) * dRad2, dX - dRad2, dY + dRad2); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - (1 + Kappa) * dRad2, dY + (1 - Kappa) * dRad2, dX - (1 + Kappa) * dRad2, dY - (1 - Kappa) * dRad2, dX - dRad2, dY - dRad2); - m_seAppBuffer->Append("S\n"); - } - - // Рисуем половину окружности (правую нижнюю) с помощью кривых Безье. (dX, dY) - центр, dRad - радиус. - void Annot::DrawCircleBottomRight(double dX, double dY, double dRad) - { - double dRad2 = dRad / sqrt(2.0); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} m\n", dX - dRad2, dY - dRad2); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX - (1 - Kappa) * dRad2, dY - (1 + Kappa) * dRad2, dX + (1 - Kappa) * dRad2, dY - (1 + Kappa) * dRad2, dX + dRad2, dY - dRad2); - m_seAppBuffer->AppendFormat("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n", dX + (1 + Kappa) * dRad2, dY - (1 - Kappa) * dRad2, dX + (1 + Kappa) * dRad2, dY + (1 - Kappa) * dRad2, dX + dRad2, dY + dRad2); - m_seAppBuffer->Append("S\n"); - } - - Object *Annot::FieldLookup(Dict *pField, char *sKey, Object *pObject) - { - Dict *pDict = pField; - if (!pDict->Search(sKey, pObject)->IsNull()) - { - return pObject; - } - pObject->Free(); - - Object oParent; - if (pDict->Search("Parent", &oParent)->IsDict()) - { - FieldLookup(oParent.GetDict(), sKey, pObject); - } - else - { - pObject->InitNull(); - } - oParent.Free(); - return pObject; - } - - void Annot::Draw(Graphics *pGraphics, bool bPrinting) - { - // Flags - if ((m_nFlags & annotFlagHidden) || (bPrinting && !(m_nFlags & annotFlagPrint)) || (!bPrinting && (m_nFlags & annotFlagNoView))) - { - return; - } - - // Appearance stream - bool bIsLink = m_seType && !m_seType->Compare("Link"); - - Object oTemp; - m_oAppearance.Fetch(m_pXref, &oTemp); - pGraphics->DrawAnnotation(&oTemp, (bIsLink ? m_pBorderStyle : (AnnotBorderStyle *)NULL), m_dMinX, m_dMinY, m_dMaxX, m_dMaxY); - oTemp.Free(); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Annots - //------------------------------------------------------------------------------------------------------------------------------- - - Annots::Annots(GlobalParams *pGlobalParams, XRef *pXref, Catalog *pCatalog, Object *pAnnotsObject) - { - m_pGlobalParams = pGlobalParams; - - Annot *pAnnot = NULL; - Ref oRef; - - m_ppAnnots = NULL; - int nSize = 0; - m_nAnnotsCount = 0; - - Dict *pAcroForm = (pCatalog->GetAcroForm()->IsDict() ? pCatalog->GetAcroForm()->GetDict() : NULL); - if (pAnnotsObject->IsArray()) - { - for (int nIndex = 0; nIndex < pAnnotsObject->ArrayGetLength(); ++nIndex) - { - Object oTemp; - if (pAnnotsObject->ArrayGetCopy(nIndex, &oTemp)->IsRef()) - { - oRef = oTemp.GetRef(); - oTemp.Free(); - pAnnotsObject->ArrayGet(nIndex, &oTemp); - } - else - { - oRef.nNum = oRef.nGen = -1; - } - if (oTemp.IsDict()) - { - pAnnot = new Annot(m_pGlobalParams, pXref, pAcroForm, oTemp.GetDict(), &oRef); - if (pAnnot->CheckValidation()) - { - if (m_nAnnotsCount >= nSize) - { - nSize += 16; - m_ppAnnots = (Annot **)MemUtilsReallocArray(m_ppAnnots, nSize, sizeof(Annot *)); - } - m_ppAnnots[m_nAnnotsCount++] = pAnnot; - } - else - { - delete pAnnot; - } - } - oTemp.Free(); - } - } - } - - Annots::~Annots() - { - for (int nIndex = 0; nIndex < m_nAnnotsCount; ++nIndex) - { - delete m_ppAnnots[nIndex]; - } - MemUtilsFree(m_ppAnnots); - } - - void Annots::GenerateAppearances(Dict *pAcroForm) - { - Ref oRef; - - Object oField; - if (pAcroForm->Search("Fields", &oField)->IsArray()) - { - for (int nIndex = 0; nIndex < oField.ArrayGetLength(); ++nIndex) - { - Object oItem; - if (oField.ArrayGetCopy(nIndex, &oItem)->IsRef()) - { - oRef = oItem.GetRef(); - oItem.Free(); - oField.ArrayGet(nIndex, &oItem); - } - else - { - oRef.nNum = oRef.nGen = -1; - } - if (oItem.IsDict()) - { - ScanFieldAppearances(oItem.GetDict(), &oRef, NULL, pAcroForm); - } - oItem.Free(); - } - } - oField.Free(); - } - - void Annots::ScanFieldAppearances(Dict *pNode, Ref *pRef, Dict *pParent, Dict *pAcroForm) - { - Annot *pAnnot = NULL; - Ref oRef2; - - Object oNodeItem; - if (pNode->Search("Kids", &oNodeItem)->IsArray()) - { - for (int nIndex = 0; nIndex < oNodeItem.ArrayGetLength(); ++nIndex) - { - Object oTemp; - if (oNodeItem.ArrayGetCopy(nIndex, &oTemp)->IsRef()) - { - oRef2 = oTemp.GetRef(); - oTemp.Free(); - oNodeItem.ArrayGet(nIndex, &oTemp); - } - else - { - oRef2.nNum = oRef2.nGen = -1; - } - if (oTemp.IsDict()) - { - ScanFieldAppearances(oTemp.GetDict(), &oRef2, pNode, pAcroForm); - } - oTemp.Free(); - } - oNodeItem.Free(); - return; - } - oNodeItem.Free(); - - if ((pAnnot = FindAnnot(pRef))) - { - pNode->SearchAndCopy("Parent", &oNodeItem); - if (!pParent || !oNodeItem.IsNull()) - { - pAnnot->GenerateFieldAppearance(pNode, pNode, pAcroForm); - } - else - { - pAnnot->GenerateFieldAppearance(pParent, pNode, pAcroForm); - } - oNodeItem.Free(); - } - } - - Annot *Annots::FindAnnot(Ref *pRef) - { - for (int nIndex = 0; nIndex < m_nAnnotsCount; ++nIndex) - { - if (m_ppAnnots[nIndex]->Match(pRef)) - { - return m_ppAnnots[nIndex]; - } - } - return NULL; - } -} diff --git a/PdfReader/old/Annot.h b/PdfReader/old/Annot.h deleted file mode 100644 index 39b378d1d8..0000000000 --- a/PdfReader/old/Annot.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_ANNOT_H -#define _PDF_READER_ANNOT_H - -namespace PdfReader -{ - class XRef; - class Catalog; - class Graphics; - class GrFontDict; - - //------------------------------------------------------------------------------------------------------------------------------- - // AnnotBorderStyle - //------------------------------------------------------------------------------------------------------------------------------- - - enum AnnotBorderType - { - annotBorderSolid, - annotBorderDashed, - annotBorderBeveled, - annotBorderInset, - annotBorderUnderlined - }; - - class AnnotBorderStyle - { - public: - - AnnotBorderStyle(AnnotBorderType eType, double dWidth, double *pDash, int nDashLength, double dR, double dG, double dB); - ~AnnotBorderStyle(); - - AnnotBorderType GetType() - { - return m_eType; - } - double GetWidth() - { - return m_dWidth; - } - void GetDash(double **ppDash, int *pnDashLength) - { - *ppDash = m_pDash; - *pnDashLength = m_nDashLength; - } - void GetColor(double *pdR, double *pdG, double *pdB) - { - *pdR = m_dR; - *pdG = m_dG; - *pdB = m_dB; - } - - private: - - AnnotBorderType m_eType; // Тип - double m_dWidth; // Ширина рамки - double *m_pDash; // Если линия пунктирная, тогда определяем длину штриха - int m_nDashLength; // Количество элементов в массиве m_pDash - double m_dR; // - double m_dG; // Цвет - double m_dB; // - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Annot - //------------------------------------------------------------------------------------------------------------------------------- - - class Annot - { - public: - - Annot(GlobalParams *pGlobalParams, XRef *pXref, Dict *pAcroForm, Dict *pDict, Ref *pRef); - ~Annot(); - bool CheckValidation() - { - return m_bValid; - } - - void Draw(Graphics *pGraphics, bool pBrinting); - Object *GetAppearance(Object *pObject) - { - return m_oAppearance.Fetch(m_pXref, pObject); - } - - AnnotBorderStyle *GetBorderStyle() - { - return m_pBorderStyle; - } - - bool Match(Ref *pRef) - { - return m_oRef.nNum == pRef->nNum && m_oRef.nGen == pRef->nGen; - } - - void GenerateFieldAppearance(Dict *pField, Dict *pAnnot, Dict *pAcroForm); - - private: - - void SetColor(Array *pArray, bool bFill, int nAdjust); - void DrawText(StringExt *seText, StringExt *seDA, GrFontDict *pFontDict, bool bMultiline, int nComb, int nQuadding, bool bTextField, bool bForceZapfDingbats); - void DrawListBox(StringExt **ppText, bool *pSelection, int nOptionsCount, int nTopIndex, StringExt *seDA, GrFontDict *pFontDict, int nQuadding); - void GetNextLine(StringExt *seText, int nStart, GrFont *pFont, double dFontSize, double dMaxW, int *pEnd, double *pWidth, int *pNext); - void DrawCircle(double dX, double dY, double dRad, bool bFill); - void DrawCircleTopLeft(double dX, double dY, double dRad); - void DrawCircleBottomRight(double dX, double dY, double dRad); - Object *FieldLookup(Dict *pField, char *sKey, Object *pObject); - - private: - - XRef *m_pXref; // Таблица XRef для данного PDF-документа - Ref m_oRef; // Ссылка на объект, определяющий данной Annotation - StringExt *m_seType; // Тип Annotation - Object m_oAppearance; // Ссылка на Form XObject-поток - StringExt *m_seAppBuffer; - - double m_dMinX; // - double m_dMinY; // Прямоугольник, ограничивающий данную Annotation - double m_dMaxX; // - double m_dMaxY; // - - unsigned int m_nFlags; - AnnotBorderStyle *m_pBorderStyle; - - bool m_bValid; - - GlobalParams *m_pGlobalParams; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Annots - //------------------------------------------------------------------------------------------------------------------------------- - - class Annots - { - public: - - Annots(GlobalParams *pGlobalParams, XRef *pXref, Catalog *pCatalog, Object *pAnnotsObject); - - ~Annots(); - - int GetAnnotsCount() - { - return m_nAnnotsCount; - } - Annot *GetAnnot(int nIndex) - { - return m_ppAnnots[nIndex]; - } - - - void GenerateAppearances(Dict *pAcroForm); - - private: - - void ScanFieldAppearances(Dict *pNode, Ref *pRef, Dict *pParent, Dict *pAcroForm); - Annot *FindAnnot(Ref *pRef); - - private: - Annot **m_ppAnnots; // Список Annotations - int m_nAnnotsCount; // Количество элементов - - GlobalParams *m_pGlobalParams; - }; -} - -#endif // _PDF_READER_ANNOT_H diff --git a/PdfReader/old/Array.cpp b/PdfReader/old/Array.cpp deleted file mode 100644 index 648d01db6a..0000000000 --- a/PdfReader/old/Array.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "Array.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Array - //------------------------------------------------------------------------ - - Array::Array(XRef *pXRef) - { - m_pXRef = pXRef; - m_arrItems = NULL; - m_nItemSize = m_nCount = 0; - m_nRef = 1; - } - - Array::~Array() - { - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - m_arrItems[nIndex].Free(); - MemUtilsFree(m_arrItems); - } - - void Array::Add(Object *pItem) - { - if (m_nCount == m_nItemSize) - { - if (m_nCount == 0) - { - m_nItemSize = 8; - } - else - { - m_nItemSize *= 2; - } - m_arrItems = (Object *)MemUtilsReallocArray(m_arrItems, m_nItemSize, sizeof(Object)); - } - m_arrItems[m_nCount] = *pItem; - ++m_nCount; - } - - Object *Array::Get(int nIndex, Object *pObject) - { - if (nIndex < 0 || nIndex >= m_nCount) - { - return pObject->InitNull(); - } - return m_arrItems[nIndex].Fetch(m_pXRef, pObject); - } - - Object *Array::GetCopy(int nIndex, Object *pObject) - { - if (nIndex < 0 || nIndex >= m_nCount) - { - return pObject->InitNull(); - } - return m_arrItems[nIndex].Copy(pObject); - } -} \ No newline at end of file diff --git a/PdfReader/old/Array.h b/PdfReader/old/Array.h deleted file mode 100644 index e75b2e41da..0000000000 --- a/PdfReader/old/Array.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_ARRAY_H -#define _PDF_READER_ARRAY_H - -#include "Object.h" - -namespace PdfReader -{ - class Object; - class XRef; - - //------------------------------------------------------------------------ - // Array - //------------------------------------------------------------------------ - - class Array - { - public: - - Array(XRef *pXRef); - - ~Array(); - - int AddRef() - { - return ++m_nRef; - } - int Release() - { - return --m_nRef; - } - - - int GetCount() - { - return m_nCount; - } - - - void Add(Object *pItem); - - Object *Get(int nIndex, Object *pObject); - Object *GetCopy(int nIndex, Object *pObject); - - private: - - XRef *m_pXRef; // Таблица Xref для данного PDF документа - Object *m_arrItems; // Массив элементов - int m_nItemSize; // Размер элемента - int m_nCount; // Чилсо элементов в массиве - - int m_nRef; // Счетчик ссылок - }; -} - -#endif // _PDF_READER_ARRAY_H diff --git a/PdfReader/old/BuiltinFont.h b/PdfReader/old/BuiltinFont.h deleted file mode 100644 index 3f86b74fda..0000000000 --- a/PdfReader/old/BuiltinFont.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_BUILT_INFONT_H -#define _PDF_READER_BUILT_INFONT_H - -namespace PdfReader -{ - struct BuiltinFont; - class BuiltinFontWidths; - - //------------------------------------------------------------------------ - struct BuiltinFontWidth - { - char *sName; - unsigned short unWidth; - BuiltinFontWidth *pNext; - }; - - struct BuiltinFont - { - char *sName; - char **ppDefaultBaseEncoding; - short nAscent; - short nDescent; - short arrBBox[4]; - BuiltinFontWidth *pWidths; - int nSize; - }; - - //------------------------------------------------------------------------ - - static bool BuiltinFontGetWidth(BuiltinFont *pFont, char *sName, unsigned short *punWidth) - { - for (int nIndex = 0; nIndex < pFont->nSize; nIndex++) - { - BuiltinFontWidth oWitdh = pFont->pWidths[nIndex]; - if (!strcmp(oWitdh.sName, sName)) - { - *punWidth = oWitdh.unWidth; - return true; - } - } - return false; - } -} - -#endif // _PDF_READER_BUILT_INFONT_H diff --git a/PdfReader/old/BuiltinFontTables.h b/PdfReader/old/BuiltinFontTables.h deleted file mode 100644 index 85837ee989..0000000000 --- a/PdfReader/old/BuiltinFontTables.h +++ /dev/null @@ -1,4307 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_BUILTIN_FONT_TABLES_H -#define _PDF_READER_BUILTIN_FONT_TABLES_H - -#include "BuiltinFont.h" -#include "EncodingTables.h" - -#define BuiltinFontsCount 14 -#define BuiltinFontSubsetsCount 12 - -namespace PdfReader -{ - static BuiltinFontWidth c_arrCourierWidthsTable[] = - { - { "Ntilde", 600, NULL }, - { "rcaron", 600, NULL }, - { "kcommaaccent", 600, NULL }, - { "Ncommaaccent", 600, NULL }, - { "Zacute", 600, NULL }, - { "comma", 600, NULL }, - { "cedilla", 600, NULL }, - { "plusminus", 600, NULL }, - { "circumflex", 600, NULL }, - { "dotaccent", 600, NULL }, - { "edotaccent", 600, NULL }, - { "asciitilde", 600, NULL }, - { "colon", 600, NULL }, - { "onehalf", 600, NULL }, - { "dollar", 600, NULL }, - { "Lcaron", 600, NULL }, - { "ntilde", 600, NULL }, - { "Aogonek", 600, NULL }, - { "ncommaaccent", 600, NULL }, - { "minus", 600, NULL }, - { "Iogonek", 600, NULL }, - { "zacute", 600, NULL }, - { "yen", 600, NULL }, - { "space", 600, NULL }, - { "Omacron", 600, NULL }, - { "questiondown", 600, NULL }, - { "emdash", 600, NULL }, - { "Agrave", 600, NULL }, - { "three", 600, NULL }, - { "numbersign", 600, NULL }, - { "lcaron", 600, NULL }, - { "A", 600, NULL }, - { "B", 600, NULL }, - { "C", 600, NULL }, - { "aogonek", 600, NULL }, - { "D", 600, NULL }, - { "E", 600, NULL }, - { "onequarter", 600, NULL }, - { "F", 600, NULL }, - { "G", 600, NULL }, - { "H", 600, NULL }, - { "I", 600, NULL }, - { "J", 600, NULL }, - { "K", 600, NULL }, - { "iogonek", 600, NULL }, - { "L", 600, NULL }, - { "backslash", 600, NULL }, - { "periodcentered", 600, NULL }, - { "M", 600, NULL }, - { "N", 600, NULL }, - { "omacron", 600, NULL }, - { "Tcommaaccent", 600, NULL }, - { "O", 600, NULL }, - { "P", 600, NULL }, - { "Q", 600, NULL }, - { "Uhungarumlaut", 600, NULL }, - { "R", 600, NULL }, - { "Aacute", 600, NULL }, - { "caron", 600, NULL }, - { "S", 600, NULL }, - { "T", 600, NULL }, - { "U", 600, NULL }, - { "agrave", 600, NULL }, - { "V", 600, NULL }, - { "W", 600, NULL }, - { "equal", 600, NULL }, - { "question", 600, NULL }, - { "X", 600, NULL }, - { "Y", 600, NULL }, - { "Z", 600, NULL }, - { "four", 600, NULL }, - { "a", 600, NULL }, - { "Gcommaaccent", 600, NULL }, - { "b", 600, NULL }, - { "c", 600, NULL }, - { "d", 600, NULL }, - { "e", 600, NULL }, - { "f", 600, NULL }, - { "g", 600, NULL }, - { "bullet", 600, NULL }, - { "h", 600, NULL }, - { "i", 600, NULL }, - { "Oslash", 600, NULL }, - { "dagger", 600, NULL }, - { "j", 600, NULL }, - { "k", 600, NULL }, - { "l", 600, NULL }, - { "m", 600, NULL }, - { "n", 600, NULL }, - { "tcommaaccent", 600, NULL }, - { "o", 600, NULL }, - { "ordfeminine", 600, NULL }, - { "ring", 600, NULL }, - { "p", 600, NULL }, - { "q", 600, NULL }, - { "uhungarumlaut", 600, NULL }, - { "r", 600, NULL }, - { "twosuperior", 600, NULL }, - { "aacute", 600, NULL }, - { "s", 600, NULL }, - { "OE", 600, NULL }, - { "t", 600, NULL }, - { "divide", 600, NULL }, - { "u", 600, NULL }, - { "Ccaron", 600, NULL }, - { "v", 600, NULL }, - { "w", 600, NULL }, - { "x", 600, NULL }, - { "y", 600, NULL }, - { "z", 600, NULL }, - { "Gbreve", 600, NULL }, - { "commaaccent", 600, NULL }, - { "hungarumlaut", 600, NULL }, - { "Idotaccent", 600, NULL }, - { "Nacute", 600, NULL }, - { "quotedbl", 600, NULL }, - { "gcommaaccent", 600, NULL }, - { "mu", 600, NULL }, - { "greaterequal", 600, NULL }, - { "Scaron", 600, NULL }, - { "Lslash", 600, NULL }, - { "semicolon", 600, NULL }, - { "oslash", 600, NULL }, - { "lessequal", 600, NULL }, - { "lozenge", 600, NULL }, - { "parenright", 600, NULL }, - { "ccaron", 600, NULL }, - { "Ecircumflex", 600, NULL }, - { "gbreve", 600, NULL }, - { "trademark", 600, NULL }, - { "daggerdbl", 600, NULL }, - { "nacute", 600, NULL }, - { "macron", 600, NULL }, - { "Otilde", 600, NULL }, - { "Emacron", 600, NULL }, - { "ellipsis", 600, NULL }, - { "scaron", 600, NULL }, - { "AE", 600, NULL }, - { "Ucircumflex", 600, NULL }, - { "lslash", 600, NULL }, - { "quotedblleft", 600, NULL }, - { "hyphen", 600, NULL }, - { "guilsinglright", 600, NULL }, - { "quotesingle", 600, NULL }, - { "eight", 600, NULL }, - { "exclamdown", 600, NULL }, - { "endash", 600, NULL }, - { "oe", 600, NULL }, - { "Abreve", 600, NULL }, - { "Umacron", 600, NULL }, - { "ecircumflex", 600, NULL }, - { "Adieresis", 600, NULL }, - { "copyright", 600, NULL }, - { "Egrave", 600, NULL }, - { "slash", 600, NULL }, - { "Edieresis", 600, NULL }, - { "otilde", 600, NULL }, - { "Idieresis", 600, NULL }, - { "parenleft", 600, NULL }, - { "one", 600, NULL }, - { "emacron", 600, NULL }, - { "Odieresis", 600, NULL }, - { "ucircumflex", 600, NULL }, - { "bracketleft", 600, NULL }, - { "Ugrave", 600, NULL }, - { "quoteright", 600, NULL }, - { "Udieresis", 600, NULL }, - { "perthousand", 600, NULL }, - { "Ydieresis", 600, NULL }, - { "umacron", 600, NULL }, - { "abreve", 600, NULL }, - { "Eacute", 600, NULL }, - { "adieresis", 600, NULL }, - { "egrave", 600, NULL }, - { "edieresis", 600, NULL }, - { "idieresis", 600, NULL }, - { "Eth", 600, NULL }, - { "ae", 600, NULL }, - { "asterisk", 600, NULL }, - { "odieresis", 600, NULL }, - { "Uacute", 600, NULL }, - { "ugrave", 600, NULL }, - { "five", 600, NULL }, - { "nine", 600, NULL }, - { "udieresis", 600, NULL }, - { "Zcaron", 600, NULL }, - { "Scommaaccent", 600, NULL }, - { "threequarters", 600, NULL }, - { "guillemotright", 600, NULL }, - { "Ccedilla", 600, NULL }, - { "ydieresis", 600, NULL }, - { "tilde", 600, NULL }, - { "at", 600, NULL }, - { "eacute", 600, NULL }, - { "underscore", 600, NULL }, - { "Euro", 600, NULL }, - { "Dcroat", 600, NULL }, - { "zero", 600, NULL }, - { "multiply", 600, NULL }, - { "eth", 600, NULL }, - { "Scedilla", 600, NULL }, - { "Racute", 600, NULL }, - { "Ograve", 600, NULL }, - { "partialdiff", 600, NULL }, - { "uacute", 600, NULL }, - { "braceleft", 600, NULL }, - { "Thorn", 600, NULL }, - { "zcaron", 600, NULL }, - { "scommaaccent", 600, NULL }, - { "ccedilla", 600, NULL }, - { "Dcaron", 600, NULL }, - { "dcroat", 600, NULL }, - { "scedilla", 600, NULL }, - { "Oacute", 600, NULL }, - { "Ocircumflex", 600, NULL }, - { "ogonek", 600, NULL }, - { "ograve", 600, NULL }, - { "racute", 600, NULL }, - { "Tcaron", 600, NULL }, - { "Eogonek", 600, NULL }, - { "thorn", 600, NULL }, - { "degree", 600, NULL }, - { "registered", 600, NULL }, - { "radical", 600, NULL }, - { "Aring", 600, NULL }, - { "percent", 600, NULL }, - { "six", 600, NULL }, - { "paragraph", 600, NULL }, - { "dcaron", 600, NULL }, - { "Uogonek", 600, NULL }, - { "two", 600, NULL }, - { "summation", 600, NULL }, - { "Igrave", 600, NULL }, - { "Lacute", 600, NULL }, - { "ocircumflex", 600, NULL }, - { "oacute", 600, NULL }, - { "Uring", 600, NULL }, - { "Lcommaaccent", 600, NULL }, - { "tcaron", 600, NULL }, - { "eogonek", 600, NULL }, - { "Delta", 600, NULL }, - { "Ohungarumlaut", 600, NULL }, - { "asciicircum", 600, NULL }, - { "aring", 600, NULL }, - { "grave", 600, NULL }, - { "uogonek", 600, NULL }, - { "bracketright", 600, NULL }, - { "ampersand", 600, NULL }, - { "Iacute", 600, NULL }, - { "lacute", 600, NULL }, - { "igrave", 600, NULL }, - { "Ncaron", 600, NULL }, - { "plus", 600, NULL }, - { "uring", 600, NULL }, - { "quotesinglbase", 600, NULL }, - { "lcommaaccent", 600, NULL }, - { "Yacute", 600, NULL }, - { "ohungarumlaut", 600, NULL }, - { "threesuperior", 600, NULL }, - { "acute", 600, NULL }, - { "section", 600, NULL }, - { "dieresis", 600, NULL }, - { "quotedblbase", 600, NULL }, - { "iacute", 600, NULL }, - { "ncaron", 600, NULL }, - { "florin", 600, NULL }, - { "yacute", 600, NULL }, - { "Rcommaaccent", 600, NULL }, - { "fi", 600, NULL }, - { "fl", 600, NULL }, - { "Acircumflex", 600, NULL }, - { "Cacute", 600, NULL }, - { "Icircumflex", 600, NULL }, - { "guillemotleft", 600, NULL }, - { "germandbls", 600, NULL }, - { "seven", 600, NULL }, - { "Amacron", 600, NULL }, - { "Sacute", 600, NULL }, - { "ordmasculine", 600, NULL }, - { "dotlessi", 600, NULL }, - { "sterling", 600, NULL }, - { "notequal", 600, NULL }, - { "Imacron", 600, NULL }, - { "rcommaaccent", 600, NULL }, - { "Zdotaccent", 600, NULL }, - { "acircumflex", 600, NULL }, - { "cacute", 600, NULL }, - { "Ecaron", 600, NULL }, - { "braceright", 600, NULL }, - { "icircumflex", 600, NULL }, - { "quotedblright", 600, NULL }, - { "amacron", 600, NULL }, - { "sacute", 600, NULL }, - { "imacron", 600, NULL }, - { "cent", 600, NULL }, - { "currency", 600, NULL }, - { "logicalnot", 600, NULL }, - { "zdotaccent", 600, NULL }, - { "Atilde", 600, NULL }, - { "breve", 600, NULL }, - { "bar", 600, NULL }, - { "fraction", 600, NULL }, - { "less", 600, NULL }, - { "ecaron", 600, NULL }, - { "guilsinglleft", 600, NULL }, - { "exclam", 600, NULL }, - { "period", 600, NULL }, - { "Rcaron", 600, NULL }, - { "Kcommaaccent", 600, NULL }, - { "greater", 600, NULL }, - { "atilde", 600, NULL }, - { "brokenbar", 600, NULL }, - { "quoteleft", 600, NULL }, - { "Edotaccent", 600, NULL }, - { "onesuperior", 600, NULL } - }; - - static BuiltinFontWidth c_arrCourierBoldWidthsTable[] = - { - { "Ntilde", 600, NULL }, - { "rcaron", 600, NULL }, - { "kcommaaccent", 600, NULL }, - { "Ncommaaccent", 600, NULL }, - { "Zacute", 600, NULL }, - { "comma", 600, NULL }, - { "cedilla", 600, NULL }, - { "plusminus", 600, NULL }, - { "circumflex", 600, NULL }, - { "dotaccent", 600, NULL }, - { "edotaccent", 600, NULL }, - { "asciitilde", 600, NULL }, - { "colon", 600, NULL }, - { "onehalf", 600, NULL }, - { "dollar", 600, NULL }, - { "Lcaron", 600, NULL }, - { "ntilde", 600, NULL }, - { "Aogonek", 600, NULL }, - { "ncommaaccent", 600, NULL }, - { "minus", 600, NULL }, - { "Iogonek", 600, NULL }, - { "zacute", 600, NULL }, - { "yen", 600, NULL }, - { "space", 600, NULL }, - { "Omacron", 600, NULL }, - { "questiondown", 600, NULL }, - { "emdash", 600, NULL }, - { "Agrave", 600, NULL }, - { "three", 600, NULL }, - { "numbersign", 600, NULL }, - { "lcaron", 600, NULL }, - { "A", 600, NULL }, - { "B", 600, NULL }, - { "C", 600, NULL }, - { "aogonek", 600, NULL }, - { "D", 600, NULL }, - { "E", 600, NULL }, - { "onequarter", 600, NULL }, - { "F", 600, NULL }, - { "G", 600, NULL }, - { "H", 600, NULL }, - { "I", 600, NULL }, - { "J", 600, NULL }, - { "K", 600, NULL }, - { "iogonek", 600, NULL }, - { "backslash", 600, NULL }, - { "L", 600, NULL }, - { "periodcentered", 600, NULL }, - { "M", 600, NULL }, - { "N", 600, NULL }, - { "omacron", 600, NULL }, - { "Tcommaaccent", 600, NULL }, - { "O", 600, NULL }, - { "P", 600, NULL }, - { "Q", 600, NULL }, - { "Uhungarumlaut", 600, NULL }, - { "R", 600, NULL }, - { "Aacute", 600, NULL }, - { "caron", 600, NULL }, - { "S", 600, NULL }, - { "T", 600, NULL }, - { "U", 600, NULL }, - { "agrave", 600, NULL }, - { "V", 600, NULL }, - { "W", 600, NULL }, - { "X", 600, NULL }, - { "question", 600, NULL }, - { "equal", 600, NULL }, - { "Y", 600, NULL }, - { "Z", 600, NULL }, - { "four", 600, NULL }, - { "a", 600, NULL }, - { "Gcommaaccent", 600, NULL }, - { "b", 600, NULL }, - { "c", 600, NULL }, - { "d", 600, NULL }, - { "e", 600, NULL }, - { "f", 600, NULL }, - { "g", 600, NULL }, - { "bullet", 600, NULL }, - { "h", 600, NULL }, - { "i", 600, NULL }, - { "Oslash", 600, NULL }, - { "dagger", 600, NULL }, - { "j", 600, NULL }, - { "k", 600, NULL }, - { "l", 600, NULL }, - { "m", 600, NULL }, - { "n", 600, NULL }, - { "tcommaaccent", 600, NULL }, - { "o", 600, NULL }, - { "ordfeminine", 600, NULL }, - { "ring", 600, NULL }, - { "p", 600, NULL }, - { "q", 600, NULL }, - { "uhungarumlaut", 600, NULL }, - { "r", 600, NULL }, - { "twosuperior", 600, NULL }, - { "aacute", 600, NULL }, - { "s", 600, NULL }, - { "OE", 600, NULL }, - { "t", 600, NULL }, - { "divide", 600, NULL }, - { "u", 600, NULL }, - { "Ccaron", 600, NULL }, - { "v", 600, NULL }, - { "w", 600, NULL }, - { "x", 600, NULL }, - { "y", 600, NULL }, - { "z", 600, NULL }, - { "Gbreve", 600, NULL }, - { "commaaccent", 600, NULL }, - { "hungarumlaut", 600, NULL }, - { "Idotaccent", 600, NULL }, - { "Nacute", 600, NULL }, - { "quotedbl", 600, NULL }, - { "gcommaaccent", 600, NULL }, - { "mu", 600, NULL }, - { "greaterequal", 600, NULL }, - { "Scaron", 600, NULL }, - { "Lslash", 600, NULL }, - { "semicolon", 600, NULL }, - { "oslash", 600, NULL }, - { "lessequal", 600, NULL }, - { "lozenge", 600, NULL }, - { "parenright", 600, NULL }, - { "ccaron", 600, NULL }, - { "Ecircumflex", 600, NULL }, - { "gbreve", 600, NULL }, - { "trademark", 600, NULL }, - { "daggerdbl", 600, NULL }, - { "nacute", 600, NULL }, - { "macron", 600, NULL }, - { "Otilde", 600, NULL }, - { "Emacron", 600, NULL }, - { "ellipsis", 600, NULL }, - { "scaron", 600, NULL }, - { "AE", 600, NULL }, - { "Ucircumflex", 600, NULL }, - { "lslash", 600, NULL }, - { "quotedblleft", 600, NULL }, - { "guilsinglright", 600, NULL }, - { "hyphen", 600, NULL }, - { "quotesingle", 600, NULL }, - { "eight", 600, NULL }, - { "exclamdown", 600, NULL }, - { "endash", 600, NULL }, - { "oe", 600, NULL }, - { "Abreve", 600, NULL }, - { "Umacron", 600, NULL }, - { "ecircumflex", 600, NULL }, - { "Adieresis", 600, NULL }, - { "copyright", 600, NULL }, - { "Egrave", 600, NULL }, - { "slash", 600, NULL }, - { "Edieresis", 600, NULL }, - { "otilde", 600, NULL }, - { "Idieresis", 600, NULL }, - { "parenleft", 600, NULL }, - { "one", 600, NULL }, - { "emacron", 600, NULL }, - { "Odieresis", 600, NULL }, - { "ucircumflex", 600, NULL }, - { "bracketleft", 600, NULL }, - { "Ugrave", 600, NULL }, - { "quoteright", 600, NULL }, - { "Udieresis", 600, NULL }, - { "perthousand", 600, NULL }, - { "Ydieresis", 600, NULL }, - { "umacron", 600, NULL }, - { "abreve", 600, NULL }, - { "Eacute", 600, NULL }, - { "adieresis", 600, NULL }, - { "egrave", 600, NULL }, - { "edieresis", 600, NULL }, - { "idieresis", 600, NULL }, - { "Eth", 600, NULL }, - { "ae", 600, NULL }, - { "asterisk", 600, NULL }, - { "odieresis", 600, NULL }, - { "Uacute", 600, NULL }, - { "ugrave", 600, NULL }, - { "nine", 600, NULL }, - { "five", 600, NULL }, - { "udieresis", 600, NULL }, - { "Zcaron", 600, NULL }, - { "Scommaaccent", 600, NULL }, - { "threequarters", 600, NULL }, - { "guillemotright", 600, NULL }, - { "Ccedilla", 600, NULL }, - { "ydieresis", 600, NULL }, - { "tilde", 600, NULL }, - { "at", 600, NULL }, - { "eacute", 600, NULL }, - { "underscore", 600, NULL }, - { "Euro", 600, NULL }, - { "Dcroat", 600, NULL }, - { "multiply", 600, NULL }, - { "zero", 600, NULL }, - { "eth", 600, NULL }, - { "Scedilla", 600, NULL }, - { "Ograve", 600, NULL }, - { "Racute", 600, NULL }, - { "partialdiff", 600, NULL }, - { "uacute", 600, NULL }, - { "braceleft", 600, NULL }, - { "Thorn", 600, NULL }, - { "zcaron", 600, NULL }, - { "scommaaccent", 600, NULL }, - { "ccedilla", 600, NULL }, - { "Dcaron", 600, NULL }, - { "dcroat", 600, NULL }, - { "Ocircumflex", 600, NULL }, - { "Oacute", 600, NULL }, - { "scedilla", 600, NULL }, - { "ogonek", 600, NULL }, - { "ograve", 600, NULL }, - { "racute", 600, NULL }, - { "Tcaron", 600, NULL }, - { "Eogonek", 600, NULL }, - { "thorn", 600, NULL }, - { "degree", 600, NULL }, - { "registered", 600, NULL }, - { "radical", 600, NULL }, - { "Aring", 600, NULL }, - { "percent", 600, NULL }, - { "six", 600, NULL }, - { "paragraph", 600, NULL }, - { "dcaron", 600, NULL }, - { "Uogonek", 600, NULL }, - { "two", 600, NULL }, - { "summation", 600, NULL }, - { "Igrave", 600, NULL }, - { "Lacute", 600, NULL }, - { "ocircumflex", 600, NULL }, - { "oacute", 600, NULL }, - { "Uring", 600, NULL }, - { "Lcommaaccent", 600, NULL }, - { "tcaron", 600, NULL }, - { "eogonek", 600, NULL }, - { "Delta", 600, NULL }, - { "Ohungarumlaut", 600, NULL }, - { "asciicircum", 600, NULL }, - { "aring", 600, NULL }, - { "grave", 600, NULL }, - { "uogonek", 600, NULL }, - { "bracketright", 600, NULL }, - { "Iacute", 600, NULL }, - { "ampersand", 600, NULL }, - { "igrave", 600, NULL }, - { "lacute", 600, NULL }, - { "Ncaron", 600, NULL }, - { "plus", 600, NULL }, - { "uring", 600, NULL }, - { "quotesinglbase", 600, NULL }, - { "lcommaaccent", 600, NULL }, - { "Yacute", 600, NULL }, - { "ohungarumlaut", 600, NULL }, - { "threesuperior", 600, NULL }, - { "acute", 600, NULL }, - { "section", 600, NULL }, - { "dieresis", 600, NULL }, - { "iacute", 600, NULL }, - { "quotedblbase", 600, NULL }, - { "ncaron", 600, NULL }, - { "florin", 600, NULL }, - { "yacute", 600, NULL }, - { "Rcommaaccent", 600, NULL }, - { "fi", 600, NULL }, - { "fl", 600, NULL }, - { "Acircumflex", 600, NULL }, - { "Cacute", 600, NULL }, - { "Icircumflex", 600, NULL }, - { "guillemotleft", 600, NULL }, - { "germandbls", 600, NULL }, - { "Amacron", 600, NULL }, - { "seven", 600, NULL }, - { "Sacute", 600, NULL }, - { "ordmasculine", 600, NULL }, - { "dotlessi", 600, NULL }, - { "sterling", 600, NULL }, - { "notequal", 600, NULL }, - { "Imacron", 600, NULL }, - { "rcommaaccent", 600, NULL }, - { "Zdotaccent", 600, NULL }, - { "acircumflex", 600, NULL }, - { "cacute", 600, NULL }, - { "Ecaron", 600, NULL }, - { "icircumflex", 600, NULL }, - { "braceright", 600, NULL }, - { "quotedblright", 600, NULL }, - { "amacron", 600, NULL }, - { "sacute", 600, NULL }, - { "imacron", 600, NULL }, - { "cent", 600, NULL }, - { "currency", 600, NULL }, - { "logicalnot", 600, NULL }, - { "zdotaccent", 600, NULL }, - { "Atilde", 600, NULL }, - { "breve", 600, NULL }, - { "bar", 600, NULL }, - { "fraction", 600, NULL }, - { "less", 600, NULL }, - { "ecaron", 600, NULL }, - { "guilsinglleft", 600, NULL }, - { "exclam", 600, NULL }, - { "period", 600, NULL }, - { "Rcaron", 600, NULL }, - { "Kcommaaccent", 600, NULL }, - { "greater", 600, NULL }, - { "atilde", 600, NULL }, - { "brokenbar", 600, NULL }, - { "quoteleft", 600, NULL }, - { "Edotaccent", 600, NULL }, - { "onesuperior", 600, NULL } - }; - - static BuiltinFontWidth c_arrCourierBoldObliqueWidthsTable[] = - { - { "Ntilde", 600, NULL }, - { "rcaron", 600, NULL }, - { "kcommaaccent", 600, NULL }, - { "Ncommaaccent", 600, NULL }, - { "Zacute", 600, NULL }, - { "comma", 600, NULL }, - { "cedilla", 600, NULL }, - { "plusminus", 600, NULL }, - { "circumflex", 600, NULL }, - { "dotaccent", 600, NULL }, - { "edotaccent", 600, NULL }, - { "asciitilde", 600, NULL }, - { "colon", 600, NULL }, - { "onehalf", 600, NULL }, - { "dollar", 600, NULL }, - { "Lcaron", 600, NULL }, - { "ntilde", 600, NULL }, - { "Aogonek", 600, NULL }, - { "ncommaaccent", 600, NULL }, - { "minus", 600, NULL }, - { "Iogonek", 600, NULL }, - { "zacute", 600, NULL }, - { "yen", 600, NULL }, - { "space", 600, NULL }, - { "Omacron", 600, NULL }, - { "questiondown", 600, NULL }, - { "emdash", 600, NULL }, - { "Agrave", 600, NULL }, - { "three", 600, NULL }, - { "numbersign", 600, NULL }, - { "lcaron", 600, NULL }, - { "A", 600, NULL }, - { "B", 600, NULL }, - { "C", 600, NULL }, - { "aogonek", 600, NULL }, - { "D", 600, NULL }, - { "E", 600, NULL }, - { "onequarter", 600, NULL }, - { "F", 600, NULL }, - { "G", 600, NULL }, - { "H", 600, NULL }, - { "I", 600, NULL }, - { "J", 600, NULL }, - { "K", 600, NULL }, - { "iogonek", 600, NULL }, - { "backslash", 600, NULL }, - { "L", 600, NULL }, - { "periodcentered", 600, NULL }, - { "M", 600, NULL }, - { "N", 600, NULL }, - { "omacron", 600, NULL }, - { "Tcommaaccent", 600, NULL }, - { "O", 600, NULL }, - { "P", 600, NULL }, - { "Q", 600, NULL }, - { "Uhungarumlaut", 600, NULL }, - { "R", 600, NULL }, - { "Aacute", 600, NULL }, - { "caron", 600, NULL }, - { "S", 600, NULL }, - { "T", 600, NULL }, - { "U", 600, NULL }, - { "agrave", 600, NULL }, - { "V", 600, NULL }, - { "W", 600, NULL }, - { "X", 600, NULL }, - { "question", 600, NULL }, - { "equal", 600, NULL }, - { "Y", 600, NULL }, - { "Z", 600, NULL }, - { "four", 600, NULL }, - { "a", 600, NULL }, - { "Gcommaaccent", 600, NULL }, - { "b", 600, NULL }, - { "c", 600, NULL }, - { "d", 600, NULL }, - { "e", 600, NULL }, - { "f", 600, NULL }, - { "g", 600, NULL }, - { "bullet", 600, NULL }, - { "h", 600, NULL }, - { "i", 600, NULL }, - { "Oslash", 600, NULL }, - { "dagger", 600, NULL }, - { "j", 600, NULL }, - { "k", 600, NULL }, - { "l", 600, NULL }, - { "m", 600, NULL }, - { "n", 600, NULL }, - { "tcommaaccent", 600, NULL }, - { "o", 600, NULL }, - { "ordfeminine", 600, NULL }, - { "ring", 600, NULL }, - { "p", 600, NULL }, - { "q", 600, NULL }, - { "uhungarumlaut", 600, NULL }, - { "r", 600, NULL }, - { "twosuperior", 600, NULL }, - { "aacute", 600, NULL }, - { "s", 600, NULL }, - { "OE", 600, NULL }, - { "t", 600, NULL }, - { "divide", 600, NULL }, - { "u", 600, NULL }, - { "Ccaron", 600, NULL }, - { "v", 600, NULL }, - { "w", 600, NULL }, - { "x", 600, NULL }, - { "y", 600, NULL }, - { "z", 600, NULL }, - { "Gbreve", 600, NULL }, - { "commaaccent", 600, NULL }, - { "hungarumlaut", 600, NULL }, - { "Idotaccent", 600, NULL }, - { "Nacute", 600, NULL }, - { "quotedbl", 600, NULL }, - { "gcommaaccent", 600, NULL }, - { "mu", 600, NULL }, - { "greaterequal", 600, NULL }, - { "Scaron", 600, NULL }, - { "Lslash", 600, NULL }, - { "semicolon", 600, NULL }, - { "oslash", 600, NULL }, - { "lessequal", 600, NULL }, - { "lozenge", 600, NULL }, - { "parenright", 600, NULL }, - { "ccaron", 600, NULL }, - { "Ecircumflex", 600, NULL }, - { "gbreve", 600, NULL }, - { "trademark", 600, NULL }, - { "daggerdbl", 600, NULL }, - { "nacute", 600, NULL }, - { "macron", 600, NULL }, - { "Otilde", 600, NULL }, - { "Emacron", 600, NULL }, - { "ellipsis", 600, NULL }, - { "scaron", 600, NULL }, - { "AE", 600, NULL }, - { "Ucircumflex", 600, NULL }, - { "lslash", 600, NULL }, - { "quotedblleft", 600, NULL }, - { "guilsinglright", 600, NULL }, - { "hyphen", 600, NULL }, - { "quotesingle", 600, NULL }, - { "eight", 600, NULL }, - { "exclamdown", 600, NULL }, - { "endash", 600, NULL }, - { "oe", 600, NULL }, - { "Abreve", 600, NULL }, - { "Umacron", 600, NULL }, - { "ecircumflex", 600, NULL }, - { "Adieresis", 600, NULL }, - { "copyright", 600, NULL }, - { "Egrave", 600, NULL }, - { "slash", 600, NULL }, - { "Edieresis", 600, NULL }, - { "otilde", 600, NULL }, - { "Idieresis", 600, NULL }, - { "parenleft", 600, NULL }, - { "one", 600, NULL }, - { "emacron", 600, NULL }, - { "Odieresis", 600, NULL }, - { "ucircumflex", 600, NULL }, - { "bracketleft", 600, NULL }, - { "Ugrave", 600, NULL }, - { "quoteright", 600, NULL }, - { "Udieresis", 600, NULL }, - { "perthousand", 600, NULL }, - { "Ydieresis", 600, NULL }, - { "umacron", 600, NULL }, - { "abreve", 600, NULL }, - { "Eacute", 600, NULL }, - { "adieresis", 600, NULL }, - { "egrave", 600, NULL }, - { "edieresis", 600, NULL }, - { "idieresis", 600, NULL }, - { "Eth", 600, NULL }, - { "ae", 600, NULL }, - { "asterisk", 600, NULL }, - { "odieresis", 600, NULL }, - { "Uacute", 600, NULL }, - { "ugrave", 600, NULL }, - { "nine", 600, NULL }, - { "five", 600, NULL }, - { "udieresis", 600, NULL }, - { "Zcaron", 600, NULL }, - { "Scommaaccent", 600, NULL }, - { "threequarters", 600, NULL }, - { "guillemotright", 600, NULL }, - { "Ccedilla", 600, NULL }, - { "ydieresis", 600, NULL }, - { "tilde", 600, NULL }, - { "at", 600, NULL }, - { "eacute", 600, NULL }, - { "underscore", 600, NULL }, - { "Euro", 600, NULL }, - { "Dcroat", 600, NULL }, - { "multiply", 600, NULL }, - { "zero", 600, NULL }, - { "eth", 600, NULL }, - { "Scedilla", 600, NULL }, - { "Ograve", 600, NULL }, - { "Racute", 600, NULL }, - { "partialdiff", 600, NULL }, - { "uacute", 600, NULL }, - { "braceleft", 600, NULL }, - { "Thorn", 600, NULL }, - { "zcaron", 600, NULL }, - { "scommaaccent", 600, NULL }, - { "ccedilla", 600, NULL }, - { "Dcaron", 600, NULL }, - { "dcroat", 600, NULL }, - { "Ocircumflex", 600, NULL }, - { "Oacute", 600, NULL }, - { "scedilla", 600, NULL }, - { "ogonek", 600, NULL }, - { "ograve", 600, NULL }, - { "racute", 600, NULL }, - { "Tcaron", 600, NULL }, - { "Eogonek", 600, NULL }, - { "thorn", 600, NULL }, - { "degree", 600, NULL }, - { "registered", 600, NULL }, - { "radical", 600, NULL }, - { "Aring", 600, NULL }, - { "percent", 600, NULL }, - { "six", 600, NULL }, - { "paragraph", 600, NULL }, - { "dcaron", 600, NULL }, - { "Uogonek", 600, NULL }, - { "two", 600, NULL }, - { "summation", 600, NULL }, - { "Igrave", 600, NULL }, - { "Lacute", 600, NULL }, - { "ocircumflex", 600, NULL }, - { "oacute", 600, NULL }, - { "Uring", 600, NULL }, - { "Lcommaaccent", 600, NULL }, - { "tcaron", 600, NULL }, - { "eogonek", 600, NULL }, - { "Delta", 600, NULL }, - { "Ohungarumlaut", 600, NULL }, - { "asciicircum", 600, NULL }, - { "aring", 600, NULL }, - { "grave", 600, NULL }, - { "uogonek", 600, NULL }, - { "bracketright", 600, NULL }, - { "Iacute", 600, NULL }, - { "ampersand", 600, NULL }, - { "igrave", 600, NULL }, - { "lacute", 600, NULL }, - { "Ncaron", 600, NULL }, - { "plus", 600, NULL }, - { "uring", 600, NULL }, - { "quotesinglbase", 600, NULL }, - { "lcommaaccent", 600, NULL }, - { "Yacute", 600, NULL }, - { "ohungarumlaut", 600, NULL }, - { "threesuperior", 600, NULL }, - { "acute", 600, NULL }, - { "section", 600, NULL }, - { "dieresis", 600, NULL }, - { "iacute", 600, NULL }, - { "quotedblbase", 600, NULL }, - { "ncaron", 600, NULL }, - { "florin", 600, NULL }, - { "yacute", 600, NULL }, - { "Rcommaaccent", 600, NULL }, - { "fi", 600, NULL }, - { "fl", 600, NULL }, - { "Acircumflex", 600, NULL }, - { "Cacute", 600, NULL }, - { "Icircumflex", 600, NULL }, - { "guillemotleft", 600, NULL }, - { "germandbls", 600, NULL }, - { "Amacron", 600, NULL }, - { "seven", 600, NULL }, - { "Sacute", 600, NULL }, - { "ordmasculine", 600, NULL }, - { "dotlessi", 600, NULL }, - { "sterling", 600, NULL }, - { "notequal", 600, NULL }, - { "Imacron", 600, NULL }, - { "rcommaaccent", 600, NULL }, - { "Zdotaccent", 600, NULL }, - { "acircumflex", 600, NULL }, - { "cacute", 600, NULL }, - { "Ecaron", 600, NULL }, - { "icircumflex", 600, NULL }, - { "braceright", 600, NULL }, - { "quotedblright", 600, NULL }, - { "amacron", 600, NULL }, - { "sacute", 600, NULL }, - { "imacron", 600, NULL }, - { "cent", 600, NULL }, - { "currency", 600, NULL }, - { "logicalnot", 600, NULL }, - { "zdotaccent", 600, NULL }, - { "Atilde", 600, NULL }, - { "breve", 600, NULL }, - { "bar", 600, NULL }, - { "fraction", 600, NULL }, - { "less", 600, NULL }, - { "ecaron", 600, NULL }, - { "guilsinglleft", 600, NULL }, - { "exclam", 600, NULL }, - { "period", 600, NULL }, - { "Rcaron", 600, NULL }, - { "Kcommaaccent", 600, NULL }, - { "greater", 600, NULL }, - { "atilde", 600, NULL }, - { "brokenbar", 600, NULL }, - { "quoteleft", 600, NULL }, - { "Edotaccent", 600, NULL }, - { "onesuperior", 600, NULL } - }; - - static BuiltinFontWidth c_arrCourierObliqueWidthsTable[] = - { - { "Ntilde", 600, NULL }, - { "rcaron", 600, NULL }, - { "kcommaaccent", 600, NULL }, - { "Ncommaaccent", 600, NULL }, - { "Zacute", 600, NULL }, - { "comma", 600, NULL }, - { "cedilla", 600, NULL }, - { "plusminus", 600, NULL }, - { "circumflex", 600, NULL }, - { "dotaccent", 600, NULL }, - { "edotaccent", 600, NULL }, - { "asciitilde", 600, NULL }, - { "colon", 600, NULL }, - { "onehalf", 600, NULL }, - { "dollar", 600, NULL }, - { "Lcaron", 600, NULL }, - { "ntilde", 600, NULL }, - { "Aogonek", 600, NULL }, - { "ncommaaccent", 600, NULL }, - { "minus", 600, NULL }, - { "Iogonek", 600, NULL }, - { "zacute", 600, NULL }, - { "yen", 600, NULL }, - { "space", 600, NULL }, - { "Omacron", 600, NULL }, - { "questiondown", 600, NULL }, - { "emdash", 600, NULL }, - { "Agrave", 600, NULL }, - { "three", 600, NULL }, - { "numbersign", 600, NULL }, - { "lcaron", 600, NULL }, - { "A", 600, NULL }, - { "B", 600, NULL }, - { "C", 600, NULL }, - { "aogonek", 600, NULL }, - { "D", 600, NULL }, - { "E", 600, NULL }, - { "onequarter", 600, NULL }, - { "F", 600, NULL }, - { "G", 600, NULL }, - { "H", 600, NULL }, - { "I", 600, NULL }, - { "J", 600, NULL }, - { "K", 600, NULL }, - { "iogonek", 600, NULL }, - { "backslash", 600, NULL }, - { "L", 600, NULL }, - { "periodcentered", 600, NULL }, - { "M", 600, NULL }, - { "N", 600, NULL }, - { "omacron", 600, NULL }, - { "Tcommaaccent", 600, NULL }, - { "O", 600, NULL }, - { "P", 600, NULL }, - { "Q", 600, NULL }, - { "Uhungarumlaut", 600, NULL }, - { "R", 600, NULL }, - { "Aacute", 600, NULL }, - { "caron", 600, NULL }, - { "S", 600, NULL }, - { "T", 600, NULL }, - { "U", 600, NULL }, - { "agrave", 600, NULL }, - { "V", 600, NULL }, - { "W", 600, NULL }, - { "X", 600, NULL }, - { "question", 600, NULL }, - { "equal", 600, NULL }, - { "Y", 600, NULL }, - { "Z", 600, NULL }, - { "four", 600, NULL }, - { "a", 600, NULL }, - { "Gcommaaccent", 600, NULL }, - { "b", 600, NULL }, - { "c", 600, NULL }, - { "d", 600, NULL }, - { "e", 600, NULL }, - { "f", 600, NULL }, - { "g", 600, NULL }, - { "bullet", 600, NULL }, - { "h", 600, NULL }, - { "i", 600, NULL }, - { "Oslash", 600, NULL }, - { "dagger", 600, NULL }, - { "j", 600, NULL }, - { "k", 600, NULL }, - { "l", 600, NULL }, - { "m", 600, NULL }, - { "n", 600, NULL }, - { "tcommaaccent", 600, NULL }, - { "o", 600, NULL }, - { "ordfeminine", 600, NULL }, - { "ring", 600, NULL }, - { "p", 600, NULL }, - { "q", 600, NULL }, - { "uhungarumlaut", 600, NULL }, - { "r", 600, NULL }, - { "twosuperior", 600, NULL }, - { "aacute", 600, NULL }, - { "s", 600, NULL }, - { "OE", 600, NULL }, - { "t", 600, NULL }, - { "divide", 600, NULL }, - { "u", 600, NULL }, - { "Ccaron", 600, NULL }, - { "v", 600, NULL }, - { "w", 600, NULL }, - { "x", 600, NULL }, - { "y", 600, NULL }, - { "z", 600, NULL }, - { "Gbreve", 600, NULL }, - { "commaaccent", 600, NULL }, - { "hungarumlaut", 600, NULL }, - { "Idotaccent", 600, NULL }, - { "Nacute", 600, NULL }, - { "quotedbl", 600, NULL }, - { "gcommaaccent", 600, NULL }, - { "mu", 600, NULL }, - { "greaterequal", 600, NULL }, - { "Scaron", 600, NULL }, - { "Lslash", 600, NULL }, - { "semicolon", 600, NULL }, - { "oslash", 600, NULL }, - { "lessequal", 600, NULL }, - { "lozenge", 600, NULL }, - { "parenright", 600, NULL }, - { "ccaron", 600, NULL }, - { "Ecircumflex", 600, NULL }, - { "gbreve", 600, NULL }, - { "trademark", 600, NULL }, - { "daggerdbl", 600, NULL }, - { "nacute", 600, NULL }, - { "macron", 600, NULL }, - { "Otilde", 600, NULL }, - { "Emacron", 600, NULL }, - { "ellipsis", 600, NULL }, - { "scaron", 600, NULL }, - { "AE", 600, NULL }, - { "Ucircumflex", 600, NULL }, - { "lslash", 600, NULL }, - { "quotedblleft", 600, NULL }, - { "guilsinglright", 600, NULL }, - { "hyphen", 600, NULL }, - { "quotesingle", 600, NULL }, - { "eight", 600, NULL }, - { "exclamdown", 600, NULL }, - { "endash", 600, NULL }, - { "oe", 600, NULL }, - { "Abreve", 600, NULL }, - { "Umacron", 600, NULL }, - { "ecircumflex", 600, NULL }, - { "Adieresis", 600, NULL }, - { "copyright", 600, NULL }, - { "Egrave", 600, NULL }, - { "slash", 600, NULL }, - { "Edieresis", 600, NULL }, - { "otilde", 600, NULL }, - { "Idieresis", 600, NULL }, - { "parenleft", 600, NULL }, - { "one", 600, NULL }, - { "emacron", 600, NULL }, - { "Odieresis", 600, NULL }, - { "ucircumflex", 600, NULL }, - { "bracketleft", 600, NULL }, - { "Ugrave", 600, NULL }, - { "quoteright", 600, NULL }, - { "Udieresis", 600, NULL }, - { "perthousand", 600, NULL }, - { "Ydieresis", 600, NULL }, - { "umacron", 600, NULL }, - { "abreve", 600, NULL }, - { "Eacute", 600, NULL }, - { "adieresis", 600, NULL }, - { "egrave", 600, NULL }, - { "edieresis", 600, NULL }, - { "idieresis", 600, NULL }, - { "Eth", 600, NULL }, - { "ae", 600, NULL }, - { "asterisk", 600, NULL }, - { "odieresis", 600, NULL }, - { "Uacute", 600, NULL }, - { "ugrave", 600, NULL }, - { "nine", 600, NULL }, - { "five", 600, NULL }, - { "udieresis", 600, NULL }, - { "Zcaron", 600, NULL }, - { "Scommaaccent", 600, NULL }, - { "threequarters", 600, NULL }, - { "guillemotright", 600, NULL }, - { "Ccedilla", 600, NULL }, - { "ydieresis", 600, NULL }, - { "tilde", 600, NULL }, - { "at", 600, NULL }, - { "eacute", 600, NULL }, - { "underscore", 600, NULL }, - { "Euro", 600, NULL }, - { "Dcroat", 600, NULL }, - { "multiply", 600, NULL }, - { "zero", 600, NULL }, - { "eth", 600, NULL }, - { "Scedilla", 600, NULL }, - { "Ograve", 600, NULL }, - { "Racute", 600, NULL }, - { "partialdiff", 600, NULL }, - { "uacute", 600, NULL }, - { "braceleft", 600, NULL }, - { "Thorn", 600, NULL }, - { "zcaron", 600, NULL }, - { "scommaaccent", 600, NULL }, - { "ccedilla", 600, NULL }, - { "Dcaron", 600, NULL }, - { "dcroat", 600, NULL }, - { "Ocircumflex", 600, NULL }, - { "Oacute", 600, NULL }, - { "scedilla", 600, NULL }, - { "ogonek", 600, NULL }, - { "ograve", 600, NULL }, - { "racute", 600, NULL }, - { "Tcaron", 600, NULL }, - { "Eogonek", 600, NULL }, - { "thorn", 600, NULL }, - { "degree", 600, NULL }, - { "registered", 600, NULL }, - { "radical", 600, NULL }, - { "Aring", 600, NULL }, - { "percent", 600, NULL }, - { "six", 600, NULL }, - { "paragraph", 600, NULL }, - { "dcaron", 600, NULL }, - { "Uogonek", 600, NULL }, - { "two", 600, NULL }, - { "summation", 600, NULL }, - { "Igrave", 600, NULL }, - { "Lacute", 600, NULL }, - { "ocircumflex", 600, NULL }, - { "oacute", 600, NULL }, - { "Uring", 600, NULL }, - { "Lcommaaccent", 600, NULL }, - { "tcaron", 600, NULL }, - { "eogonek", 600, NULL }, - { "Delta", 600, NULL }, - { "Ohungarumlaut", 600, NULL }, - { "asciicircum", 600, NULL }, - { "aring", 600, NULL }, - { "grave", 600, NULL }, - { "uogonek", 600, NULL }, - { "bracketright", 600, NULL }, - { "Iacute", 600, NULL }, - { "ampersand", 600, NULL }, - { "igrave", 600, NULL }, - { "lacute", 600, NULL }, - { "Ncaron", 600, NULL }, - { "plus", 600, NULL }, - { "uring", 600, NULL }, - { "quotesinglbase", 600, NULL }, - { "lcommaaccent", 600, NULL }, - { "Yacute", 600, NULL }, - { "ohungarumlaut", 600, NULL }, - { "threesuperior", 600, NULL }, - { "acute", 600, NULL }, - { "section", 600, NULL }, - { "dieresis", 600, NULL }, - { "iacute", 600, NULL }, - { "quotedblbase", 600, NULL }, - { "ncaron", 600, NULL }, - { "florin", 600, NULL }, - { "yacute", 600, NULL }, - { "Rcommaaccent", 600, NULL }, - { "fi", 600, NULL }, - { "fl", 600, NULL }, - { "Acircumflex", 600, NULL }, - { "Cacute", 600, NULL }, - { "Icircumflex", 600, NULL }, - { "guillemotleft", 600, NULL }, - { "germandbls", 600, NULL }, - { "Amacron", 600, NULL }, - { "seven", 600, NULL }, - { "Sacute", 600, NULL }, - { "ordmasculine", 600, NULL }, - { "dotlessi", 600, NULL }, - { "sterling", 600, NULL }, - { "notequal", 600, NULL }, - { "Imacron", 600, NULL }, - { "rcommaaccent", 600, NULL }, - { "Zdotaccent", 600, NULL }, - { "acircumflex", 600, NULL }, - { "cacute", 600, NULL }, - { "Ecaron", 600, NULL }, - { "icircumflex", 600, NULL }, - { "braceright", 600, NULL }, - { "quotedblright", 600, NULL }, - { "amacron", 600, NULL }, - { "sacute", 600, NULL }, - { "imacron", 600, NULL }, - { "cent", 600, NULL }, - { "currency", 600, NULL }, - { "logicalnot", 600, NULL }, - { "zdotaccent", 600, NULL }, - { "Atilde", 600, NULL }, - { "breve", 600, NULL }, - { "bar", 600, NULL }, - { "fraction", 600, NULL }, - { "less", 600, NULL }, - { "ecaron", 600, NULL }, - { "guilsinglleft", 600, NULL }, - { "exclam", 600, NULL }, - { "period", 600, NULL }, - { "Rcaron", 600, NULL }, - { "Kcommaaccent", 600, NULL }, - { "greater", 600, NULL }, - { "atilde", 600, NULL }, - { "brokenbar", 600, NULL }, - { "quoteleft", 600, NULL }, - { "Edotaccent", 600, NULL }, - { "onesuperior", 600, NULL } - }; - - static BuiltinFontWidth c_arrHelveticaWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 333, NULL }, - { "kcommaaccent", 500, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 278, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 584, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 556, NULL }, - { "asciitilde", 584, NULL }, - { "colon", 278, NULL }, - { "onehalf", 834, NULL }, - { "dollar", 556, NULL }, - { "Lcaron", 556, NULL }, - { "ntilde", 556, NULL }, - { "Aogonek", 667, NULL }, - { "ncommaaccent", 556, NULL }, - { "minus", 584, NULL }, - { "Iogonek", 278, NULL }, - { "zacute", 500, NULL }, - { "yen", 556, NULL }, - { "space", 278, NULL }, - { "Omacron", 778, NULL }, - { "questiondown", 611, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 667, NULL }, - { "three", 556, NULL }, - { "numbersign", 556, NULL }, - { "lcaron", 299, NULL }, - { "A", 667, NULL }, - { "B", 667, NULL }, - { "C", 722, NULL }, - { "aogonek", 556, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 834, NULL }, - { "F", 611, NULL }, - { "G", 778, NULL }, - { "H", 722, NULL }, - { "I", 278, NULL }, - { "J", 500, NULL }, - { "K", 667, NULL }, - { "iogonek", 222, NULL }, - { "backslash", 278, NULL }, - { "L", 556, NULL }, - { "periodcentered", 278, NULL }, - { "M", 833, NULL }, - { "N", 722, NULL }, - { "omacron", 556, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 778, NULL }, - { "P", 667, NULL }, - { "Q", 778, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 722, NULL }, - { "Aacute", 667, NULL }, - { "caron", 333, NULL }, - { "S", 667, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 556, NULL }, - { "V", 667, NULL }, - { "W", 944, NULL }, - { "X", 667, NULL }, - { "question", 556, NULL }, - { "equal", 584, NULL }, - { "Y", 667, NULL }, - { "Z", 611, NULL }, - { "four", 556, NULL }, - { "a", 556, NULL }, - { "Gcommaaccent", 778, NULL }, - { "b", 556, NULL }, - { "c", 500, NULL }, - { "d", 556, NULL }, - { "e", 556, NULL }, - { "f", 278, NULL }, - { "g", 556, NULL }, - { "bullet", 350, NULL }, - { "h", 556, NULL }, - { "i", 222, NULL }, - { "Oslash", 778, NULL }, - { "dagger", 556, NULL }, - { "j", 222, NULL }, - { "k", 500, NULL }, - { "l", 222, NULL }, - { "m", 833, NULL }, - { "n", 556, NULL }, - { "tcommaaccent", 278, NULL }, - { "o", 556, NULL }, - { "ordfeminine", 370, NULL }, - { "ring", 333, NULL }, - { "p", 556, NULL }, - { "q", 556, NULL }, - { "uhungarumlaut", 556, NULL }, - { "r", 333, NULL }, - { "twosuperior", 333, NULL }, - { "aacute", 556, NULL }, - { "s", 500, NULL }, - { "OE", 1000, NULL }, - { "t", 278, NULL }, - { "divide", 584, NULL }, - { "u", 556, NULL }, - { "Ccaron", 722, NULL }, - { "v", 500, NULL }, - { "w", 722, NULL }, - { "x", 500, NULL }, - { "y", 500, NULL }, - { "z", 500, NULL }, - { "Gbreve", 778, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 278, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 355, NULL }, - { "gcommaaccent", 556, NULL }, - { "mu", 556, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 667, NULL }, - { "Lslash", 556, NULL }, - { "semicolon", 278, NULL }, - { "oslash", 611, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 471, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 500, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 556, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 556, NULL }, - { "nacute", 556, NULL }, - { "macron", 333, NULL }, - { "Otilde", 778, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 500, NULL }, - { "AE", 1000, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 222, NULL }, - { "quotedblleft", 333, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 191, NULL }, - { "eight", 556, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 556, NULL }, - { "oe", 944, NULL }, - { "Abreve", 667, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 556, NULL }, - { "Adieresis", 667, NULL }, - { "copyright", 737, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 556, NULL }, - { "Idieresis", 278, NULL }, - { "parenleft", 333, NULL }, - { "one", 556, NULL }, - { "emacron", 556, NULL }, - { "Odieresis", 778, NULL }, - { "ucircumflex", 556, NULL }, - { "bracketleft", 278, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 222, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 667, NULL }, - { "umacron", 556, NULL }, - { "abreve", 556, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 556, NULL }, - { "egrave", 556, NULL }, - { "edieresis", 556, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 889, NULL }, - { "asterisk", 389, NULL }, - { "odieresis", 556, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 556, NULL }, - { "nine", 556, NULL }, - { "five", 556, NULL }, - { "udieresis", 556, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 667, NULL }, - { "threequarters", 834, NULL }, - { "guillemotright", 556, NULL }, - { "Ccedilla", 722, NULL }, - { "ydieresis", 500, NULL }, - { "tilde", 333, NULL }, - { "at", 1015, NULL }, - { "eacute", 556, NULL }, - { "underscore", 556, NULL }, - { "Euro", 556, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 584, NULL }, - { "zero", 556, NULL }, - { "eth", 556, NULL }, - { "Scedilla", 667, NULL }, - { "Ograve", 778, NULL }, - { "Racute", 722, NULL }, - { "partialdiff", 476, NULL }, - { "uacute", 556, NULL }, - { "braceleft", 334, NULL }, - { "Thorn", 667, NULL }, - { "zcaron", 500, NULL }, - { "scommaaccent", 500, NULL }, - { "ccedilla", 500, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 556, NULL }, - { "Ocircumflex", 778, NULL }, - { "Oacute", 778, NULL }, - { "scedilla", 500, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 556, NULL }, - { "racute", 333, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 556, NULL }, - { "degree", 400, NULL }, - { "registered", 737, NULL }, - { "radical", 453, NULL }, - { "Aring", 667, NULL }, - { "percent", 889, NULL }, - { "six", 556, NULL }, - { "paragraph", 537, NULL }, - { "dcaron", 643, NULL }, - { "Uogonek", 722, NULL }, - { "two", 556, NULL }, - { "summation", 600, NULL }, - { "Igrave", 278, NULL }, - { "Lacute", 556, NULL }, - { "ocircumflex", 556, NULL }, - { "oacute", 556, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 556, NULL }, - { "tcaron", 317, NULL }, - { "eogonek", 556, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 778, NULL }, - { "asciicircum", 469, NULL }, - { "aring", 556, NULL }, - { "grave", 333, NULL }, - { "uogonek", 556, NULL }, - { "bracketright", 278, NULL }, - { "Iacute", 278, NULL }, - { "ampersand", 667, NULL }, - { "igrave", 278, NULL }, - { "lacute", 222, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 584, NULL }, - { "uring", 556, NULL }, - { "quotesinglbase", 222, NULL }, - { "lcommaaccent", 222, NULL }, - { "Yacute", 667, NULL }, - { "ohungarumlaut", 556, NULL }, - { "threesuperior", 333, NULL }, - { "acute", 333, NULL }, - { "section", 556, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 333, NULL }, - { "ncaron", 556, NULL }, - { "florin", 556, NULL }, - { "yacute", 500, NULL }, - { "Rcommaaccent", 722, NULL }, - { "fi", 500, NULL }, - { "fl", 500, NULL }, - { "Acircumflex", 667, NULL }, - { "Cacute", 722, NULL }, - { "Icircumflex", 278, NULL }, - { "guillemotleft", 556, NULL }, - { "germandbls", 611, NULL }, - { "Amacron", 667, NULL }, - { "seven", 556, NULL }, - { "Sacute", 667, NULL }, - { "ordmasculine", 365, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 556, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 278, NULL }, - { "rcommaaccent", 333, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 556, NULL }, - { "cacute", 500, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 334, NULL }, - { "quotedblright", 333, NULL }, - { "amacron", 556, NULL }, - { "sacute", 500, NULL }, - { "imacron", 278, NULL }, - { "cent", 556, NULL }, - { "currency", 556, NULL }, - { "logicalnot", 584, NULL }, - { "zdotaccent", 500, NULL }, - { "Atilde", 667, NULL }, - { "breve", 333, NULL }, - { "bar", 260, NULL }, - { "fraction", 167, NULL }, - { "less", 584, NULL }, - { "ecaron", 556, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 278, NULL }, - { "period", 278, NULL }, - { "Rcaron", 722, NULL }, - { "Kcommaaccent", 667, NULL }, - { "greater", 584, NULL }, - { "atilde", 556, NULL }, - { "brokenbar", 260, NULL }, - { "quoteleft", 222, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 333, NULL } - }; - - static BuiltinFontWidth c_arrHelveticaBoldWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 389, NULL }, - { "kcommaaccent", 556, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 278, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 584, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 556, NULL }, - { "asciitilde", 584, NULL }, - { "colon", 333, NULL }, - { "onehalf", 834, NULL }, - { "dollar", 556, NULL }, - { "Lcaron", 611, NULL }, - { "ntilde", 611, NULL }, - { "Aogonek", 722, NULL }, - { "ncommaaccent", 611, NULL }, - { "minus", 584, NULL }, - { "Iogonek", 278, NULL }, - { "zacute", 500, NULL }, - { "yen", 556, NULL }, - { "space", 278, NULL }, - { "Omacron", 778, NULL }, - { "questiondown", 611, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 722, NULL }, - { "three", 556, NULL }, - { "numbersign", 556, NULL }, - { "lcaron", 400, NULL }, - { "A", 722, NULL }, - { "B", 722, NULL }, - { "C", 722, NULL }, - { "aogonek", 556, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 834, NULL }, - { "F", 611, NULL }, - { "G", 778, NULL }, - { "H", 722, NULL }, - { "I", 278, NULL }, - { "J", 556, NULL }, - { "K", 722, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 611, NULL }, - { "periodcentered", 278, NULL }, - { "M", 833, NULL }, - { "N", 722, NULL }, - { "omacron", 611, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 778, NULL }, - { "P", 667, NULL }, - { "Q", 778, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 722, NULL }, - { "Aacute", 722, NULL }, - { "caron", 333, NULL }, - { "S", 667, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 556, NULL }, - { "V", 667, NULL }, - { "W", 944, NULL }, - { "X", 667, NULL }, - { "question", 611, NULL }, - { "equal", 584, NULL }, - { "Y", 667, NULL }, - { "Z", 611, NULL }, - { "four", 556, NULL }, - { "a", 556, NULL }, - { "Gcommaaccent", 778, NULL }, - { "b", 611, NULL }, - { "c", 556, NULL }, - { "d", 611, NULL }, - { "e", 556, NULL }, - { "f", 333, NULL }, - { "g", 611, NULL }, - { "bullet", 350, NULL }, - { "h", 611, NULL }, - { "i", 278, NULL }, - { "Oslash", 778, NULL }, - { "dagger", 556, NULL }, - { "j", 278, NULL }, - { "k", 556, NULL }, - { "l", 278, NULL }, - { "m", 889, NULL }, - { "n", 611, NULL }, - { "tcommaaccent", 333, NULL }, - { "o", 611, NULL }, - { "ordfeminine", 370, NULL }, - { "ring", 333, NULL }, - { "p", 611, NULL }, - { "q", 611, NULL }, - { "uhungarumlaut", 611, NULL }, - { "r", 389, NULL }, - { "twosuperior", 333, NULL }, - { "aacute", 556, NULL }, - { "s", 556, NULL }, - { "OE", 1000, NULL }, - { "t", 333, NULL }, - { "divide", 584, NULL }, - { "u", 611, NULL }, - { "Ccaron", 722, NULL }, - { "v", 556, NULL }, - { "w", 778, NULL }, - { "x", 556, NULL }, - { "y", 556, NULL }, - { "z", 500, NULL }, - { "Gbreve", 778, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 278, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 474, NULL }, - { "gcommaaccent", 611, NULL }, - { "mu", 611, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 667, NULL }, - { "Lslash", 611, NULL }, - { "semicolon", 333, NULL }, - { "oslash", 611, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 494, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 556, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 611, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 556, NULL }, - { "nacute", 611, NULL }, - { "macron", 333, NULL }, - { "Otilde", 778, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 556, NULL }, - { "AE", 1000, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 500, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 238, NULL }, - { "eight", 556, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 556, NULL }, - { "oe", 944, NULL }, - { "Abreve", 722, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 556, NULL }, - { "Adieresis", 722, NULL }, - { "copyright", 737, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 611, NULL }, - { "Idieresis", 278, NULL }, - { "parenleft", 333, NULL }, - { "one", 556, NULL }, - { "emacron", 556, NULL }, - { "Odieresis", 778, NULL }, - { "ucircumflex", 611, NULL }, - { "bracketleft", 333, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 278, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 667, NULL }, - { "umacron", 611, NULL }, - { "abreve", 556, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 556, NULL }, - { "egrave", 556, NULL }, - { "edieresis", 556, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 889, NULL }, - { "asterisk", 389, NULL }, - { "odieresis", 611, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 611, NULL }, - { "nine", 556, NULL }, - { "five", 556, NULL }, - { "udieresis", 611, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 667, NULL }, - { "threequarters", 834, NULL }, - { "guillemotright", 556, NULL }, - { "Ccedilla", 722, NULL }, - { "ydieresis", 556, NULL }, - { "tilde", 333, NULL }, - { "dbldaggerumlaut", 556, NULL }, - { "at", 975, NULL }, - { "eacute", 556, NULL }, - { "underscore", 556, NULL }, - { "Euro", 556, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 584, NULL }, - { "zero", 556, NULL }, - { "eth", 611, NULL }, - { "Scedilla", 667, NULL }, - { "Ograve", 778, NULL }, - { "Racute", 722, NULL }, - { "partialdiff", 494, NULL }, - { "uacute", 611, NULL }, - { "braceleft", 389, NULL }, - { "Thorn", 667, NULL }, - { "zcaron", 500, NULL }, - { "scommaaccent", 556, NULL }, - { "ccedilla", 556, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 611, NULL }, - { "Ocircumflex", 778, NULL }, - { "Oacute", 778, NULL }, - { "scedilla", 556, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 611, NULL }, - { "racute", 389, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 611, NULL }, - { "degree", 400, NULL }, - { "registered", 737, NULL }, - { "radical", 549, NULL }, - { "Aring", 722, NULL }, - { "percent", 889, NULL }, - { "six", 556, NULL }, - { "paragraph", 556, NULL }, - { "dcaron", 743, NULL }, - { "Uogonek", 722, NULL }, - { "two", 556, NULL }, - { "summation", 600, NULL }, - { "Igrave", 278, NULL }, - { "Lacute", 611, NULL }, - { "ocircumflex", 611, NULL }, - { "oacute", 611, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 611, NULL }, - { "tcaron", 389, NULL }, - { "eogonek", 556, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 778, NULL }, - { "asciicircum", 584, NULL }, - { "aring", 556, NULL }, - { "grave", 333, NULL }, - { "uogonek", 611, NULL }, - { "bracketright", 333, NULL }, - { "Iacute", 278, NULL }, - { "ampersand", 722, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 584, NULL }, - { "uring", 611, NULL }, - { "quotesinglbase", 278, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 667, NULL }, - { "ohungarumlaut", 611, NULL }, - { "threesuperior", 333, NULL }, - { "acute", 333, NULL }, - { "section", 556, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 500, NULL }, - { "ncaron", 611, NULL }, - { "florin", 556, NULL }, - { "yacute", 556, NULL }, - { "Rcommaaccent", 722, NULL }, - { "fi", 611, NULL }, - { "fl", 611, NULL }, - { "Acircumflex", 722, NULL }, - { "Cacute", 722, NULL }, - { "Icircumflex", 278, NULL }, - { "guillemotleft", 556, NULL }, - { "germandbls", 611, NULL }, - { "Amacron", 722, NULL }, - { "seven", 556, NULL }, - { "Sacute", 667, NULL }, - { "ordmasculine", 365, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 556, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 278, NULL }, - { "rcommaaccent", 389, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 556, NULL }, - { "cacute", 556, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 389, NULL }, - { "quotedblright", 500, NULL }, - { "amacron", 556, NULL }, - { "sacute", 556, NULL }, - { "imacron", 278, NULL }, - { "cent", 556, NULL }, - { "currency", 556, NULL }, - { "logicalnot", 584, NULL }, - { "zdotaccent", 500, NULL }, - { "Atilde", 722, NULL }, - { "breve", 333, NULL }, - { "bar", 280, NULL }, - { "fraction", 167, NULL }, - { "less", 584, NULL }, - { "ecaron", 556, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 333, NULL }, - { "period", 278, NULL }, - { "Rcaron", 722, NULL }, - { "Kcommaaccent", 722, NULL }, - { "greater", 584, NULL }, - { "atilde", 556, NULL }, - { "brokenbar", 280, NULL }, - { "quoteleft", 278, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 333, NULL } - }; - - static BuiltinFontWidth c_arrHelveticaBoldObliqueWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 389, NULL }, - { "kcommaaccent", 556, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 278, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 584, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 556, NULL }, - { "asciitilde", 584, NULL }, - { "colon", 333, NULL }, - { "onehalf", 834, NULL }, - { "dollar", 556, NULL }, - { "Lcaron", 611, NULL }, - { "ntilde", 611, NULL }, - { "Aogonek", 722, NULL }, - { "ncommaaccent", 611, NULL }, - { "minus", 584, NULL }, - { "Iogonek", 278, NULL }, - { "zacute", 500, NULL }, - { "yen", 556, NULL }, - { "space", 278, NULL }, - { "Omacron", 778, NULL }, - { "questiondown", 611, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 722, NULL }, - { "three", 556, NULL }, - { "numbersign", 556, NULL }, - { "lcaron", 400, NULL }, - { "A", 722, NULL }, - { "B", 722, NULL }, - { "C", 722, NULL }, - { "aogonek", 556, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 834, NULL }, - { "F", 611, NULL }, - { "G", 778, NULL }, - { "H", 722, NULL }, - { "I", 278, NULL }, - { "J", 556, NULL }, - { "K", 722, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 611, NULL }, - { "periodcentered", 278, NULL }, - { "M", 833, NULL }, - { "N", 722, NULL }, - { "omacron", 611, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 778, NULL }, - { "P", 667, NULL }, - { "Q", 778, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 722, NULL }, - { "Aacute", 722, NULL }, - { "caron", 333, NULL }, - { "S", 667, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 556, NULL }, - { "V", 667, NULL }, - { "W", 944, NULL }, - { "X", 667, NULL }, - { "question", 611, NULL }, - { "equal", 584, NULL }, - { "Y", 667, NULL }, - { "Z", 611, NULL }, - { "four", 556, NULL }, - { "a", 556, NULL }, - { "Gcommaaccent", 778, NULL }, - { "b", 611, NULL }, - { "c", 556, NULL }, - { "d", 611, NULL }, - { "e", 556, NULL }, - { "f", 333, NULL }, - { "g", 611, NULL }, - { "bullet", 350, NULL }, - { "h", 611, NULL }, - { "i", 278, NULL }, - { "Oslash", 778, NULL }, - { "dagger", 556, NULL }, - { "j", 278, NULL }, - { "k", 556, NULL }, - { "l", 278, NULL }, - { "m", 889, NULL }, - { "n", 611, NULL }, - { "tcommaaccent", 333, NULL }, - { "o", 611, NULL }, - { "ordfeminine", 370, NULL }, - { "ring", 333, NULL }, - { "p", 611, NULL }, - { "q", 611, NULL }, - { "uhungarumlaut", 611, NULL }, - { "r", 389, NULL }, - { "twosuperior", 333, NULL }, - { "aacute", 556, NULL }, - { "s", 556, NULL }, - { "OE", 1000, NULL }, - { "t", 333, NULL }, - { "divide", 584, NULL }, - { "u", 611, NULL }, - { "Ccaron", 722, NULL }, - { "v", 556, NULL }, - { "w", 778, NULL }, - { "x", 556, NULL }, - { "y", 556, NULL }, - { "z", 500, NULL }, - { "Gbreve", 778, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 278, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 474, NULL }, - { "gcommaaccent", 611, NULL }, - { "mu", 611, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 667, NULL }, - { "Lslash", 611, NULL }, - { "semicolon", 333, NULL }, - { "oslash", 611, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 494, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 556, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 611, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 556, NULL }, - { "nacute", 611, NULL }, - { "macron", 333, NULL }, - { "Otilde", 778, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 556, NULL }, - { "AE", 1000, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 500, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 238, NULL }, - { "eight", 556, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 556, NULL }, - { "oe", 944, NULL }, - { "Abreve", 722, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 556, NULL }, - { "Adieresis", 722, NULL }, - { "copyright", 737, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 611, NULL }, - { "Idieresis", 278, NULL }, - { "parenleft", 333, NULL }, - { "one", 556, NULL }, - { "emacron", 556, NULL }, - { "Odieresis", 778, NULL }, - { "ucircumflex", 611, NULL }, - { "bracketleft", 333, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 278, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 667, NULL }, - { "umacron", 611, NULL }, - { "abreve", 556, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 556, NULL }, - { "egrave", 556, NULL }, - { "edieresis", 556, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 889, NULL }, - { "asterisk", 389, NULL }, - { "odieresis", 611, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 611, NULL }, - { "nine", 556, NULL }, - { "five", 556, NULL }, - { "udieresis", 611, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 667, NULL }, - { "threequarters", 834, NULL }, - { "guillemotright", 556, NULL }, - { "Ccedilla", 722, NULL }, - { "ydieresis", 556, NULL }, - { "tilde", 333, NULL }, - { "at", 975, NULL }, - { "eacute", 556, NULL }, - { "underscore", 556, NULL }, - { "Euro", 556, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 584, NULL }, - { "zero", 556, NULL }, - { "eth", 611, NULL }, - { "Scedilla", 667, NULL }, - { "Ograve", 778, NULL }, - { "Racute", 722, NULL }, - { "partialdiff", 494, NULL }, - { "uacute", 611, NULL }, - { "braceleft", 389, NULL }, - { "Thorn", 667, NULL }, - { "zcaron", 500, NULL }, - { "scommaaccent", 556, NULL }, - { "ccedilla", 556, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 611, NULL }, - { "Ocircumflex", 778, NULL }, - { "Oacute", 778, NULL }, - { "scedilla", 556, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 611, NULL }, - { "racute", 389, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 611, NULL }, - { "degree", 400, NULL }, - { "registered", 737, NULL }, - { "radical", 549, NULL }, - { "Aring", 722, NULL }, - { "percent", 889, NULL }, - { "six", 556, NULL }, - { "paragraph", 556, NULL }, - { "dcaron", 743, NULL }, - { "Uogonek", 722, NULL }, - { "two", 556, NULL }, - { "summation", 600, NULL }, - { "Igrave", 278, NULL }, - { "Lacute", 611, NULL }, - { "ocircumflex", 611, NULL }, - { "oacute", 611, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 611, NULL }, - { "tcaron", 389, NULL }, - { "eogonek", 556, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 778, NULL }, - { "asciicircum", 584, NULL }, - { "aring", 556, NULL }, - { "grave", 333, NULL }, - { "uogonek", 611, NULL }, - { "bracketright", 333, NULL }, - { "Iacute", 278, NULL }, - { "ampersand", 722, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 584, NULL }, - { "uring", 611, NULL }, - { "quotesinglbase", 278, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 667, NULL }, - { "ohungarumlaut", 611, NULL }, - { "threesuperior", 333, NULL }, - { "acute", 333, NULL }, - { "section", 556, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 500, NULL }, - { "ncaron", 611, NULL }, - { "florin", 556, NULL }, - { "yacute", 556, NULL }, - { "Rcommaaccent", 722, NULL }, - { "fi", 611, NULL }, - { "fl", 611, NULL }, - { "Acircumflex", 722, NULL }, - { "Cacute", 722, NULL }, - { "Icircumflex", 278, NULL }, - { "guillemotleft", 556, NULL }, - { "germandbls", 611, NULL }, - { "Amacron", 722, NULL }, - { "seven", 556, NULL }, - { "Sacute", 667, NULL }, - { "ordmasculine", 365, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 556, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 278, NULL }, - { "rcommaaccent", 389, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 556, NULL }, - { "cacute", 556, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 389, NULL }, - { "quotedblright", 500, NULL }, - { "amacron", 556, NULL }, - { "sacute", 556, NULL }, - { "imacron", 278, NULL }, - { "cent", 556, NULL }, - { "currency", 556, NULL }, - { "logicalnot", 584, NULL }, - { "zdotaccent", 500, NULL }, - { "Atilde", 722, NULL }, - { "breve", 333, NULL }, - { "bar", 280, NULL }, - { "fraction", 167, NULL }, - { "less", 584, NULL }, - { "ecaron", 556, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 333, NULL }, - { "period", 278, NULL }, - { "Rcaron", 722, NULL }, - { "Kcommaaccent", 722, NULL }, - { "greater", 584, NULL }, - { "atilde", 556, NULL }, - { "brokenbar", 280, NULL }, - { "quoteleft", 278, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 333, NULL } - }; - - static BuiltinFontWidth c_arrHelveticaObliqueWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 333, NULL }, - { "kcommaaccent", 500, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 278, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 584, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 556, NULL }, - { "asciitilde", 584, NULL }, - { "colon", 278, NULL }, - { "onehalf", 834, NULL }, - { "dollar", 556, NULL }, - { "Lcaron", 556, NULL }, - { "ntilde", 556, NULL }, - { "Aogonek", 667, NULL }, - { "ncommaaccent", 556, NULL }, - { "minus", 584, NULL }, - { "Iogonek", 278, NULL }, - { "zacute", 500, NULL }, - { "yen", 556, NULL }, - { "space", 278, NULL }, - { "Omacron", 778, NULL }, - { "questiondown", 611, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 667, NULL }, - { "three", 556, NULL }, - { "numbersign", 556, NULL }, - { "lcaron", 299, NULL }, - { "A", 667, NULL }, - { "B", 667, NULL }, - { "C", 722, NULL }, - { "aogonek", 556, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 834, NULL }, - { "F", 611, NULL }, - { "G", 778, NULL }, - { "H", 722, NULL }, - { "I", 278, NULL }, - { "J", 500, NULL }, - { "K", 667, NULL }, - { "iogonek", 222, NULL }, - { "backslash", 278, NULL }, - { "L", 556, NULL }, - { "periodcentered", 278, NULL }, - { "M", 833, NULL }, - { "N", 722, NULL }, - { "omacron", 556, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 778, NULL }, - { "P", 667, NULL }, - { "Q", 778, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 722, NULL }, - { "Aacute", 667, NULL }, - { "caron", 333, NULL }, - { "S", 667, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 556, NULL }, - { "V", 667, NULL }, - { "W", 944, NULL }, - { "X", 667, NULL }, - { "question", 556, NULL }, - { "equal", 584, NULL }, - { "Y", 667, NULL }, - { "Z", 611, NULL }, - { "four", 556, NULL }, - { "a", 556, NULL }, - { "Gcommaaccent", 778, NULL }, - { "b", 556, NULL }, - { "c", 500, NULL }, - { "d", 556, NULL }, - { "e", 556, NULL }, - { "f", 278, NULL }, - { "g", 556, NULL }, - { "bullet", 350, NULL }, - { "h", 556, NULL }, - { "i", 222, NULL }, - { "Oslash", 778, NULL }, - { "dagger", 556, NULL }, - { "j", 222, NULL }, - { "k", 500, NULL }, - { "l", 222, NULL }, - { "m", 833, NULL }, - { "n", 556, NULL }, - { "tcommaaccent", 278, NULL }, - { "o", 556, NULL }, - { "ordfeminine", 370, NULL }, - { "ring", 333, NULL }, - { "p", 556, NULL }, - { "q", 556, NULL }, - { "uhungarumlaut", 556, NULL }, - { "r", 333, NULL }, - { "twosuperior", 333, NULL }, - { "aacute", 556, NULL }, - { "s", 500, NULL }, - { "OE", 1000, NULL }, - { "t", 278, NULL }, - { "divide", 584, NULL }, - { "u", 556, NULL }, - { "Ccaron", 722, NULL }, - { "v", 500, NULL }, - { "w", 722, NULL }, - { "x", 500, NULL }, - { "y", 500, NULL }, - { "z", 500, NULL }, - { "Gbreve", 778, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 278, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 355, NULL }, - { "gcommaaccent", 556, NULL }, - { "mu", 556, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 667, NULL }, - { "Lslash", 556, NULL }, - { "semicolon", 278, NULL }, - { "oslash", 611, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 471, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 500, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 556, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 556, NULL }, - { "nacute", 556, NULL }, - { "macron", 333, NULL }, - { "Otilde", 778, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 500, NULL }, - { "AE", 1000, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 222, NULL }, - { "quotedblleft", 333, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 191, NULL }, - { "eight", 556, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 556, NULL }, - { "oe", 944, NULL }, - { "Abreve", 667, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 556, NULL }, - { "Adieresis", 667, NULL }, - { "copyright", 737, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 556, NULL }, - { "Idieresis", 278, NULL }, - { "parenleft", 333, NULL }, - { "one", 556, NULL }, - { "emacron", 556, NULL }, - { "Odieresis", 778, NULL }, - { "ucircumflex", 556, NULL }, - { "bracketleft", 278, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 222, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 667, NULL }, - { "umacron", 556, NULL }, - { "abreve", 556, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 556, NULL }, - { "egrave", 556, NULL }, - { "edieresis", 556, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 889, NULL }, - { "asterisk", 389, NULL }, - { "odieresis", 556, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 556, NULL }, - { "nine", 556, NULL }, - { "five", 556, NULL }, - { "udieresis", 556, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 667, NULL }, - { "threequarters", 834, NULL }, - { "guillemotright", 556, NULL }, - { "Ccedilla", 722, NULL }, - { "ydieresis", 500, NULL }, - { "tilde", 333, NULL }, - { "at", 1015, NULL }, - { "eacute", 556, NULL }, - { "underscore", 556, NULL }, - { "Euro", 556, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 584, NULL }, - { "zero", 556, NULL }, - { "eth", 556, NULL }, - { "Scedilla", 667, NULL }, - { "Ograve", 778, NULL }, - { "Racute", 722, NULL }, - { "partialdiff", 476, NULL }, - { "uacute", 556, NULL }, - { "braceleft", 334, NULL }, - { "Thorn", 667, NULL }, - { "zcaron", 500, NULL }, - { "scommaaccent", 500, NULL }, - { "ccedilla", 500, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 556, NULL }, - { "Ocircumflex", 778, NULL }, - { "Oacute", 778, NULL }, - { "scedilla", 500, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 556, NULL }, - { "racute", 333, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 556, NULL }, - { "degree", 400, NULL }, - { "registered", 737, NULL }, - { "radical", 453, NULL }, - { "Aring", 667, NULL }, - { "percent", 889, NULL }, - { "six", 556, NULL }, - { "paragraph", 537, NULL }, - { "dcaron", 643, NULL }, - { "Uogonek", 722, NULL }, - { "two", 556, NULL }, - { "summation", 600, NULL }, - { "Igrave", 278, NULL }, - { "Lacute", 556, NULL }, - { "ocircumflex", 556, NULL }, - { "oacute", 556, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 556, NULL }, - { "tcaron", 317, NULL }, - { "eogonek", 556, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 778, NULL }, - { "asciicircum", 469, NULL }, - { "aring", 556, NULL }, - { "grave", 333, NULL }, - { "uogonek", 556, NULL }, - { "bracketright", 278, NULL }, - { "Iacute", 278, NULL }, - { "ampersand", 667, NULL }, - { "igrave", 278, NULL }, - { "lacute", 222, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 584, NULL }, - { "uring", 556, NULL }, - { "quotesinglbase", 222, NULL }, - { "lcommaaccent", 222, NULL }, - { "Yacute", 667, NULL }, - { "ohungarumlaut", 556, NULL }, - { "threesuperior", 333, NULL }, - { "acute", 333, NULL }, - { "section", 556, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 333, NULL }, - { "ncaron", 556, NULL }, - { "florin", 556, NULL }, - { "yacute", 500, NULL }, - { "Rcommaaccent", 722, NULL }, - { "fi", 500, NULL }, - { "fl", 500, NULL }, - { "Acircumflex", 667, NULL }, - { "Cacute", 722, NULL }, - { "Icircumflex", 278, NULL }, - { "guillemotleft", 556, NULL }, - { "germandbls", 611, NULL }, - { "Amacron", 667, NULL }, - { "seven", 556, NULL }, - { "Sacute", 667, NULL }, - { "ordmasculine", 365, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 556, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 278, NULL }, - { "rcommaaccent", 333, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 556, NULL }, - { "cacute", 500, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 334, NULL }, - { "quotedblright", 333, NULL }, - { "amacron", 556, NULL }, - { "sacute", 500, NULL }, - { "imacron", 278, NULL }, - { "cent", 556, NULL }, - { "currency", 556, NULL }, - { "logicalnot", 584, NULL }, - { "zdotaccent", 500, NULL }, - { "Atilde", 667, NULL }, - { "breve", 333, NULL }, - { "bar", 260, NULL }, - { "fraction", 167, NULL }, - { "less", 584, NULL }, - { "ecaron", 556, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 278, NULL }, - { "period", 278, NULL }, - { "Rcaron", 722, NULL }, - { "Kcommaaccent", 667, NULL }, - { "greater", 584, NULL }, - { "atilde", 556, NULL }, - { "brokenbar", 260, NULL }, - { "quoteleft", 222, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 333, NULL } - }; - - static BuiltinFontWidth c_arrSymbolWidthsTable[] = - { - { "bracketleftex", 384, NULL }, - { "alpha", 631, NULL }, - { "union", 768, NULL }, - { "infinity", 713, NULL }, - { "comma", 250, NULL }, - { "copyrightsans", 790, NULL }, - { "plusminus", 549, NULL }, - { "arrowup", 603, NULL }, - { "apple", 790, NULL }, - { "parenleftbt", 384, NULL }, - { "notelement", 713, NULL }, - { "colon", 278, NULL }, - { "beta", 549, NULL }, - { "braceleftbt", 494, NULL }, - { "Lambda", 686, NULL }, - { "Phi", 763, NULL }, - { "minus", 549, NULL }, - { "space", 250, NULL }, - { "Sigma", 592, NULL }, - { "approxequal", 549, NULL }, - { "minute", 247, NULL }, - { "circleplus", 768, NULL }, - { "Omicron", 722, NULL }, - { "three", 500, NULL }, - { "numbersign", 500, NULL }, - { "lambda", 549, NULL }, - { "phi", 521, NULL }, - { "aleph", 823, NULL }, - { "Tau", 611, NULL }, - { "spade", 753, NULL }, - { "logicaland", 603, NULL }, - { "sigma", 603, NULL }, - { "propersuperset", 713, NULL }, - { "omicron", 549, NULL }, - { "question", 444, NULL }, - { "equal", 549, NULL }, - { "Epsilon", 611, NULL }, - { "emptyset", 823, NULL }, - { "diamond", 753, NULL }, - { "four", 500, NULL }, - { "Mu", 889, NULL }, - { "parenlefttp", 384, NULL }, - { "club", 753, NULL }, - { "bullet", 460, NULL }, - { "Omega", 768, NULL }, - { "tau", 439, NULL }, - { "Upsilon", 690, NULL }, - { "bracelefttp", 494, NULL }, - { "heart", 753, NULL }, - { "divide", 549, NULL }, - { "epsilon", 439, NULL }, - { "logicalor", 603, NULL }, - { "parenleftex", 384, NULL }, - { "greaterequal", 549, NULL }, - { "mu", 576, NULL }, - { "Nu", 722, NULL }, - { "therefore", 863, NULL }, - { "notsubset", 713, NULL }, - { "omega", 686, NULL }, - { "semicolon", 278, NULL }, - { "element", 713, NULL }, - { "upsilon", 576, NULL }, - { "existential", 549, NULL }, - { "integralbt", 686, NULL }, - { "lessequal", 549, NULL }, - { "phi1", 603, NULL }, - { "lozenge", 494, NULL }, - { "trademarkserif", 890, NULL }, - { "parenright", 333, NULL }, - { "reflexsuperset", 713, NULL }, - { "sigma1", 439, NULL }, - { "nu", 521, NULL }, - { "Gamma", 603, NULL }, - { "angleright", 329, NULL }, - { "ellipsis", 1000, NULL }, - { "Rho", 556, NULL }, - { "parenrightbt", 384, NULL }, - { "radicalex", 500, NULL }, - { "eight", 500, NULL }, - { "angleleft", 329, NULL }, - { "arrowdbldown", 603, NULL }, - { "congruent", 549, NULL }, - { "Theta", 741, NULL }, - { "intersection", 768, NULL }, - { "Pi", 768, NULL }, - { "slash", 278, NULL }, - { "registerserif", 790, NULL }, - { "parenleft", 333, NULL }, - { "one", 500, NULL }, - { "gamma", 411, NULL }, - { "bracketleft", 333, NULL }, - { "rho", 549, NULL }, - { "circlemultiply", 768, NULL }, - { "Chi", 722, NULL }, - { "theta", 521, NULL }, - { "pi", 549, NULL }, - { "integraltp", 686, NULL }, - { "Eta", 722, NULL }, - { "product", 823, NULL }, - { "nine", 500, NULL }, - { "five", 500, NULL }, - { "propersubset", 713, NULL }, - { "bracketrightbt", 384, NULL }, - { "trademarksans", 786, NULL }, - { "dotmath", 250, NULL }, - { "integralex", 686, NULL }, - { "chi", 549, NULL }, - { "parenrighttp", 384, NULL }, - { "eta", 603, NULL }, - { "underscore", 500, NULL }, - { "Euro", 750, NULL }, - { "multiply", 549, NULL }, - { "zero", 500, NULL }, - { "partialdiff", 494, NULL }, - { "angle", 768, NULL }, - { "arrowdblleft", 987, NULL }, - { "braceleft", 480, NULL }, - { "parenrightex", 384, NULL }, - { "Rfraktur", 795, NULL }, - { "Zeta", 611, NULL }, - { "braceex", 494, NULL }, - { "arrowdblup", 603, NULL }, - { "arrowdown", 603, NULL }, - { "Ifraktur", 686, NULL }, - { "degree", 400, NULL }, - { "Iota", 333, NULL }, - { "perpendicular", 658, NULL }, - { "radical", 549, NULL }, - { "asteriskmath", 500, NULL }, - { "percent", 833, NULL }, - { "zeta", 494, NULL }, - { "six", 500, NULL }, - { "two", 500, NULL }, - { "weierstrass", 987, NULL }, - { "summation", 713, NULL }, - { "bracketrighttp", 384, NULL }, - { "carriagereturn", 658, NULL }, - { "suchthat", 439, NULL }, - { "arrowvertex", 603, NULL }, - { "Delta", 612, NULL }, - { "iota", 329, NULL }, - { "arrowhorizex", 1000, NULL }, - { "bracketrightex", 384, NULL }, - { "bracketright", 333, NULL }, - { "ampersand", 778, NULL }, - { "plus", 549, NULL }, - { "proportional", 713, NULL }, - { "delta", 494, NULL }, - { "copyrightserif", 790, NULL }, - { "bracerightmid", 494, NULL }, - { "arrowleft", 987, NULL }, - { "second", 411, NULL }, - { "arrowdblboth", 1042, NULL }, - { "florin", 500, NULL }, - { "Psi", 795, NULL }, - { "bracerightbt", 494, NULL }, - { "bracketleftbt", 384, NULL }, - { "seven", 500, NULL }, - { "braceleftmid", 494, NULL }, - { "notequal", 549, NULL }, - { "psi", 686, NULL }, - { "equivalence", 549, NULL }, - { "universal", 713, NULL }, - { "arrowdblright", 987, NULL }, - { "braceright", 480, NULL }, - { "reflexsubset", 713, NULL }, - { "Xi", 645, NULL }, - { "theta1", 631, NULL }, - { "logicalnot", 713, NULL }, - { "Kappa", 722, NULL }, - { "similar", 549, NULL }, - { "bar", 200, NULL }, - { "fraction", 167, NULL }, - { "less", 549, NULL }, - { "registersans", 790, NULL }, - { "omega1", 713, NULL }, - { "exclam", 333, NULL }, - { "Upsilon1", 620, NULL }, - { "bracerighttp", 494, NULL }, - { "xi", 493, NULL }, - { "period", 250, NULL }, - { "Alpha", 722, NULL }, - { "arrowright", 987, NULL }, - { "greater", 549, NULL }, - { "bracketlefttp", 384, NULL }, - { "kappa", 549, NULL }, - { "gradient", 713, NULL }, - { "integral", 274, NULL }, - { "arrowboth", 1042, NULL }, - { "Beta", 667, NULL } - }; - - static BuiltinFontWidth c_arrTimesBoldWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 444, NULL }, - { "kcommaaccent", 556, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 667, NULL }, - { "comma", 250, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 570, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 444, NULL }, - { "asciitilde", 520, NULL }, - { "colon", 333, NULL }, - { "onehalf", 750, NULL }, - { "dollar", 500, NULL }, - { "Lcaron", 667, NULL }, - { "ntilde", 556, NULL }, - { "Aogonek", 722, NULL }, - { "ncommaaccent", 556, NULL }, - { "minus", 570, NULL }, - { "Iogonek", 389, NULL }, - { "zacute", 444, NULL }, - { "yen", 500, NULL }, - { "space", 250, NULL }, - { "Omacron", 778, NULL }, - { "questiondown", 500, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 722, NULL }, - { "three", 500, NULL }, - { "numbersign", 500, NULL }, - { "lcaron", 394, NULL }, - { "A", 722, NULL }, - { "B", 667, NULL }, - { "C", 722, NULL }, - { "aogonek", 500, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 750, NULL }, - { "F", 611, NULL }, - { "G", 778, NULL }, - { "H", 778, NULL }, - { "I", 389, NULL }, - { "J", 500, NULL }, - { "K", 778, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 667, NULL }, - { "periodcentered", 250, NULL }, - { "M", 944, NULL }, - { "N", 722, NULL }, - { "omacron", 500, NULL }, - { "Tcommaaccent", 667, NULL }, - { "O", 778, NULL }, - { "P", 611, NULL }, - { "Q", 778, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 722, NULL }, - { "Aacute", 722, NULL }, - { "caron", 333, NULL }, - { "S", 556, NULL }, - { "T", 667, NULL }, - { "U", 722, NULL }, - { "agrave", 500, NULL }, - { "V", 722, NULL }, - { "W", 1000, NULL }, - { "X", 722, NULL }, - { "question", 500, NULL }, - { "equal", 570, NULL }, - { "Y", 722, NULL }, - { "Z", 667, NULL }, - { "four", 500, NULL }, - { "a", 500, NULL }, - { "Gcommaaccent", 778, NULL }, - { "b", 556, NULL }, - { "c", 444, NULL }, - { "d", 556, NULL }, - { "e", 444, NULL }, - { "f", 333, NULL }, - { "g", 500, NULL }, - { "bullet", 350, NULL }, - { "h", 556, NULL }, - { "i", 278, NULL }, - { "Oslash", 778, NULL }, - { "dagger", 500, NULL }, - { "j", 333, NULL }, - { "k", 556, NULL }, - { "l", 278, NULL }, - { "m", 833, NULL }, - { "n", 556, NULL }, - { "tcommaaccent", 333, NULL }, - { "o", 500, NULL }, - { "ordfeminine", 300, NULL }, - { "ring", 333, NULL }, - { "p", 556, NULL }, - { "q", 556, NULL }, - { "uhungarumlaut", 556, NULL }, - { "r", 444, NULL }, - { "twosuperior", 300, NULL }, - { "aacute", 500, NULL }, - { "s", 389, NULL }, - { "OE", 1000, NULL }, - { "t", 333, NULL }, - { "divide", 570, NULL }, - { "u", 556, NULL }, - { "Ccaron", 722, NULL }, - { "v", 500, NULL }, - { "w", 722, NULL }, - { "x", 500, NULL }, - { "y", 500, NULL }, - { "z", 444, NULL }, - { "Gbreve", 778, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 389, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 555, NULL }, - { "gcommaaccent", 500, NULL }, - { "mu", 556, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 556, NULL }, - { "Lslash", 667, NULL }, - { "semicolon", 333, NULL }, - { "oslash", 500, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 494, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 444, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 500, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 500, NULL }, - { "nacute", 556, NULL }, - { "macron", 333, NULL }, - { "Otilde", 778, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 389, NULL }, - { "AE", 1000, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 500, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 278, NULL }, - { "eight", 500, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 500, NULL }, - { "oe", 722, NULL }, - { "Abreve", 722, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 444, NULL }, - { "Adieresis", 722, NULL }, - { "copyright", 747, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 500, NULL }, - { "Idieresis", 389, NULL }, - { "parenleft", 333, NULL }, - { "one", 500, NULL }, - { "emacron", 444, NULL }, - { "Odieresis", 778, NULL }, - { "ucircumflex", 556, NULL }, - { "bracketleft", 333, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 333, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 722, NULL }, - { "umacron", 556, NULL }, - { "abreve", 500, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 500, NULL }, - { "egrave", 444, NULL }, - { "edieresis", 444, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 722, NULL }, - { "asterisk", 500, NULL }, - { "odieresis", 500, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 556, NULL }, - { "nine", 500, NULL }, - { "five", 500, NULL }, - { "udieresis", 556, NULL }, - { "Zcaron", 667, NULL }, - { "Scommaaccent", 556, NULL }, - { "threequarters", 750, NULL }, - { "guillemotright", 500, NULL }, - { "Ccedilla", 722, NULL }, - { "ydieresis", 500, NULL }, - { "tilde", 333, NULL }, - { "at", 930, NULL }, - { "eacute", 444, NULL }, - { "underscore", 500, NULL }, - { "Euro", 500, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 570, NULL }, - { "zero", 500, NULL }, - { "eth", 500, NULL }, - { "Scedilla", 556, NULL }, - { "Ograve", 778, NULL }, - { "Racute", 722, NULL }, - { "partialdiff", 494, NULL }, - { "uacute", 556, NULL }, - { "braceleft", 394, NULL }, - { "Thorn", 611, NULL }, - { "zcaron", 444, NULL }, - { "scommaaccent", 389, NULL }, - { "ccedilla", 444, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 556, NULL }, - { "Ocircumflex", 778, NULL }, - { "Oacute", 778, NULL }, - { "scedilla", 389, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 500, NULL }, - { "racute", 444, NULL }, - { "Tcaron", 667, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 556, NULL }, - { "degree", 400, NULL }, - { "registered", 747, NULL }, - { "radical", 549, NULL }, - { "Aring", 722, NULL }, - { "percent", 1000, NULL }, - { "six", 500, NULL }, - { "paragraph", 540, NULL }, - { "dcaron", 672, NULL }, - { "Uogonek", 722, NULL }, - { "two", 500, NULL }, - { "summation", 600, NULL }, - { "Igrave", 389, NULL }, - { "Lacute", 667, NULL }, - { "ocircumflex", 500, NULL }, - { "oacute", 500, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 667, NULL }, - { "tcaron", 416, NULL }, - { "eogonek", 444, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 778, NULL }, - { "asciicircum", 581, NULL }, - { "aring", 500, NULL }, - { "grave", 333, NULL }, - { "uogonek", 556, NULL }, - { "bracketright", 333, NULL }, - { "Iacute", 389, NULL }, - { "ampersand", 833, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 570, NULL }, - { "uring", 556, NULL }, - { "quotesinglbase", 333, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 722, NULL }, - { "ohungarumlaut", 500, NULL }, - { "threesuperior", 300, NULL }, - { "acute", 333, NULL }, - { "section", 500, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 500, NULL }, - { "ncaron", 556, NULL }, - { "florin", 500, NULL }, - { "yacute", 500, NULL }, - { "Rcommaaccent", 722, NULL }, - { "fi", 556, NULL }, - { "fl", 556, NULL }, - { "Acircumflex", 722, NULL }, - { "Cacute", 722, NULL }, - { "Icircumflex", 389, NULL }, - { "guillemotleft", 500, NULL }, - { "germandbls", 556, NULL }, - { "Amacron", 722, NULL }, - { "seven", 500, NULL }, - { "Sacute", 556, NULL }, - { "ordmasculine", 330, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 500, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 389, NULL }, - { "rcommaaccent", 444, NULL }, - { "Zdotaccent", 667, NULL }, - { "acircumflex", 500, NULL }, - { "cacute", 444, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 394, NULL }, - { "quotedblright", 500, NULL }, - { "amacron", 500, NULL }, - { "sacute", 389, NULL }, - { "imacron", 278, NULL }, - { "cent", 500, NULL }, - { "currency", 500, NULL }, - { "logicalnot", 570, NULL }, - { "zdotaccent", 444, NULL }, - { "Atilde", 722, NULL }, - { "breve", 333, NULL }, - { "bar", 220, NULL }, - { "fraction", 167, NULL }, - { "less", 570, NULL }, - { "ecaron", 444, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 333, NULL }, - { "period", 250, NULL }, - { "Rcaron", 722, NULL }, - { "Kcommaaccent", 778, NULL }, - { "greater", 570, NULL }, - { "atilde", 500, NULL }, - { "brokenbar", 220, NULL }, - { "quoteleft", 333, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 300, NULL } - }; - - static BuiltinFontWidth c_arrTimesBoldItalicWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 389, NULL }, - { "kcommaaccent", 500, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 250, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 570, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 444, NULL }, - { "asciitilde", 570, NULL }, - { "colon", 333, NULL }, - { "onehalf", 750, NULL }, - { "dollar", 500, NULL }, - { "Lcaron", 611, NULL }, - { "ntilde", 556, NULL }, - { "Aogonek", 667, NULL }, - { "ncommaaccent", 556, NULL }, - { "minus", 606, NULL }, - { "Iogonek", 389, NULL }, - { "zacute", 389, NULL }, - { "yen", 500, NULL }, - { "space", 250, NULL }, - { "Omacron", 722, NULL }, - { "questiondown", 500, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 667, NULL }, - { "three", 500, NULL }, - { "numbersign", 500, NULL }, - { "lcaron", 382, NULL }, - { "A", 667, NULL }, - { "B", 667, NULL }, - { "C", 667, NULL }, - { "aogonek", 500, NULL }, - { "D", 722, NULL }, - { "E", 667, NULL }, - { "onequarter", 750, NULL }, - { "F", 667, NULL }, - { "G", 722, NULL }, - { "H", 778, NULL }, - { "I", 389, NULL }, - { "J", 500, NULL }, - { "K", 667, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 611, NULL }, - { "periodcentered", 250, NULL }, - { "M", 889, NULL }, - { "N", 722, NULL }, - { "omacron", 500, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 722, NULL }, - { "P", 611, NULL }, - { "Q", 722, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 667, NULL }, - { "Aacute", 667, NULL }, - { "caron", 333, NULL }, - { "S", 556, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 500, NULL }, - { "V", 667, NULL }, - { "W", 889, NULL }, - { "X", 667, NULL }, - { "question", 500, NULL }, - { "equal", 570, NULL }, - { "Y", 611, NULL }, - { "Z", 611, NULL }, - { "four", 500, NULL }, - { "a", 500, NULL }, - { "Gcommaaccent", 722, NULL }, - { "b", 500, NULL }, - { "c", 444, NULL }, - { "d", 500, NULL }, - { "e", 444, NULL }, - { "f", 333, NULL }, - { "g", 500, NULL }, - { "bullet", 350, NULL }, - { "h", 556, NULL }, - { "i", 278, NULL }, - { "Oslash", 722, NULL }, - { "dagger", 500, NULL }, - { "j", 278, NULL }, - { "k", 500, NULL }, - { "l", 278, NULL }, - { "m", 778, NULL }, - { "n", 556, NULL }, - { "tcommaaccent", 278, NULL }, - { "o", 500, NULL }, - { "ordfeminine", 266, NULL }, - { "ring", 333, NULL }, - { "p", 500, NULL }, - { "q", 500, NULL }, - { "uhungarumlaut", 556, NULL }, - { "r", 389, NULL }, - { "twosuperior", 300, NULL }, - { "aacute", 500, NULL }, - { "s", 389, NULL }, - { "OE", 944, NULL }, - { "t", 278, NULL }, - { "divide", 570, NULL }, - { "u", 556, NULL }, - { "Ccaron", 667, NULL }, - { "v", 444, NULL }, - { "w", 667, NULL }, - { "x", 500, NULL }, - { "y", 444, NULL }, - { "z", 389, NULL }, - { "Gbreve", 722, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 389, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 555, NULL }, - { "gcommaaccent", 500, NULL }, - { "mu", 576, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 556, NULL }, - { "Lslash", 611, NULL }, - { "semicolon", 333, NULL }, - { "oslash", 500, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 494, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 444, NULL }, - { "Ecircumflex", 667, NULL }, - { "gbreve", 500, NULL }, - { "trademark", 1000, NULL }, - { "daggerdbl", 500, NULL }, - { "nacute", 556, NULL }, - { "macron", 333, NULL }, - { "Otilde", 722, NULL }, - { "Emacron", 667, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 389, NULL }, - { "AE", 944, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 500, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 278, NULL }, - { "eight", 500, NULL }, - { "exclamdown", 389, NULL }, - { "endash", 500, NULL }, - { "oe", 722, NULL }, - { "Abreve", 667, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 444, NULL }, - { "Adieresis", 667, NULL }, - { "copyright", 747, NULL }, - { "Egrave", 667, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 667, NULL }, - { "otilde", 500, NULL }, - { "Idieresis", 389, NULL }, - { "parenleft", 333, NULL }, - { "one", 500, NULL }, - { "emacron", 444, NULL }, - { "Odieresis", 722, NULL }, - { "ucircumflex", 556, NULL }, - { "bracketleft", 333, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 333, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 611, NULL }, - { "umacron", 556, NULL }, - { "abreve", 500, NULL }, - { "Eacute", 667, NULL }, - { "adieresis", 500, NULL }, - { "egrave", 444, NULL }, - { "edieresis", 444, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 722, NULL }, - { "asterisk", 500, NULL }, - { "odieresis", 500, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 556, NULL }, - { "nine", 500, NULL }, - { "five", 500, NULL }, - { "udieresis", 556, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 556, NULL }, - { "threequarters", 750, NULL }, - { "guillemotright", 500, NULL }, - { "Ccedilla", 667, NULL }, - { "ydieresis", 444, NULL }, - { "tilde", 333, NULL }, - { "at", 832, NULL }, - { "eacute", 444, NULL }, - { "underscore", 500, NULL }, - { "Euro", 500, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 570, NULL }, - { "zero", 500, NULL }, - { "eth", 500, NULL }, - { "Scedilla", 556, NULL }, - { "Ograve", 722, NULL }, - { "Racute", 667, NULL }, - { "partialdiff", 494, NULL }, - { "uacute", 556, NULL }, - { "braceleft", 348, NULL }, - { "Thorn", 611, NULL }, - { "zcaron", 389, NULL }, - { "scommaaccent", 389, NULL }, - { "ccedilla", 444, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 500, NULL }, - { "Ocircumflex", 722, NULL }, - { "Oacute", 722, NULL }, - { "scedilla", 389, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 500, NULL }, - { "racute", 389, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 667, NULL }, - { "thorn", 500, NULL }, - { "degree", 400, NULL }, - { "registered", 747, NULL }, - { "radical", 549, NULL }, - { "Aring", 667, NULL }, - { "percent", 833, NULL }, - { "six", 500, NULL }, - { "paragraph", 500, NULL }, - { "dcaron", 608, NULL }, - { "Uogonek", 722, NULL }, - { "two", 500, NULL }, - { "summation", 600, NULL }, - { "Igrave", 389, NULL }, - { "Lacute", 611, NULL }, - { "ocircumflex", 500, NULL }, - { "oacute", 500, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 611, NULL }, - { "tcaron", 366, NULL }, - { "eogonek", 444, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 722, NULL }, - { "asciicircum", 570, NULL }, - { "aring", 500, NULL }, - { "grave", 333, NULL }, - { "uogonek", 556, NULL }, - { "bracketright", 333, NULL }, - { "Iacute", 389, NULL }, - { "ampersand", 778, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 570, NULL }, - { "uring", 556, NULL }, - { "quotesinglbase", 333, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 611, NULL }, - { "ohungarumlaut", 500, NULL }, - { "threesuperior", 300, NULL }, - { "acute", 333, NULL }, - { "section", 500, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 500, NULL }, - { "ncaron", 556, NULL }, - { "florin", 500, NULL }, - { "yacute", 444, NULL }, - { "Rcommaaccent", 667, NULL }, - { "fi", 556, NULL }, - { "fl", 556, NULL }, - { "Acircumflex", 667, NULL }, - { "Cacute", 667, NULL }, - { "Icircumflex", 389, NULL }, - { "guillemotleft", 500, NULL }, - { "germandbls", 500, NULL }, - { "Amacron", 667, NULL }, - { "seven", 500, NULL }, - { "Sacute", 556, NULL }, - { "ordmasculine", 300, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 500, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 389, NULL }, - { "rcommaaccent", 389, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 500, NULL }, - { "cacute", 444, NULL }, - { "Ecaron", 667, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 348, NULL }, - { "quotedblright", 500, NULL }, - { "amacron", 500, NULL }, - { "sacute", 389, NULL }, - { "imacron", 278, NULL }, - { "cent", 500, NULL }, - { "currency", 500, NULL }, - { "logicalnot", 606, NULL }, - { "zdotaccent", 389, NULL }, - { "Atilde", 667, NULL }, - { "breve", 333, NULL }, - { "bar", 220, NULL }, - { "fraction", 167, NULL }, - { "less", 570, NULL }, - { "ecaron", 444, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 389, NULL }, - { "period", 250, NULL }, - { "Rcaron", 667, NULL }, - { "Kcommaaccent", 667, NULL }, - { "greater", 570, NULL }, - { "atilde", 500, NULL }, - { "brokenbar", 220, NULL }, - { "quoteleft", 333, NULL }, - { "Edotaccent", 667, NULL }, - { "onesuperior", 300, NULL } - }; - - static BuiltinFontWidth c_arrTimesItalicWidthsTable[] = - { - { "Ntilde", 667, NULL }, - { "rcaron", 389, NULL }, - { "kcommaaccent", 444, NULL }, - { "Ncommaaccent", 667, NULL }, - { "Zacute", 556, NULL }, - { "comma", 250, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 675, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 444, NULL }, - { "asciitilde", 541, NULL }, - { "colon", 333, NULL }, - { "onehalf", 750, NULL }, - { "dollar", 500, NULL }, - { "Lcaron", 611, NULL }, - { "ntilde", 500, NULL }, - { "Aogonek", 611, NULL }, - { "ncommaaccent", 500, NULL }, - { "minus", 675, NULL }, - { "Iogonek", 333, NULL }, - { "zacute", 389, NULL }, - { "yen", 500, NULL }, - { "space", 250, NULL }, - { "Omacron", 722, NULL }, - { "questiondown", 500, NULL }, - { "emdash", 889, NULL }, - { "Agrave", 611, NULL }, - { "three", 500, NULL }, - { "numbersign", 500, NULL }, - { "lcaron", 300, NULL }, - { "A", 611, NULL }, - { "B", 611, NULL }, - { "C", 667, NULL }, - { "aogonek", 500, NULL }, - { "D", 722, NULL }, - { "E", 611, NULL }, - { "onequarter", 750, NULL }, - { "F", 611, NULL }, - { "G", 722, NULL }, - { "H", 722, NULL }, - { "I", 333, NULL }, - { "J", 444, NULL }, - { "K", 667, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 556, NULL }, - { "periodcentered", 250, NULL }, - { "M", 833, NULL }, - { "N", 667, NULL }, - { "omacron", 500, NULL }, - { "Tcommaaccent", 556, NULL }, - { "O", 722, NULL }, - { "P", 611, NULL }, - { "Q", 722, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 611, NULL }, - { "Aacute", 611, NULL }, - { "caron", 333, NULL }, - { "S", 500, NULL }, - { "T", 556, NULL }, - { "U", 722, NULL }, - { "agrave", 500, NULL }, - { "V", 611, NULL }, - { "W", 833, NULL }, - { "X", 611, NULL }, - { "question", 500, NULL }, - { "equal", 675, NULL }, - { "Y", 556, NULL }, - { "Z", 556, NULL }, - { "four", 500, NULL }, - { "a", 500, NULL }, - { "Gcommaaccent", 722, NULL }, - { "b", 500, NULL }, - { "c", 444, NULL }, - { "d", 500, NULL }, - { "e", 444, NULL }, - { "f", 278, NULL }, - { "g", 500, NULL }, - { "bullet", 350, NULL }, - { "h", 500, NULL }, - { "i", 278, NULL }, - { "Oslash", 722, NULL }, - { "dagger", 500, NULL }, - { "j", 278, NULL }, - { "k", 444, NULL }, - { "l", 278, NULL }, - { "m", 722, NULL }, - { "n", 500, NULL }, - { "tcommaaccent", 278, NULL }, - { "o", 500, NULL }, - { "ordfeminine", 276, NULL }, - { "ring", 333, NULL }, - { "p", 500, NULL }, - { "q", 500, NULL }, - { "uhungarumlaut", 500, NULL }, - { "r", 389, NULL }, - { "twosuperior", 300, NULL }, - { "aacute", 500, NULL }, - { "s", 389, NULL }, - { "OE", 944, NULL }, - { "t", 278, NULL }, - { "divide", 675, NULL }, - { "u", 500, NULL }, - { "Ccaron", 667, NULL }, - { "v", 444, NULL }, - { "w", 667, NULL }, - { "x", 444, NULL }, - { "y", 444, NULL }, - { "z", 389, NULL }, - { "Gbreve", 722, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 333, NULL }, - { "Nacute", 667, NULL }, - { "quotedbl", 420, NULL }, - { "gcommaaccent", 500, NULL }, - { "mu", 500, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 500, NULL }, - { "Lslash", 556, NULL }, - { "semicolon", 333, NULL }, - { "oslash", 500, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 471, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 444, NULL }, - { "Ecircumflex", 611, NULL }, - { "gbreve", 500, NULL }, - { "trademark", 980, NULL }, - { "daggerdbl", 500, NULL }, - { "nacute", 500, NULL }, - { "macron", 333, NULL }, - { "Otilde", 722, NULL }, - { "Emacron", 611, NULL }, - { "ellipsis", 889, NULL }, - { "scaron", 389, NULL }, - { "AE", 889, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 556, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 214, NULL }, - { "eight", 500, NULL }, - { "exclamdown", 389, NULL }, - { "endash", 500, NULL }, - { "oe", 667, NULL }, - { "Abreve", 611, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 444, NULL }, - { "Adieresis", 611, NULL }, - { "copyright", 760, NULL }, - { "Egrave", 611, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 611, NULL }, - { "otilde", 500, NULL }, - { "Idieresis", 333, NULL }, - { "parenleft", 333, NULL }, - { "one", 500, NULL }, - { "emacron", 444, NULL }, - { "Odieresis", 722, NULL }, - { "ucircumflex", 500, NULL }, - { "bracketleft", 389, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 333, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 556, NULL }, - { "umacron", 500, NULL }, - { "abreve", 500, NULL }, - { "Eacute", 611, NULL }, - { "adieresis", 500, NULL }, - { "egrave", 444, NULL }, - { "edieresis", 444, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 667, NULL }, - { "asterisk", 500, NULL }, - { "odieresis", 500, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 500, NULL }, - { "nine", 500, NULL }, - { "five", 500, NULL }, - { "udieresis", 500, NULL }, - { "Zcaron", 556, NULL }, - { "Scommaaccent", 500, NULL }, - { "threequarters", 750, NULL }, - { "guillemotright", 500, NULL }, - { "Ccedilla", 667, NULL }, - { "ydieresis", 444, NULL }, - { "tilde", 333, NULL }, - { "at", 920, NULL }, - { "eacute", 444, NULL }, - { "underscore", 500, NULL }, - { "Euro", 500, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 675, NULL }, - { "zero", 500, NULL }, - { "eth", 500, NULL }, - { "Scedilla", 500, NULL }, - { "Ograve", 722, NULL }, - { "Racute", 611, NULL }, - { "partialdiff", 476, NULL }, - { "uacute", 500, NULL }, - { "braceleft", 400, NULL }, - { "Thorn", 611, NULL }, - { "zcaron", 389, NULL }, - { "scommaaccent", 389, NULL }, - { "ccedilla", 444, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 500, NULL }, - { "Ocircumflex", 722, NULL }, - { "Oacute", 722, NULL }, - { "scedilla", 389, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 500, NULL }, - { "racute", 389, NULL }, - { "Tcaron", 556, NULL }, - { "Eogonek", 611, NULL }, - { "thorn", 500, NULL }, - { "degree", 400, NULL }, - { "registered", 760, NULL }, - { "radical", 453, NULL }, - { "Aring", 611, NULL }, - { "percent", 833, NULL }, - { "six", 500, NULL }, - { "paragraph", 523, NULL }, - { "dcaron", 544, NULL }, - { "Uogonek", 722, NULL }, - { "two", 500, NULL }, - { "summation", 600, NULL }, - { "Igrave", 333, NULL }, - { "Lacute", 556, NULL }, - { "ocircumflex", 500, NULL }, - { "oacute", 500, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 556, NULL }, - { "tcaron", 300, NULL }, - { "eogonek", 444, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 722, NULL }, - { "asciicircum", 422, NULL }, - { "aring", 500, NULL }, - { "grave", 333, NULL }, - { "uogonek", 500, NULL }, - { "bracketright", 389, NULL }, - { "Iacute", 333, NULL }, - { "ampersand", 778, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 667, NULL }, - { "plus", 675, NULL }, - { "uring", 500, NULL }, - { "quotesinglbase", 333, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 556, NULL }, - { "ohungarumlaut", 500, NULL }, - { "threesuperior", 300, NULL }, - { "acute", 333, NULL }, - { "section", 500, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 556, NULL }, - { "ncaron", 500, NULL }, - { "florin", 500, NULL }, - { "yacute", 444, NULL }, - { "Rcommaaccent", 611, NULL }, - { "fi", 500, NULL }, - { "fl", 500, NULL }, - { "Acircumflex", 611, NULL }, - { "Cacute", 667, NULL }, - { "Icircumflex", 333, NULL }, - { "guillemotleft", 500, NULL }, - { "germandbls", 500, NULL }, - { "Amacron", 611, NULL }, - { "seven", 500, NULL }, - { "Sacute", 500, NULL }, - { "ordmasculine", 310, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 500, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 333, NULL }, - { "rcommaaccent", 389, NULL }, - { "Zdotaccent", 556, NULL }, - { "acircumflex", 500, NULL }, - { "cacute", 444, NULL }, - { "Ecaron", 611, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 400, NULL }, - { "quotedblright", 556, NULL }, - { "amacron", 500, NULL }, - { "sacute", 389, NULL }, - { "imacron", 278, NULL }, - { "cent", 500, NULL }, - { "currency", 500, NULL }, - { "logicalnot", 675, NULL }, - { "zdotaccent", 389, NULL }, - { "Atilde", 611, NULL }, - { "breve", 333, NULL }, - { "bar", 275, NULL }, - { "fraction", 167, NULL }, - { "less", 675, NULL }, - { "ecaron", 444, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 333, NULL }, - { "period", 250, NULL }, - { "Rcaron", 611, NULL }, - { "Kcommaaccent", 667, NULL }, - { "greater", 675, NULL }, - { "atilde", 500, NULL }, - { "brokenbar", 275, NULL }, - { "quoteleft", 333, NULL }, - { "Edotaccent", 611, NULL }, - { "onesuperior", 300, NULL } - }; - - static BuiltinFontWidth c_arrTimesRomanWidthsTable[] = - { - { "Ntilde", 722, NULL }, - { "rcaron", 333, NULL }, - { "kcommaaccent", 500, NULL }, - { "Ncommaaccent", 722, NULL }, - { "Zacute", 611, NULL }, - { "comma", 250, NULL }, - { "cedilla", 333, NULL }, - { "plusminus", 564, NULL }, - { "circumflex", 333, NULL }, - { "dotaccent", 333, NULL }, - { "edotaccent", 444, NULL }, - { "asciitilde", 541, NULL }, - { "colon", 278, NULL }, - { "onehalf", 750, NULL }, - { "dollar", 500, NULL }, - { "Lcaron", 611, NULL }, - { "ntilde", 500, NULL }, - { "Aogonek", 722, NULL }, - { "ncommaaccent", 500, NULL }, - { "minus", 564, NULL }, - { "Iogonek", 333, NULL }, - { "zacute", 444, NULL }, - { "yen", 500, NULL }, - { "space", 250, NULL }, - { "Omacron", 722, NULL }, - { "questiondown", 444, NULL }, - { "emdash", 1000, NULL }, - { "Agrave", 722, NULL }, - { "three", 500, NULL }, - { "numbersign", 500, NULL }, - { "lcaron", 344, NULL }, - { "A", 722, NULL }, - { "B", 667, NULL }, - { "C", 667, NULL }, - { "aogonek", 444, NULL }, - { "D", 722, NULL }, - { "E", 611, NULL }, - { "onequarter", 750, NULL }, - { "F", 556, NULL }, - { "G", 722, NULL }, - { "H", 722, NULL }, - { "I", 333, NULL }, - { "J", 389, NULL }, - { "K", 722, NULL }, - { "iogonek", 278, NULL }, - { "backslash", 278, NULL }, - { "L", 611, NULL }, - { "periodcentered", 250, NULL }, - { "M", 889, NULL }, - { "N", 722, NULL }, - { "omacron", 500, NULL }, - { "Tcommaaccent", 611, NULL }, - { "O", 722, NULL }, - { "P", 556, NULL }, - { "Q", 722, NULL }, - { "Uhungarumlaut", 722, NULL }, - { "R", 667, NULL }, - { "Aacute", 722, NULL }, - { "caron", 333, NULL }, - { "S", 556, NULL }, - { "T", 611, NULL }, - { "U", 722, NULL }, - { "agrave", 444, NULL }, - { "V", 722, NULL }, - { "W", 944, NULL }, - { "X", 722, NULL }, - { "question", 444, NULL }, - { "equal", 564, NULL }, - { "Y", 722, NULL }, - { "Z", 611, NULL }, - { "four", 500, NULL }, - { "a", 444, NULL }, - { "Gcommaaccent", 722, NULL }, - { "b", 500, NULL }, - { "c", 444, NULL }, - { "d", 500, NULL }, - { "e", 444, NULL }, - { "f", 333, NULL }, - { "g", 500, NULL }, - { "bullet", 350, NULL }, - { "h", 500, NULL }, - { "i", 278, NULL }, - { "Oslash", 722, NULL }, - { "dagger", 500, NULL }, - { "j", 278, NULL }, - { "k", 500, NULL }, - { "l", 278, NULL }, - { "m", 778, NULL }, - { "n", 500, NULL }, - { "tcommaaccent", 278, NULL }, - { "o", 500, NULL }, - { "ordfeminine", 276, NULL }, - { "ring", 333, NULL }, - { "p", 500, NULL }, - { "q", 500, NULL }, - { "uhungarumlaut", 500, NULL }, - { "r", 333, NULL }, - { "twosuperior", 300, NULL }, - { "aacute", 444, NULL }, - { "s", 389, NULL }, - { "OE", 889, NULL }, - { "t", 278, NULL }, - { "divide", 564, NULL }, - { "u", 500, NULL }, - { "Ccaron", 667, NULL }, - { "v", 500, NULL }, - { "w", 722, NULL }, - { "x", 500, NULL }, - { "y", 500, NULL }, - { "z", 444, NULL }, - { "Gbreve", 722, NULL }, - { "commaaccent", 250, NULL }, - { "hungarumlaut", 333, NULL }, - { "Idotaccent", 333, NULL }, - { "Nacute", 722, NULL }, - { "quotedbl", 408, NULL }, - { "gcommaaccent", 500, NULL }, - { "mu", 500, NULL }, - { "greaterequal", 549, NULL }, - { "Scaron", 556, NULL }, - { "Lslash", 611, NULL }, - { "semicolon", 278, NULL }, - { "oslash", 500, NULL }, - { "lessequal", 549, NULL }, - { "lozenge", 471, NULL }, - { "parenright", 333, NULL }, - { "ccaron", 444, NULL }, - { "Ecircumflex", 611, NULL }, - { "gbreve", 500, NULL }, - { "trademark", 980, NULL }, - { "daggerdbl", 500, NULL }, - { "nacute", 500, NULL }, - { "macron", 333, NULL }, - { "Otilde", 722, NULL }, - { "Emacron", 611, NULL }, - { "ellipsis", 1000, NULL }, - { "scaron", 389, NULL }, - { "AE", 889, NULL }, - { "Ucircumflex", 722, NULL }, - { "lslash", 278, NULL }, - { "quotedblleft", 444, NULL }, - { "guilsinglright", 333, NULL }, - { "hyphen", 333, NULL }, - { "quotesingle", 180, NULL }, - { "eight", 500, NULL }, - { "exclamdown", 333, NULL }, - { "endash", 500, NULL }, - { "oe", 722, NULL }, - { "Abreve", 722, NULL }, - { "Umacron", 722, NULL }, - { "ecircumflex", 444, NULL }, - { "Adieresis", 722, NULL }, - { "copyright", 760, NULL }, - { "Egrave", 611, NULL }, - { "slash", 278, NULL }, - { "Edieresis", 611, NULL }, - { "otilde", 500, NULL }, - { "Idieresis", 333, NULL }, - { "parenleft", 333, NULL }, - { "one", 500, NULL }, - { "emacron", 444, NULL }, - { "Odieresis", 722, NULL }, - { "ucircumflex", 500, NULL }, - { "bracketleft", 333, NULL }, - { "Ugrave", 722, NULL }, - { "quoteright", 333, NULL }, - { "Udieresis", 722, NULL }, - { "perthousand", 1000, NULL }, - { "Ydieresis", 722, NULL }, - { "umacron", 500, NULL }, - { "abreve", 444, NULL }, - { "Eacute", 611, NULL }, - { "adieresis", 444, NULL }, - { "egrave", 444, NULL }, - { "edieresis", 444, NULL }, - { "idieresis", 278, NULL }, - { "Eth", 722, NULL }, - { "ae", 667, NULL }, - { "asterisk", 500, NULL }, - { "odieresis", 500, NULL }, - { "Uacute", 722, NULL }, - { "ugrave", 500, NULL }, - { "nine", 500, NULL }, - { "five", 500, NULL }, - { "udieresis", 500, NULL }, - { "Zcaron", 611, NULL }, - { "Scommaaccent", 556, NULL }, - { "threequarters", 750, NULL }, - { "guillemotright", 500, NULL }, - { "Ccedilla", 667, NULL }, - { "ydieresis", 500, NULL }, - { "tilde", 333, NULL }, - { "at", 921, NULL }, - { "eacute", 444, NULL }, - { "underscore", 500, NULL }, - { "Euro", 500, NULL }, - { "Dcroat", 722, NULL }, - { "multiply", 564, NULL }, - { "zero", 500, NULL }, - { "eth", 500, NULL }, - { "Scedilla", 556, NULL }, - { "Ograve", 722, NULL }, - { "Racute", 667, NULL }, - { "partialdiff", 476, NULL }, - { "uacute", 500, NULL }, - { "braceleft", 480, NULL }, - { "Thorn", 556, NULL }, - { "zcaron", 444, NULL }, - { "scommaaccent", 389, NULL }, - { "ccedilla", 444, NULL }, - { "Dcaron", 722, NULL }, - { "dcroat", 500, NULL }, - { "Ocircumflex", 722, NULL }, - { "Oacute", 722, NULL }, - { "scedilla", 389, NULL }, - { "ogonek", 333, NULL }, - { "ograve", 500, NULL }, - { "racute", 333, NULL }, - { "Tcaron", 611, NULL }, - { "Eogonek", 611, NULL }, - { "thorn", 500, NULL }, - { "degree", 400, NULL }, - { "registered", 760, NULL }, - { "radical", 453, NULL }, - { "Aring", 722, NULL }, - { "percent", 833, NULL }, - { "six", 500, NULL }, - { "paragraph", 453, NULL }, - { "dcaron", 588, NULL }, - { "Uogonek", 722, NULL }, - { "two", 500, NULL }, - { "summation", 600, NULL }, - { "Igrave", 333, NULL }, - { "Lacute", 611, NULL }, - { "ocircumflex", 500, NULL }, - { "oacute", 500, NULL }, - { "Uring", 722, NULL }, - { "Lcommaaccent", 611, NULL }, - { "tcaron", 326, NULL }, - { "eogonek", 444, NULL }, - { "Delta", 612, NULL }, - { "Ohungarumlaut", 722, NULL }, - { "asciicircum", 469, NULL }, - { "aring", 444, NULL }, - { "grave", 333, NULL }, - { "uogonek", 500, NULL }, - { "bracketright", 333, NULL }, - { "Iacute", 333, NULL }, - { "ampersand", 778, NULL }, - { "igrave", 278, NULL }, - { "lacute", 278, NULL }, - { "Ncaron", 722, NULL }, - { "plus", 564, NULL }, - { "uring", 500, NULL }, - { "quotesinglbase", 333, NULL }, - { "lcommaaccent", 278, NULL }, - { "Yacute", 722, NULL }, - { "ohungarumlaut", 500, NULL }, - { "threesuperior", 300, NULL }, - { "acute", 333, NULL }, - { "section", 500, NULL }, - { "dieresis", 333, NULL }, - { "iacute", 278, NULL }, - { "quotedblbase", 444, NULL }, - { "ncaron", 500, NULL }, - { "florin", 500, NULL }, - { "yacute", 500, NULL }, - { "Rcommaaccent", 667, NULL }, - { "fi", 556, NULL }, - { "fl", 556, NULL }, - { "Acircumflex", 722, NULL }, - { "Cacute", 667, NULL }, - { "Icircumflex", 333, NULL }, - { "guillemotleft", 500, NULL }, - { "germandbls", 500, NULL }, - { "Amacron", 722, NULL }, - { "seven", 500, NULL }, - { "Sacute", 556, NULL }, - { "ordmasculine", 310, NULL }, - { "dotlessi", 278, NULL }, - { "sterling", 500, NULL }, - { "notequal", 549, NULL }, - { "Imacron", 333, NULL }, - { "rcommaaccent", 333, NULL }, - { "Zdotaccent", 611, NULL }, - { "acircumflex", 444, NULL }, - { "cacute", 444, NULL }, - { "Ecaron", 611, NULL }, - { "icircumflex", 278, NULL }, - { "braceright", 480, NULL }, - { "quotedblright", 444, NULL }, - { "amacron", 444, NULL }, - { "sacute", 389, NULL }, - { "imacron", 278, NULL }, - { "cent", 500, NULL }, - { "currency", 500, NULL }, - { "logicalnot", 564, NULL }, - { "zdotaccent", 444, NULL }, - { "Atilde", 722, NULL }, - { "breve", 333, NULL }, - { "bar", 200, NULL }, - { "fraction", 167, NULL }, - { "less", 564, NULL }, - { "ecaron", 444, NULL }, - { "guilsinglleft", 333, NULL }, - { "exclam", 333, NULL }, - { "period", 250, NULL }, - { "Rcaron", 667, NULL }, - { "Kcommaaccent", 722, NULL }, - { "greater", 564, NULL }, - { "atilde", 444, NULL }, - { "brokenbar", 200, NULL }, - { "quoteleft", 333, NULL }, - { "Edotaccent", 611, NULL }, - { "onesuperior", 300, NULL } - }; - - static BuiltinFontWidth c_arrZapfDingbatsWidthsTable[] = - { - { "a81", 438, NULL }, - { "a82", 138, NULL }, - { "a83", 277, NULL }, - { "a84", 415, NULL }, - { "a85", 509, NULL }, - { "a86", 410, NULL }, - { "a87", 234, NULL }, - { "a88", 234, NULL }, - { "a89", 390, NULL }, - { "a140", 788, NULL }, - { "a141", 788, NULL }, - { "a142", 788, NULL }, - { "a143", 788, NULL }, - { "a144", 788, NULL }, - { "a145", 788, NULL }, - { "a146", 788, NULL }, - { "a147", 788, NULL }, - { "a148", 788, NULL }, - { "a149", 788, NULL }, - { "a90", 390, NULL }, - { "a91", 276, NULL }, - { "a92", 276, NULL }, - { "space", 278, NULL }, - { "a93", 317, NULL }, - { "a94", 317, NULL }, - { "a95", 334, NULL }, - { "a96", 334, NULL }, - { "a97", 392, NULL }, - { "a98", 392, NULL }, - { "a99", 668, NULL }, - { "a150", 788, NULL }, - { "a151", 788, NULL }, - { "a152", 788, NULL }, - { "a153", 788, NULL }, - { "a154", 788, NULL }, - { "a155", 788, NULL }, - { "a156", 788, NULL }, - { "a157", 788, NULL }, - { "a158", 788, NULL }, - { "a159", 788, NULL }, - { "a160", 894, NULL }, - { "a161", 838, NULL }, - { "a162", 924, NULL }, - { "a163", 1016, NULL }, - { "a164", 458, NULL }, - { "a165", 924, NULL }, - { "a166", 918, NULL }, - { "a167", 927, NULL }, - { "a168", 928, NULL }, - { "a169", 928, NULL }, - { "a170", 834, NULL }, - { "a171", 873, NULL }, - { "a172", 828, NULL }, - { "a173", 924, NULL }, - { "a174", 917, NULL }, - { "a175", 930, NULL }, - { "a176", 931, NULL }, - { "a177", 463, NULL }, - { "a178", 883, NULL }, - { "a179", 836, NULL }, - { "a180", 867, NULL }, - { "a181", 696, NULL }, - { "a182", 874, NULL }, - { "a183", 760, NULL }, - { "a184", 946, NULL }, - { "a185", 865, NULL }, - { "a186", 967, NULL }, - { "a187", 831, NULL }, - { "a188", 873, NULL }, - { "a189", 927, NULL }, - { "a1", 974, NULL }, - { "a2", 961, NULL }, - { "a3", 980, NULL }, - { "a4", 719, NULL }, - { "a5", 789, NULL }, - { "a6", 494, NULL }, - { "a7", 552, NULL }, - { "a8", 537, NULL }, - { "a9", 577, NULL }, - { "a190", 970, NULL }, - { "a191", 918, NULL }, - { "a192", 748, NULL }, - { "a193", 836, NULL }, - { "a194", 771, NULL }, - { "a195", 888, NULL }, - { "a196", 748, NULL }, - { "a197", 771, NULL }, - { "a198", 888, NULL }, - { "a199", 867, NULL }, - { "a10", 692, NULL }, - { "a11", 960, NULL }, - { "a12", 939, NULL }, - { "a13", 549, NULL }, - { "a14", 855, NULL }, - { "a15", 911, NULL }, - { "a16", 933, NULL }, - { "a17", 945, NULL }, - { "a18", 974, NULL }, - { "a19", 755, NULL }, - { "a20", 846, NULL }, - { "a21", 762, NULL }, - { "a22", 761, NULL }, - { "a23", 571, NULL }, - { "a24", 677, NULL }, - { "a25", 763, NULL }, - { "a26", 760, NULL }, - { "a27", 759, NULL }, - { "a28", 754, NULL }, - { "a29", 786, NULL }, - { "a30", 788, NULL }, - { "a31", 788, NULL }, - { "a32", 790, NULL }, - { "a33", 793, NULL }, - { "a34", 794, NULL }, - { "a35", 816, NULL }, - { "a36", 823, NULL }, - { "a37", 789, NULL }, - { "a38", 841, NULL }, - { "a39", 823, NULL }, - { "a40", 833, NULL }, - { "a41", 816, NULL }, - { "a42", 831, NULL }, - { "a43", 923, NULL }, - { "a44", 744, NULL }, - { "a45", 723, NULL }, - { "a46", 749, NULL }, - { "a47", 790, NULL }, - { "a48", 792, NULL }, - { "a49", 695, NULL }, - { "a100", 668, NULL }, - { "a101", 732, NULL }, - { "a102", 544, NULL }, - { "a103", 544, NULL }, - { "a104", 910, NULL }, - { "a105", 911, NULL }, - { "a106", 667, NULL }, - { "a107", 760, NULL }, - { "a108", 760, NULL }, - { "a109", 626, NULL }, - { "a50", 776, NULL }, - { "a51", 768, NULL }, - { "a52", 792, NULL }, - { "a53", 759, NULL }, - { "a54", 707, NULL }, - { "a55", 708, NULL }, - { "a56", 682, NULL }, - { "a57", 701, NULL }, - { "a58", 826, NULL }, - { "a59", 815, NULL }, - { "a110", 694, NULL }, - { "a111", 595, NULL }, - { "a112", 776, NULL }, - { "a117", 690, NULL }, - { "a118", 791, NULL }, - { "a119", 790, NULL }, - { "a60", 789, NULL }, - { "a61", 789, NULL }, - { "a62", 707, NULL }, - { "a63", 687, NULL }, - { "a64", 696, NULL }, - { "a65", 689, NULL }, - { "a66", 786, NULL }, - { "a67", 787, NULL }, - { "a68", 713, NULL }, - { "a69", 791, NULL }, - { "a200", 696, NULL }, - { "a201", 874, NULL }, - { "a120", 788, NULL }, - { "a121", 788, NULL }, - { "a202", 974, NULL }, - { "a122", 788, NULL }, - { "a203", 762, NULL }, - { "a123", 788, NULL }, - { "a204", 759, NULL }, - { "a124", 788, NULL }, - { "a205", 509, NULL }, - { "a125", 788, NULL }, - { "a206", 410, NULL }, - { "a126", 788, NULL }, - { "a127", 788, NULL }, - { "a128", 788, NULL }, - { "a129", 788, NULL }, - { "a70", 785, NULL }, - { "a71", 791, NULL }, - { "a72", 873, NULL }, - { "a73", 761, NULL }, - { "a74", 762, NULL }, - { "a75", 759, NULL }, - { "a76", 892, NULL }, - { "a77", 892, NULL }, - { "a78", 788, NULL }, - { "a79", 784, NULL }, - { "a130", 788, NULL }, - { "a131", 788, NULL }, - { "a132", 788, NULL }, - { "a133", 788, NULL }, - { "a134", 788, NULL }, - { "a135", 788, NULL }, - { "a136", 788, NULL }, - { "a137", 788, NULL }, - { "a138", 788, NULL }, - { "a139", 788, NULL } - }; - - static BuiltinFont c_arrBuiltinFonts[] = - { - { "Courier", c_arrStandardEncoding, 629, -157, { -23, -250, 715, 805}, c_arrCourierWidthsTable, 315 }, - { "Courier-Bold", c_arrStandardEncoding, 629, -157, {-113, -250, 749, 801}, c_arrCourierBoldWidthsTable, 315 }, - { "Courier-BoldOblique", c_arrStandardEncoding, 629, -157, { -57, -250, 869, 801}, c_arrCourierBoldObliqueWidthsTable, 315 }, - { "Courier-Oblique", c_arrStandardEncoding, 629, -157, { -27, -250, 849, 805}, c_arrCourierObliqueWidthsTable, 315 }, - { "Helvetica", c_arrStandardEncoding, 718, -207, {-166, -225, 1000, 931}, c_arrHelveticaWidthsTable, 315 }, - { "Helvetica-Bold", c_arrStandardEncoding, 718, -207, {-170, -228, 1003, 962}, c_arrHelveticaBoldWidthsTable, 316 }, - { "Helvetica-BoldOblique", c_arrStandardEncoding, 718, -207, {-174, -228, 1114, 962}, c_arrHelveticaBoldObliqueWidthsTable, 315 }, - { "Helvetica-Oblique", c_arrStandardEncoding, 718, -207, {-170, -225, 1116, 931}, c_arrHelveticaObliqueWidthsTable, 315 }, - { "Symbol", c_arrSymbolEncoding, 1010, -293, {-180, -293, 1090, 1010}, c_arrSymbolWidthsTable, 190 }, - { "Times-Bold", c_arrStandardEncoding, 683, -217, {-168, -218, 1000, 935}, c_arrTimesBoldWidthsTable, 315 }, - { "Times-BoldItalic", c_arrStandardEncoding, 683, -217, {-200, -218, 996, 921}, c_arrTimesBoldItalicWidthsTable, 315 }, - { "Times-Italic", c_arrStandardEncoding, 683, -217, {-169, -217, 1010, 883}, c_arrTimesItalicWidthsTable, 315 }, - { "Times-Roman", c_arrStandardEncoding, 683, -217, {-168, -218, 1000, 898}, c_arrTimesRomanWidthsTable, 315 }, - { "ZapfDingbats", c_arrZapfDingbatsEncoding, 820, -143, { -1, -143, 981, 820}, c_arrZapfDingbatsWidthsTable, 202 } - }; - - static BuiltinFont *c_arrBuiltinFontSubset[] = - { - &c_arrBuiltinFonts[0], - &c_arrBuiltinFonts[3], - &c_arrBuiltinFonts[1], - &c_arrBuiltinFonts[2], - &c_arrBuiltinFonts[4], - &c_arrBuiltinFonts[7], - &c_arrBuiltinFonts[5], - &c_arrBuiltinFonts[6], - &c_arrBuiltinFonts[12], - &c_arrBuiltinFonts[11], - &c_arrBuiltinFonts[9], - &c_arrBuiltinFonts[10] - }; -} - -#endif // _PDF_READER_BUILTIN_FONT_TABLES_H diff --git a/PdfReader/old/CCITT-Tables.h b/PdfReader/old/CCITT-Tables.h deleted file mode 100644 index f564fa61e0..0000000000 --- a/PdfReader/old/CCITT-Tables.h +++ /dev/null @@ -1,539 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CCIT_TABLES_H -#define _PDF_READER_CCIT_TABLES_H - -namespace PdfReader -{ - struct CCITTCode - { - short nBitsCount; - short nCode; - }; - - #define ccittEOL -2 - - //------------------------------------------------------------------------ - // 2D коды - //------------------------------------------------------------------------ - - #define Pass_2D 0 - #define Horiz_2D 1 - #define Vert0_2D 2 - #define VertR1_2D 3 - #define VertL1_2D 4 - #define VertR2_2D 5 - #define VertL2_2D 6 - #define VertR3_2D 7 - #define VertL3_2D 8 - - // коды 1-7 бит - static CCITTCode c_arrTable2D[128] = - { - { -1, -1 }, { -1, -1 }, // 000000x - { 7, VertL3_2D }, // 0000010 - { 7, VertR3_2D }, // 0000011 - { 6, VertL2_2D }, { 6, VertL2_2D }, // 000010x - { 6, VertR2_2D }, { 6, VertR2_2D }, // 000011x - - { 4, Pass_2D }, { 4, Pass_2D }, // 0001xxx - { 4, Pass_2D }, { 4, Pass_2D }, - { 4, Pass_2D }, { 4, Pass_2D }, - { 4, Pass_2D }, { 4, Pass_2D }, - - { 3, Horiz_2D }, { 3, Horiz_2D }, // 001xxxx - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - { 3, Horiz_2D }, { 3, Horiz_2D }, - - { 3, VertL1_2D }, { 3, VertL1_2D }, // 010xxxx - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - { 3, VertL1_2D }, { 3, VertL1_2D }, - - { 3, VertR1_2D }, { 3, VertR1_2D }, // 011xxxx - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - { 3, VertR1_2D }, { 3, VertR1_2D }, - - { 1, Vert0_2D }, { 1, Vert0_2D }, // 1xxxxxx - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D }, - { 1, Vert0_2D }, { 1, Vert0_2D } - }; - - //------------------------------------------------------------------------ - // White run lengths - //------------------------------------------------------------------------ - - // коды 11-12 бит (верхние 7 бит установлены в 0) - static CCITTCode c_arrWhiteTable1[32] = - { - { -1, -1 }, // 00000 - { 12, ccittEOL }, // 00001 - { -1, -1 }, { -1, -1 }, // 0001x - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 001xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 010xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 011xx - { 11, 1792 }, { 11, 1792 }, // 1000x - { 12, 1984 }, // 10010 - { 12, 2048 }, // 10011 - { 12, 2112 }, // 10100 - { 12, 2176 }, // 10101 - { 12, 2240 }, // 10110 - { 12, 2304 }, // 10111 - { 11, 1856 }, { 11, 1856 }, // 1100x - { 11, 1920 }, { 11, 1920 }, // 1101x - { 12, 2368 }, // 11100 - { 12, 2432 }, // 11101 - { 12, 2496 }, // 11110 - { 12, 2560 } // 11111 - }; - - // коды 1-9 бит - static CCITTCode c_arrWhiteTable2[512] = - { - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 0000000xx - { 8, 29 }, { 8, 29 }, // 00000010x - { 8, 30 }, { 8, 30 }, // 00000011x - { 8, 45 }, { 8, 45 }, // 00000100x - { 8, 46 }, { 8, 46 }, // 00000101x - { 7, 22 }, { 7, 22 }, { 7, 22 }, { 7, 22 }, // 0000011xx - { 7, 23 }, { 7, 23 }, { 7, 23 }, { 7, 23 }, // 0000100xx - { 8, 47 }, { 8, 47 }, // 00001010x - { 8, 48 }, { 8, 48 }, // 00001011x - - { 6, 13 }, { 6, 13 }, { 6, 13 }, { 6, 13 }, // 000011xxx - { 6, 13 }, { 6, 13 }, { 6, 13 }, { 6, 13 }, - - { 7, 20 }, { 7, 20 }, { 7, 20 }, { 7, 20 }, // 0001000xx - { 8, 33 }, { 8, 33 }, // 00010010x - { 8, 34 }, { 8, 34 }, // 00010011x - { 8, 35 }, { 8, 35 }, // 00010100x - { 8, 36 }, { 8, 36 }, // 00010101x - { 8, 37 }, { 8, 37 }, // 00010110x - { 8, 38 }, { 8, 38 }, // 00010111x - { 7, 19 }, { 7, 19 }, { 7, 19 }, { 7, 19 }, // 0001100xx - { 8, 31 }, { 8, 31 }, // 00011010x - { 8, 32 }, { 8, 32 }, // 00011011x - - { 6, 1 }, { 6, 1 }, { 6, 1 }, { 6, 1 }, // 000111xxx - { 6, 1 }, { 6, 1 }, { 6, 1 }, { 6, 1 }, - - { 6, 12 }, { 6, 12 }, { 6, 12 }, { 6, 12 }, // 001000xxx - { 6, 12 }, { 6, 12 }, { 6, 12 }, { 6, 12 }, - - { 8, 53 }, { 8, 53 }, // 00100100x - { 8, 54 }, { 8, 54 }, // 00100101x - { 7, 26 }, { 7, 26 }, { 7, 26 }, { 7, 26 }, // 0010011xx - { 8, 39 }, { 8, 39 }, // 00101000x - { 8, 40 }, { 8, 40 }, // 00101001x - - { 8, 41 }, { 8, 41 }, // 00101010x - { 8, 42 }, { 8, 42 }, // 00101011x - { 8, 43 }, { 8, 43 }, // 00101100x - { 8, 44 }, { 8, 44 }, // 00101101x - { 7, 21 }, { 7, 21 }, { 7, 21 }, { 7, 21 }, // 0010111xx - { 7, 28 }, { 7, 28 }, { 7, 28 }, { 7, 28 }, // 0011000xx - { 8, 61 }, { 8, 61 }, // 00110010x - { 8, 62 }, { 8, 62 }, // 00110011x - { 8, 63 }, { 8, 63 }, // 00110100x - { 8, 0 }, { 8, 0 }, // 00110101x - { 8, 320 }, { 8, 320 }, // 00110110x - { 8, 384 }, { 8, 384 }, // 00110111x - - { 5, 10 }, { 5, 10 }, { 5, 10 }, { 5, 10 }, // 00111xxxx - { 5, 10 }, { 5, 10 }, { 5, 10 }, { 5, 10 }, - { 5, 10 }, { 5, 10 }, { 5, 10 }, { 5, 10 }, - { 5, 10 }, { 5, 10 }, { 5, 10 }, { 5, 10 }, - - { 5, 11 }, { 5, 11 }, { 5, 11 }, { 5, 11 }, // 01000xxxx - { 5, 11 }, { 5, 11 }, { 5, 11 }, { 5, 11 }, - { 5, 11 }, { 5, 11 }, { 5, 11 }, { 5, 11 }, - { 5, 11 }, { 5, 11 }, { 5, 11 }, { 5, 11 }, - - { 7, 27 }, { 7, 27 }, { 7, 27 }, { 7, 27 }, // 0100100xx - { 8, 59 }, { 8, 59 }, // 01001010x - { 8, 60 }, { 8, 60 }, // 01001011x - { 9, 1472 }, // 010011000 - { 9, 1536 }, // 010011001 - { 9, 1600 }, // 010011010 - { 9, 1728 }, // 010011011 - { 7, 18 }, { 7, 18 }, { 7, 18 }, { 7, 18 }, // 0100111xx - { 7, 24 }, { 7, 24 }, { 7, 24 }, { 7, 24 }, // 0101000xx - { 8, 49 }, { 8, 49 }, // 01010010x - { 8, 50 }, { 8, 50 }, // 01010011x - { 8, 51 }, { 8, 51 }, // 01010100x - { 8, 52 }, { 8, 52 }, // 01010101x - { 7, 25 }, { 7, 25 }, { 7, 25 }, { 7, 25 }, // 0101011xx - { 8, 55 }, { 8, 55 }, // 01011000x - { 8, 56 }, { 8, 56 }, // 01011001x - { 8, 57 }, { 8, 57 }, // 01011010x - { 8, 58 }, { 8, 58 }, // 01011011x - - { 6, 192 }, { 6, 192 }, { 6, 192 }, { 6, 192 }, // 010111xxx - { 6, 192 }, { 6, 192 }, { 6, 192 }, { 6, 192 }, - - { 6, 1664 }, { 6, 1664 }, { 6, 1664 }, { 6, 1664 }, // 011000xxx - { 6, 1664 }, { 6, 1664 }, { 6, 1664 }, { 6, 1664 }, - - { 8, 448 }, { 8, 448 }, // 01100100x - { 8, 512 }, { 8, 512 }, // 01100101x - { 9, 704 }, // 011001100 - { 9, 768 }, // 011001101 - { 8, 640 }, { 8, 640 }, // 01100111x - { 8, 576 }, { 8, 576 }, // 01101000x - { 9, 832 }, // 011010010 - { 9, 896 }, // 011010011 - { 9, 960 }, // 011010100 - { 9, 1024 }, // 011010101 - { 9, 1088 }, // 011010110 - { 9, 1152 }, // 011010111 - { 9, 1216 }, // 011011000 - { 9, 1280 }, // 011011001 - { 9, 1344 }, // 011011010 - { 9, 1408 }, // 011011011 - { 7, 256 }, { 7, 256 }, { 7, 256 }, { 7, 256 }, // 0110111xx - - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, // 0111xxxxx - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - { 4, 2 }, { 4, 2 }, { 4, 2 }, { 4, 2 }, - - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, // 1000xxxxx - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - { 4, 3 }, { 4, 3 }, { 4, 3 }, { 4, 3 }, - - { 5, 128 }, { 5, 128 }, { 5, 128 }, { 5, 128 }, // 10010xxxx - { 5, 128 }, { 5, 128 }, { 5, 128 }, { 5, 128 }, - { 5, 128 }, { 5, 128 }, { 5, 128 }, { 5, 128 }, - { 5, 128 }, { 5, 128 }, { 5, 128 }, { 5, 128 }, - - { 5, 8 }, { 5, 8 }, { 5, 8 }, { 5, 8 }, // 10011xxxx - { 5, 8 }, { 5, 8 }, { 5, 8 }, { 5, 8 }, - { 5, 8 }, { 5, 8 }, { 5, 8 }, { 5, 8 }, - { 5, 8 }, { 5, 8 }, { 5, 8 }, { 5, 8 }, - - { 5, 9 }, { 5, 9 }, { 5, 9 }, { 5, 9 }, // 10100xxxx - { 5, 9 }, { 5, 9 }, { 5, 9 }, { 5, 9 }, - { 5, 9 }, { 5, 9 }, { 5, 9 }, { 5, 9 }, - { 5, 9 }, { 5, 9 }, { 5, 9 }, { 5, 9 }, - - { 6, 16 }, { 6, 16 }, { 6, 16 }, { 6, 16 }, // 101010xxx - { 6, 16 }, { 6, 16 }, { 6, 16 }, { 6, 16 }, - - { 6, 17 }, { 6, 17 }, { 6, 17 }, { 6, 17 }, // 101011xxx - { 6, 17 }, { 6, 17 }, { 6, 17 }, { 6, 17 }, - - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, // 1011xxxxx - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - { 4, 4 }, { 4, 4 }, { 4, 4 }, { 4, 4 }, - - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, // 1100xxxxx - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, - - { 6, 14 }, { 6, 14 }, { 6, 14 }, { 6, 14 }, // 110100xxx - { 6, 14 }, { 6, 14 }, { 6, 14 }, { 6, 14 }, - - { 6, 15 }, { 6, 15 }, { 6, 15 }, { 6, 15 }, // 110101xxx - { 6, 15 }, { 6, 15 }, { 6, 15 }, { 6, 15 }, - - { 5, 64 }, { 5, 64 }, { 5, 64 }, { 5, 64 }, // 11011xxxx - { 5, 64 }, { 5, 64 }, { 5, 64 }, { 5, 64 }, - { 5, 64 }, { 5, 64 }, { 5, 64 }, { 5, 64 }, - { 5, 64 }, { 5, 64 }, { 5, 64 }, { 5, 64 }, - - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, // 1110xxxxx - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, - - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, // 1111xxxxx - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 }, - { 4, 7 }, { 4, 7 }, { 4, 7 }, { 4, 7 } - }; - - //------------------------------------------------------------------------ - // Black run lengths - //------------------------------------------------------------------------ - - // коды 10-13 бит (верхние 6 бит установлены в 0) - static CCITTCode c_arrBlackTable1[128] = - { - { -1, -1 }, { -1, -1 }, // 000000000000x - { 12, ccittEOL }, { 12, ccittEOL }, // 000000000001x - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000001xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000010xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000011xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000100xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000101xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000110xx - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 00000000111xx - { 11, 1792 }, { 11, 1792 }, { 11, 1792 }, { 11, 1792 }, // 00000001000xx - { 12, 1984 }, { 12, 1984 }, // 000000010010x - { 12, 2048 }, { 12, 2048 }, // 000000010011x - { 12, 2112 }, { 12, 2112 }, // 000000010100x - { 12, 2176 }, { 12, 2176 }, // 000000010101x - { 12, 2240 }, { 12, 2240 }, // 000000010110x - { 12, 2304 }, { 12, 2304 }, // 000000010111x - { 11, 1856 }, { 11, 1856 }, { 11, 1856 }, { 11, 1856 }, // 00000001100xx - { 11, 1920 }, { 11, 1920 }, { 11, 1920 }, { 11, 1920 }, // 00000001101xx - { 12, 2368 }, { 12, 2368 }, // 000000011100x - { 12, 2432 }, { 12, 2432 }, // 000000011101x - { 12, 2496 }, { 12, 2496 }, // 000000011110x - { 12, 2560 }, { 12, 2560 }, // 000000011111x - - { 10, 18 }, { 10, 18 }, { 10, 18 }, { 10, 18 }, // 0000001000xxx - { 10, 18 }, { 10, 18 }, { 10, 18 }, { 10, 18 }, - - { 12, 52 }, { 12, 52 }, // 000000100100x - { 13, 640 }, // 0000001001010 - { 13, 704 }, // 0000001001011 - { 13, 768 }, // 0000001001100 - { 13, 832 }, // 0000001001101 - { 12, 55 }, { 12, 55 }, // 000000100111x - { 12, 56 }, { 12, 56 }, // 000000101000x - { 13, 1280 }, // 0000001010010 - { 13, 1344 }, // 0000001010011 - { 13, 1408 }, // 0000001010100 - { 13, 1472 }, // 0000001010101 - { 12, 59 }, { 12, 59 }, // 000000101011x - { 12, 60 }, { 12, 60 }, // 000000101100x - { 13, 1536 }, // 0000001011010 - { 13, 1600 }, // 0000001011011 - { 11, 24 }, { 11, 24 }, { 11, 24 }, { 11, 24 }, // 00000010111xx - { 11, 25 }, { 11, 25 }, { 11, 25 }, { 11, 25 }, // 00000011000xx - { 13, 1664 }, // 0000001100100 - { 13, 1728 }, // 0000001100101 - { 12, 320 }, { 12, 320 }, // 000000110011x - { 12, 384 }, { 12, 384 }, // 000000110100x - { 12, 448 }, { 12, 448 }, // 000000110101x - { 13, 512 }, // 0000001101100 - { 13, 576 }, // 0000001101101 - { 12, 53 }, { 12, 53 }, // 000000110111x - { 12, 54 }, { 12, 54 }, // 000000111000x - { 13, 896 }, // 0000001110010 - { 13, 960 }, // 0000001110011 - { 13, 1024 }, // 0000001110100 - { 13, 1088 }, // 0000001110101 - { 13, 1152 }, // 0000001110110 - { 13, 1216 }, // 0000001110111 - { 10, 64 }, { 10, 64 }, { 10, 64 }, { 10, 64 }, // 0000001111xxx - { 10, 64 }, { 10, 64 }, { 10, 64 }, { 10, 64 } - }; - - // коды 7-12 быит (верхние 4 бита установлены в 0) - static CCITTCode c_arrBlackTable2[192] = - { - { 8, 13 }, { 8, 13 }, { 8, 13 }, { 8, 13 }, // 00000100xxxx - { 8, 13 }, { 8, 13 }, { 8, 13 }, { 8, 13 }, - { 8, 13 }, { 8, 13 }, { 8, 13 }, { 8, 13 }, - { 8, 13 }, { 8, 13 }, { 8, 13 }, { 8, 13 }, - - { 11, 23 }, { 11, 23 }, // 00000101000x - { 12, 50 }, // 000001010010 - { 12, 51 }, // 000001010011 - { 12, 44 }, // 000001010100 - { 12, 45 }, // 000001010101 - { 12, 46 }, // 000001010110 - { 12, 47 }, // 000001010111 - { 12, 57 }, // 000001011000 - { 12, 58 }, // 000001011001 - { 12, 61 }, // 000001011010 - { 12, 256 }, // 000001011011 - { 10, 16 }, { 10, 16 }, { 10, 16 }, { 10, 16 },// 0000010111xx - { 10, 17 }, { 10, 17 }, { 10, 17 }, { 10, 17 },// 0000011000xx - { 12, 48 }, // 000001100100 - { 12, 49 }, // 000001100101 - { 12, 62 }, // 000001100110 - { 12, 63 }, // 000001100111 - { 12, 30 }, // 000001101000 - { 12, 31 }, // 000001101001 - { 12, 32 }, // 000001101010 - { 12, 33 }, // 000001101011 - { 12, 40 }, // 000001101100 - { 12, 41 }, // 000001101101 - { 11, 22 }, { 11, 22 }, // 00000110111x - - { 8, 14 }, { 8, 14 }, { 8, 14 }, { 8, 14 }, // 00000111xxxx - { 8, 14 }, { 8, 14 }, { 8, 14 }, { 8, 14 }, - { 8, 14 }, { 8, 14 }, { 8, 14 }, { 8, 14 }, - { 8, 14 }, { 8, 14 }, { 8, 14 }, { 8, 14 }, - - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, // 0000100xxxxx - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - { 7, 10 }, { 7, 10 }, { 7, 10 }, { 7, 10 }, - - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, // 0000101xxxxx - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - { 7, 11 }, { 7, 11 }, { 7, 11 }, { 7, 11 }, - - { 9, 15 }, { 9, 15 }, { 9, 15 }, { 9, 15 }, // 000011000xxx - { 9, 15 }, { 9, 15 }, { 9, 15 }, { 9, 15 }, - - { 12, 128 }, // 000011001000 - { 12, 192 }, // 000011001001 - { 12, 26 }, // 000011001010 - { 12, 27 }, // 000011001011 - { 12, 28 }, // 000011001100 - { 12, 29 }, // 000011001101 - { 11, 19 }, { 11, 19 }, // 00001100111x - { 11, 20 }, { 11, 20 }, // 00001101000x - { 12, 34 }, // 000011010010 - { 12, 35 }, // 000011010011 - { 12, 36 }, // 000011010100 - { 12, 37 }, // 000011010101 - { 12, 38 }, // 000011010110 - { 12, 39 }, // 000011010111 - { 11, 21 }, { 11, 21 }, // 00001101100x - { 12, 42 }, // 000011011010 - { 12, 43 }, // 000011011011 - { 10, 0 }, { 10, 0 }, { 10, 0 }, { 10, 0 }, // 0000110111xx - - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, // 0000111xxxxx - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 }, - { 7, 12 }, { 7, 12 }, { 7, 12 }, { 7, 12 } - }; - - // коды 2-6 бит - static CCITTCode c_arrBlackTable3[64] = - { - { -1, -1 }, { -1, -1 }, { -1, -1 }, { -1, -1 }, // 0000xx - { 6, 9 }, // 000100 - { 6, 8 }, // 000101 - { 5, 7 }, { 5, 7 }, // 00011x - { 4, 6 }, { 4, 6 }, { 4, 6 }, { 4, 6 }, // 0010xx - { 4, 5 }, { 4, 5 }, { 4, 5 }, { 4, 5 }, // 0011xx - - { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, // 010xxx - { 3, 1 }, { 3, 1 }, { 3, 1 }, { 3, 1 }, - - { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, // 011xxx - { 3, 4 }, { 3, 4 }, { 3, 4 }, { 3, 4 }, - - { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, // 10xxxx - { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, - { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, - { 2, 3 }, { 2, 3 }, { 2, 3 }, { 2, 3 }, - - { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, // 11xxxx - { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, - { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 }, - { 2, 2 }, { 2, 2 }, { 2, 2 }, { 2, 2 } - }; -} - -#endif // _PDF_READER_CCIT_TABLES_H \ No newline at end of file diff --git a/PdfReader/old/CMap.cpp b/PdfReader/old/CMap.cpp deleted file mode 100644 index 359c03d900..0000000000 --- a/PdfReader/old/CMap.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "File.h" -#include "StringExt.h" -#include "GlobalParams.h" -#include "PSLexer.h" -#include "CMap.h" - -namespace PdfReader -{ - struct CMapVectorEntry - { - bool bIsVector; - CID nCID; - CMapVectorEntry *pVector; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - - static int GetCharFromFile(void *pFile) - { - return fgetc((FILE *)pFile); - } - - //------------------------------------------------------------------------------------------------------------------------------- - - CMap *CMap::Parse(CMapCache *pCache, StringExt *seCollection, StringExt *seCMapName, GlobalParams *pGlobalParams, wchar_t *wsFilePath) - { - FILE *pFile = NULL; - char sToken1[256], sToken2[256], sToken3[256]; - int nLen1, nLen2, nLen3; - - if (NULL != wsFilePath) - { - pFile = NSFile::CFileBinary::OpenFileNative(wsFilePath, L"rb"); - if (!pFile) - return NULL; - } - else - { - if (pGlobalParams && !(pFile = pGlobalParams->FindCMapFile(seCollection, seCMapName))) - { - // Проверяем на Identity CMap. - if (!seCMapName->Compare("Identity") || !seCMapName->Compare("Identity-H")) - { - return new CMap(pGlobalParams, seCollection->Copy(), seCMapName->Copy(), 0); - } - if (!seCMapName->Compare("Identity-V")) - { - return new CMap(pGlobalParams, seCollection->Copy(), seCMapName->Copy(), 1); - } - - // TO DO: Error "Couldn't find CMap file for collection" - return NULL; - } - } - - CMap *pCMap = new CMap(pGlobalParams, seCollection->Copy(), seCMapName->Copy()); - - PSLexer *Lexer = new PSLexer(&GetCharFromFile, pFile); - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - - while (Lexer->GetToken(sToken2, sizeof(sToken2), &nLen2)) - { - if (!strcmp(sToken2, "usecmap")) - { - if (sToken1[0] == '/') - { - pCMap->UseCMap(pCache, sToken1 + 1); - } - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken1, "/WMode")) - { - pCMap->m_nWMode = atoi(sToken2); - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken2, "begincodespacerange")) - { - while (Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1)) - { - if (!strcmp(sToken1, "endcodespacerange")) - { - break; - } - if (!Lexer->GetToken(sToken2, sizeof(sToken2), &nLen2) || !strcmp(sToken2, "endcodespacerange")) - { - // TO DO: Error "Illegal entry in codespacerange block in CMap" - break; - } - if (sToken1[0] == '<' && sToken2[0] == '<' && nLen1 == nLen2 && nLen1 >= 4 && (nLen1 & 1) == 0) - { - unsigned int unStart = 0, unEnd = 0; - sToken1[nLen1 - 1] = sToken2[nLen1 - 1] = '\0'; - sscanf(sToken1 + 1, "%x", &unStart); - sscanf(sToken2 + 1, "%x", &unEnd); - nLen1 = (nLen1 - 2) / 2; - pCMap->AddCodeSpace(pCMap->m_pVector, unStart, unEnd, nLen1); - } - } - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken2, "begincidchar")) - { - while (Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1)) - { - if (!strcmp(sToken1, "endcidchar")) - { - break; - } - if (!Lexer->GetToken(sToken2, sizeof(sToken2), &nLen2) || !strcmp(sToken2, "endcidchar")) - { - // TO DO: Error "Illegal entry in cidchar block in CMap" - break; - } - if (!(sToken1[0] == '<' && sToken1[nLen1 - 1] == '>' && nLen1 >= 4 && (nLen1 & 1) == 0)) - { - // TO DO: Error "Illegal entry in cidchar block in CMap" - continue; - } - sToken1[nLen1 - 1] = '\0'; - unsigned int unCode = 0; - if (sscanf(sToken1 + 1, "%x", &unCode) != 1) - { - // TO DO: Error "Illegal entry in cidchar block in CMap" - continue; - } - nLen1 = (nLen1 - 2) / 2; - pCMap->AddCIDs(unCode, unCode, nLen1, (CID)atoi(sToken2)); - } - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken2, "begincidrange")) - { - while (Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1)) - { - if (!strcmp(sToken1, "endcidrange")) - { - break; - } - if (!Lexer->GetToken(sToken2, sizeof(sToken2), &nLen2) || !strcmp(sToken2, "endcidrange") || !Lexer->GetToken(sToken3, sizeof(sToken3), &nLen3) || !strcmp(sToken3, "endcidrange")) - { - // TO DO: Error "Illegal entry in cidrange block in CMap" - break; - } - if (sToken1[0] == '<' && sToken2[0] == '<' && nLen1 == nLen2 && nLen1 >= 4 && (nLen1 & 1) == 0) - { - unsigned int unStart = 0, unEnd = 0; - sToken1[nLen1 - 1] = sToken2[nLen1 - 1] = '\0'; - sscanf(sToken1 + 1, "%x", &unStart); - sscanf(sToken2 + 1, "%x", &unEnd); - nLen1 = (nLen1 - 2) / 2; - pCMap->AddCIDs(unStart, unEnd, nLen1, (CID)atoi(sToken3)); - } - } - Lexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else - { - strcpy(sToken1, sToken2); - } - } - delete Lexer; - - fclose(pFile); - - return pCMap; - } - - CMap::CMap(GlobalParams *pGlobalParams, StringExt *seCollection, StringExt *seCMapName) - { - m_pGlobalParams = pGlobalParams; - - m_seCollection = seCollection; - m_seCMapName = seCMapName; - m_nWMode = 0; - m_pVector = (CMapVectorEntry *)MemUtilsMallocArray(256, sizeof(CMapVectorEntry)); - - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - m_pVector[nIndex].bIsVector = false; - m_pVector[nIndex].nCID = 0; - } - m_nRef = 1; - - m_oCS.InitializeCriticalSection(); - } - - CMap::CMap(GlobalParams *pGlobalParams, StringExt *seCollection, StringExt *seCMapName, int nWMode) - { - m_pGlobalParams = pGlobalParams; - - m_seCollection = seCollection; - m_seCMapName = seCMapName; - m_nWMode = nWMode; - m_pVector = NULL; - m_nRef = 1; - - m_oCS.InitializeCriticalSection(); - } - - void CMap::UseCMap(CMapCache *pCache, char *sUseName) - { - StringExt *pUseNameStr = new StringExt(sUseName); - if (!pUseNameStr) - return; - CMap *pSubCMap = pCache->GetCMap(m_seCollection, pUseNameStr, m_pGlobalParams); - delete pUseNameStr; - if (!pSubCMap) - return; - CopyVector(m_pVector, pSubCMap->m_pVector); - pSubCMap->Release(); - } - - void CMap::CopyVector(CMapVectorEntry *pDest, CMapVectorEntry *pSrc) - { - for (int nSrcIndex = 0; nSrcIndex < 256; ++nSrcIndex) - { - if (pSrc[nSrcIndex].bIsVector) - { - if (!pDest[nSrcIndex].bIsVector) - { - pDest[nSrcIndex].bIsVector = true; - pDest[nSrcIndex].pVector = (CMapVectorEntry *)MemUtilsMallocArray(256, sizeof(CMapVectorEntry)); - for (int pDstIndex = 0; pDstIndex < 256; ++pDstIndex) - { - pDest[nSrcIndex].pVector[pDstIndex].bIsVector = false; - pDest[nSrcIndex].pVector[pDstIndex].nCID = 0; - } - } - CopyVector(pDest[nSrcIndex].pVector, pSrc[nSrcIndex].pVector); - } - else - { - if (pDest[nSrcIndex].bIsVector) - { - // TO DO: Error "Collision in usecmap" - } - else - { - pDest[nSrcIndex].nCID = pSrc[nSrcIndex].nCID; - } - } - } - } - - void CMap::AddCodeSpace(CMapVectorEntry *pVector, unsigned int unStart, unsigned int unEnd, unsigned int unBytesCount) - { - if (unBytesCount > 1) - { - int nStartByte = (unStart >> (8 * (unBytesCount - 1))) & 0xff; - int nEndByte = (unEnd >> (8 * (unBytesCount - 1))) & 0xff; - unsigned int unStart2 = unStart & ((1 << (8 * (unBytesCount - 1))) - 1); - unsigned int unEnd2 = unEnd & ((1 << (8 * (unBytesCount - 1))) - 1); - for (int nI = nStartByte; nI <= nEndByte; ++nI) - { - if (!pVector[nI].bIsVector) - { - pVector[nI].bIsVector = true; - pVector[nI].pVector = (CMapVectorEntry *)MemUtilsMallocArray(256, sizeof(CMapVectorEntry)); - for (int nJ = 0; nJ < 256; ++nJ) - { - pVector[nI].pVector[nJ].bIsVector = false; - pVector[nI].pVector[nJ].nCID = 0; - } - } - AddCodeSpace(pVector[nI].pVector, unStart2, unEnd2, unBytesCount - 1); - } - } - } - - void CMap::AddCIDs(unsigned int unStart, unsigned int unEnd, unsigned int unBytesCount, CID nFirstCID) - { - CMapVectorEntry *pVector = m_pVector; - for (unsigned int nIndex = unBytesCount - 1; nIndex >= 1; --nIndex) - { - int nByte = (unStart >> (8 * nIndex)) & 0xff; - if (!pVector[nByte].bIsVector) - { - // TO DO: Error "Invalid CID in CMap" - return; - } - pVector = pVector[nByte].pVector; - } - CID nCID = nFirstCID; - for (int nByte = (int)(unStart & 0xff); nByte <= (int)(unEnd & 0xff); ++nByte) - { - if (pVector[nByte].bIsVector) - { - // TO DO: Error "Invalid CID in CMap" - } - else - { - pVector[nByte].nCID = nCID; - } - ++nCID; - } - } - - CMap::~CMap() - { - if (m_seCollection) - delete m_seCollection; - - if (m_seCMapName) - delete m_seCMapName; - if (m_pVector) - { - FreeCMapVector(m_pVector); - } - - m_oCS.DeleteCriticalSection(); - } - - void CMap::FreeCMapVector(CMapVectorEntry *pVector) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (pVector[nIndex].bIsVector) - { - FreeCMapVector(pVector[nIndex].pVector); - } - } - MemUtilsFree(pVector); - } - - void CMap::AddRef() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - ++m_nRef; - - RELEASEOBJECT(pCS); - } - - void CMap::Release() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - - bool bDelete = (--m_nRef == 0); - - RELEASEOBJECT(pCS); - - if (bDelete) - { - delete this; - } - } - - bool CMap::Match(StringExt *seCollection, StringExt *seCMapName) - { - return !m_seCollection->Compare(seCollection) && !m_seCMapName->Compare(seCMapName); - } - - CID CMap::GetCID(char *sChar, int nLen, int *pnUsed) - { - CMapVectorEntry *pVector; - - if (!(pVector = m_pVector)) - { - // Identity CMap - *pnUsed = 2; - if (nLen < 2) - { - return 0; - } - return ((sChar[0] & 0xff) << 8) + (sChar[1] & 0xff); - } - int nUsedCount = 0; - while (1) - { - if (nUsedCount >= nLen) - { - *pnUsed = nUsedCount; - return 0; - } - int nIndex = sChar[nUsedCount++] & 0xff; - if (!pVector[nIndex].bIsVector) - { - *pnUsed = nUsedCount; - return pVector[nIndex].nCID; - } - pVector = pVector[nIndex].pVector; - } - } - - void CMap::ToXml(std::wstring wsFilePath) - { - CXmlWriter oWriter; - oWriter.WriteNodeBegin(L"PDF-CMap", true); - oWriter.WriteAttribute(L"collection", m_seCollection->GetWString()); - oWriter.WriteAttribute(L"name", m_seCMapName->GetWString()); - oWriter.WriteNodeEnd(L"PDF-CMap", true, false); - - if (!m_seCMapName->Compare("Identity") || !m_seCMapName->Compare("Identity-H") || !m_seCMapName->Compare("Identity-V")) - WriteVectorToXml(&oWriter, m_pVector); - - oWriter.WriteNodeEnd(L"PDF-CMap", false, true); - oWriter.SaveToFile(wsFilePath); - } - - void CMap::WriteVectorToXml(CXmlWriter *pWriter, CMapVectorEntry *pVector) - { - if (NULL == pVector) - return; - - for (int nIndex = 0; nIndex < 256; nIndex++) - { - if (0 != pVector[nIndex].nCID || false != pVector[nIndex].bIsVector) - { - if (pVector[nIndex].bIsVector) - { - pWriter->WriteNodeBegin(L"Vector", true); - pWriter->WriteAttribute(L"index", nIndex); - pWriter->WriteAttribute(L"isvector", 1); - pWriter->WriteAttribute(L"cid", (int)pVector[nIndex].nCID); - pWriter->WriteNodeEnd(L"Vector", true, false); - - WriteVectorToXml(pWriter, pVector[nIndex].pVector); - - pWriter->WriteNodeEnd(L"Vector", false, true); - } - else - { - pWriter->WriteNodeBegin(L"Vector", true); - pWriter->WriteAttribute(L"index", nIndex); - pWriter->WriteAttribute(L"isvector", 0); - pWriter->WriteAttribute(L"cid", (int)pVector[nIndex].nCID); - pWriter->WriteNodeEnd(L"Vector", true, true); - } - } - } - } - //------------------------------------------------------------------------------------------------------------------------------- - - CMapCache::CMapCache() - { - for (int nIndex = 0; nIndex < CMapCacheSize; ++nIndex) - { - m_ppCache[nIndex] = NULL; - } - } - - CMapCache::~CMapCache() - { - for (int nIndex = 0; nIndex < CMapCacheSize; ++nIndex) - { - if (m_ppCache[nIndex]) - { - m_ppCache[nIndex]->Release(); - } - } - } - - CMap *CMapCache::GetCMap(StringExt *seCollection, StringExt *seCMapName, GlobalParams* pGlobalParams, wchar_t *wsFilePath) - { - CMap *pCMap = NULL; - - if (m_ppCache[0] && m_ppCache[0]->Match(seCollection, seCMapName)) - { - m_ppCache[0]->AddRef(); - return m_ppCache[0]; - } - - for (int nIndex = 1; nIndex < CMapCacheSize; ++nIndex) - { - if (m_ppCache[nIndex] && m_ppCache[nIndex]->Match(seCollection, seCMapName)) - { - pCMap = m_ppCache[nIndex]; - for (int nJ = nIndex; nJ >= 1; --nJ) - { - m_ppCache[nJ] = m_ppCache[nJ - 1]; - } - m_ppCache[0] = pCMap; - pCMap->AddRef(); - return pCMap; - } - } - if ((pCMap = CMap::Parse(this, seCollection, seCMapName, pGlobalParams, wsFilePath))) - { - if (m_ppCache[CMapCacheSize - 1]) - { - m_ppCache[CMapCacheSize - 1]->Release(); - } - for (int nJ = CMapCacheSize - 1; nJ >= 1; --nJ) - { - m_ppCache[nJ] = m_ppCache[nJ - 1]; - } - m_ppCache[0] = pCMap; - pCMap->AddRef(); - return pCMap; - } - return NULL; - } -} diff --git a/PdfReader/old/CMap.h b/PdfReader/old/CMap.h deleted file mode 100644 index 77f17fc06c..0000000000 --- a/PdfReader/old/CMap.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CMAP_H -#define _PDF_READER_CMAP_H - -#include "CharTypes.h" -#include "GlobalParams.h" -#include "XmlUtils.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" - -namespace PdfReader -{ - - class StringExt; - struct CMapVectorEntry; - class CMapCache; - - //------------------------------------------------------------------------------------------------------------------------------- - - class CMap - { - public: - - // Создаем карту CMap определенную по и . - // Устанавливаем счетчик ссылок на 1. - static CMap *Parse(CMapCache *pCache, StringExt *seCollection, StringExt *seCMapName, GlobalParams *pGlobalParams, wchar_t *wsFilePath = NULL); - - ~CMap(); - - // Считаем ссылки - void AddRef(); - void Release(); - - // Название коллекции возвращаем в следующем формате: registry-ordering. - StringExt *GetCollection() - { - return m_seCollection; - } - - // Возвращаем true, если параметры CMap совпадают с заданными и . - bool Match(StringExt *seCollection, StringExt *seCMapName); - - // Возвращаем CID соответствующий коду символа, который начинается в , - // и содержит байт. - CID GetCID(char *sChar, int nLen, int *pnUsed); - - // Writing mode (0 = horizontal, 1 = vertical). - int GetWMode() - { - return m_nWMode; - } - void ToXml(std::wstring wsFilePath); - - private: - - CMap(GlobalParams *pGlobalParams, StringExt *seCollection, StringExt *seCMapName); - CMap(GlobalParams *pGlobalParams, StringExt *seCollection, StringExt *seCMapName, int nWMode); - void UseCMap(CMapCache *pCache, char *sUseName); - void CopyVector(CMapVectorEntry *pDest, CMapVectorEntry *pSrc); - void AddCodeSpace(CMapVectorEntry *pVector, unsigned int unStart, unsigned int unEnd, unsigned int unBytesCount); - void AddCIDs(unsigned int unStart, unsigned int unEnd, unsigned int unBytesCount, CID nFirstCID); - void FreeCMapVector(CMapVectorEntry *pVector); - void WriteVectorToXml(CXmlWriter *pWriter, CMapVectorEntry *pVector); - - private: - - StringExt *m_seCollection; // - StringExt *m_seCMapName; // - int m_nWMode; // writing mode (0=horizontal, 1=vertical) - CMapVectorEntry *m_pVector; // vector for first byte (NULL for identity CMap) - int m_nRef; // Счетчик ссылок - - GlobalParams *m_pGlobalParams; - - NSCriticalSection::CRITICAL_SECTION m_oCS; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - -#define CMapCacheSize 4 - - class CMapCache - { - public: - - CMapCache(); - ~CMapCache(); - - CMap *GetCMap(StringExt *seCollection, StringExt *seCMapName, GlobalParams *pGlobalParams, wchar_t *wsFilePath = NULL); - - private: - - CMap *m_ppCache[CMapCacheSize]; - }; -} - -#endif // _PDF_READER_CMAP_H diff --git a/PdfReader/old/Catalog.cpp b/PdfReader/old/Catalog.cpp deleted file mode 100644 index b29417b498..0000000000 --- a/PdfReader/old/Catalog.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "XRef.h" -#include "Array.h" -#include "Dict.h" -#include "Page.h" -#include "Link.h" -#include "Catalog.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Catalog - //------------------------------------------------------------------------ - - Catalog::Catalog(GlobalParams *pGlobalParams, XRef *pXref) - { - m_pGlobalParams = pGlobalParams; - - m_bValid = true; - m_pXref = pXref; - m_ppPages = NULL; - m_pPageRefs = NULL; - m_nPagesCount = m_nPagesSize = 0; - m_seBaseURI = NULL; - - Object oCatalogDict; - m_pXref->GetCatalog(&oCatalogDict); - - if (!oCatalogDict.IsDict()) - { - // TO DO: Error "Catalog object is wrong type " - oCatalogDict.Free(); - m_oDests.InitNull(); - m_oNameTree.InitNull(); - m_bValid = false; - - return; - } - - // Считываем Pages - Object oPagesDict; - oCatalogDict.DictLookup("Pages", &oPagesDict); - - if (!oPagesDict.IsDict()) - { - // TO DO: Error "Top-level pages object is wrong type " - oPagesDict.Free(); - oCatalogDict.Free(); - m_oDests.InitNull(); - m_oNameTree.InitNull(); - m_bValid = false; - - return; - } - - // Считываем количество страниц - Object oTemp; - oPagesDict.DictLookup("Count", &oTemp); - if (!oTemp.IsNum()) // почему-то иногда количество страниц пишется как вещественное число(поэтому IsNum, а не IsInt) - { - // TO DO: Error "Page count in top-level pages object is wrong type" - oTemp.Free(); - oPagesDict.Free(); - oCatalogDict.Free(); - m_oDests.InitNull(); - m_oNameTree.InitNull(); - m_bValid = false; - - return; - } - - int nPagesCount = 0; - m_nPagesSize = nPagesCount = (int)oTemp.GetNum(); - oTemp.Free(); - - // выделяем место под соответствующее количество страниц - m_ppPages = (Page**)MemUtilsMallocArray(m_nPagesSize, sizeof(Page*)); - m_pPageRefs = (Ref*)MemUtilsMallocArray(m_nPagesSize, sizeof(Ref)); - - for (int nIndex = 0; nIndex < m_nPagesSize; ++nIndex) - { - m_ppPages[nIndex] = NULL; - m_pPageRefs[nIndex].nNum = -1; - m_pPageRefs[nIndex].nGen = -1; - } - - char* sAlreadyRead = (char *)MemUtilsMalloc(m_pXref->GetObjectsCount()); - memset(sAlreadyRead, 0, m_pXref->GetObjectsCount()); - - Object oPagesDictRef; - if (oCatalogDict.DictLookupAndCopy("Pages", &oPagesDictRef)->IsRef() && oPagesDictRef.GetRefNum() >= 0 && oPagesDictRef.GetRefNum() < m_pXref->GetObjectsCount()) - { - sAlreadyRead[oPagesDictRef.GetRefNum()] = 1; - } - oPagesDictRef.Free(); - - m_nPagesCount = ReadPageTree(oPagesDict.GetDict(), NULL, 0, sAlreadyRead); - MemUtilsFree(sAlreadyRead); - - if (m_nPagesCount != nPagesCount) - { - // TO DO: Error "Page count in top-level pages object is incorrect" - } - oPagesDict.Free(); - - // Считываем Named destination - oCatalogDict.DictLookup("Dests", &m_oDests); - - if (oCatalogDict.DictLookup("Names", &oTemp)->IsDict()) - oTemp.DictLookup("Dests", &m_oNameTree); - else - m_oNameTree.InitNull(); - oTemp.Free(); - - // URI - if (oCatalogDict.DictLookup("URI", &oTemp)->IsDict()) - { - Object oBase; - if (oTemp.DictLookup("Base", &oBase)->IsString()) - { - m_seBaseURI = oBase.GetString()->Copy(); - } - oBase.Free(); - } - oTemp.Free(); - - // Metadata - oCatalogDict.DictLookup("Metadata", &m_oMetadata); - - // StructTreeRoot - oCatalogDict.DictLookup("StructTreeRoot", &m_oStructTreeRoot); - - // Outlines - oCatalogDict.DictLookup("Outlines", &m_oOutline); - - // AcroForm - oCatalogDict.DictLookup("AcroForm", &m_oAcroForm); - - oCatalogDict.DictLookup("PageLabels", &m_oPageLabels); - - oCatalogDict.Free(); - return; - } - - Catalog::~Catalog() - { - if (m_ppPages) - { - for (int nIndex = 0; nIndex < m_nPagesSize; ++nIndex) - { - if (m_ppPages[nIndex]) - { - delete m_ppPages[nIndex]; - } - } - MemUtilsFree(m_ppPages); - MemUtilsFree(m_pPageRefs); - } - m_oDests.Free(); - m_oNameTree.Free(); - - if (m_seBaseURI) - { - delete m_seBaseURI; - } - - m_oMetadata.Free(); - m_oStructTreeRoot.Free(); - m_oOutline.Free(); - m_oAcroForm.Free(); - m_oPageLabels.Free(); - } - - StringExt *Catalog::ReadMetadata() - { - if (!m_oMetadata.IsStream()) - { - return NULL; - } - Dict *pDict = m_oMetadata.StreamGetDict(); - Object oTemp; - if (!pDict->Search("Subtype", &oTemp)->IsName("XML")) - { - // TO DO: Error "Unknown Metadata type" - } - oTemp.Free(); - StringExt *seResult = new StringExt(); - - m_oMetadata.StreamReset(); - int nChar = 0; - // TO DO: Вообще здесь выводится вся xml как она есть, надо бы ее более детально разобрать - while ((nChar = m_oMetadata.StreamGetChar()) != EOF) - { - seResult->Append(nChar); - } - m_oMetadata.StreamClose(); - return seResult; - } - - int Catalog::ReadPageTree(Dict *pPagesDict, PageAttrs *pAttrs, int nStart, char *sAlreadyRead) - { - PageAttrs *pPageAttrs = new PageAttrs(pAttrs, pPagesDict); - Object oKids; - pPagesDict->Search("Kids", &oKids); - - if (!oKids.IsArray()) - { - // TO DO: Error "Kids object is wrong type" - oKids.Free(); - delete pPageAttrs; - m_bValid = false; - return -1; - } - - for (int nIndex = 0; nIndex < oKids.ArrayGetLength(); ++nIndex) - { - Object oKidRef; - oKids.ArrayGetCopy(nIndex, &oKidRef); - if (oKidRef.IsRef() && oKidRef.GetRefNum() >= 0 && oKidRef.GetRefNum() < m_pXref->GetObjectsCount()) - { - if (sAlreadyRead[oKidRef.GetRefNum()]) - { - // TO DO: Error "Loop in Pages tree" - oKidRef.Free(); - continue; - } - sAlreadyRead[oKidRef.GetRefNum()] = 1; - } - Object oKid; - oKids.ArrayGet(nIndex, &oKid); - if (oKid.IsDict("Page")) - { - PageAttrs *pCurPageAttrs = new PageAttrs(pPageAttrs, oKid.GetDict()); - Page *pCurPage = new Page(m_pGlobalParams, m_pXref, nStart + 1, oKid.GetDict(), pCurPageAttrs); - if (!pCurPage->IsValid()) - { - ++nStart; - MemUtilsFree(pCurPage); - oKid.Free(); - oKids.Free(); - MemUtilsFree(pPageAttrs); - m_bValid = false; - return -1; - } - if (nStart >= m_nPagesSize) - { - m_nPagesSize += 32; - // выделяем дополнительную память - m_ppPages = (Page**)MemUtilsReallocArray(m_ppPages, m_nPagesSize, sizeof(Page *)); - m_pPageRefs = (Ref*)MemUtilsReallocArray(m_pPageRefs, m_nPagesSize, sizeof(Ref)); - - for (int nJ = m_nPagesSize - 32; nJ < m_nPagesSize; ++nJ) - { - m_ppPages[nJ] = NULL; - m_pPageRefs[nJ].nNum = -1; - m_pPageRefs[nJ].nGen = -1; - } - } - m_ppPages[nStart] = pCurPage; - if (oKidRef.IsRef()) - { - m_pPageRefs[nStart].nNum = oKidRef.GetRefNum(); - m_pPageRefs[nStart].nGen = oKidRef.GetRefGen(); - } - ++nStart; - } - else if (oKid.IsDict()) // иногда почему-то пропускают ключ /Type - { - if ((nStart = ReadPageTree(oKid.GetDict(), pPageAttrs, nStart, sAlreadyRead)) < 0) - { - oKid.Free(); - oKids.Free(); - MemUtilsFree(pPageAttrs); - m_bValid = false; - return -1; - } - } - else - { - // TO DO: Error "Kid object is wrong type" - } - oKid.Free(); - oKidRef.Free(); - } - - delete pPageAttrs; - oKids.Free(); - return nStart; - } - - int Catalog::FindPage(int nNum, int nGen) - { - for (int nIndex = 0; nIndex < m_nPagesCount; ++nIndex) - { - if (m_pPageRefs[nIndex].nNum == nNum && m_pPageRefs[nIndex].nGen == nGen) - return nIndex + 1; - } - return 0; - } - - LinkDestination *Catalog::FindDest(StringExt *seName) - { - bool bFound = false; - - Object oDestDict; - if (m_oDests.IsDict()) - { - if (!m_oDests.DictLookup(seName->GetBuffer(), &oDestDict)->IsNull()) - bFound = true; - else - oDestDict.Free(); - } - - if (!bFound && m_oNameTree.IsDict()) - { - if (!FindDestInTree(&m_oNameTree, seName, &oDestDict)->IsNull()) - bFound = true; - else - oDestDict.Free(); - } - - if (!bFound) - return NULL; - - // construct LinkDest - LinkDestination *pLinkDest = NULL; - - if (oDestDict.IsArray()) - { - pLinkDest = new LinkDestination(oDestDict.GetArray()); - } - else if (oDestDict.IsDict()) - { - Object oTemp; - if (oDestDict.DictLookup("D", &oTemp)->IsArray()) - pLinkDest = new LinkDestination(oTemp.GetArray()); - else - { - // TO DO: Error "Bad named destination value" - } - oTemp.Free(); - } - else - { - // TO DO: Error "Bad named destination value" - } - oDestDict.Free(); - if (pLinkDest && !pLinkDest->CheckValidate()) - { - delete pLinkDest; - pLinkDest = NULL; - } - - return pLinkDest; - } - - Object *Catalog::FindDestInTree(Object *pTree, StringExt *seName, Object *pObject) - { - bool bDone = false, bFound = false; - - Object oNames; - if (pTree->DictLookup("Names", &oNames)->IsArray()) - { - bDone = bFound = false; - - for (int nIndex = 0; !bDone && nIndex < oNames.ArrayGetLength(); nIndex += 2) - { - Object oCurName; - if (oNames.ArrayGet(nIndex, &oCurName)->IsString()) - { - int nCompareRes = seName->Compare(oCurName.GetString()); - if (nCompareRes == 0) - { - oNames.ArrayGet(nIndex + 1, pObject); - bFound = true; - bDone = true; - } - else if (nCompareRes < 0) - { - bDone = true; - } - } - oCurName.Free(); - } - oNames.Free(); - if (!bFound) - pObject->InitNull(); - return pObject; - } - oNames.Free(); - - bDone = false; - - Object oKids; - if (pTree->DictLookup("Kids", &oKids)->IsArray()) - { - for (int nIndex = 0; !bDone && nIndex < oKids.ArrayGetLength(); ++nIndex) - { - Object oKid; - if (oKids.ArrayGet(nIndex, &oKid)->IsDict()) - { - Object oLimits; - if (oKid.DictLookup("Limits", &oLimits)->IsArray()) - { - Object oLow; - if (oLimits.ArrayGet(0, &oLow)->IsString() && seName->Compare(oLow.GetString()) >= 0) - { - Object oHigh; - if (oLimits.ArrayGet(1, &oHigh)->IsString() && seName->Compare(oHigh.GetString()) <= 0) - { - FindDestInTree(&oKid, seName, pObject); - bDone = true; - } - oHigh.Free(); - } - oLow.Free(); - } - oLimits.Free(); - } - oKid.Free(); - } - } - oKids.Free(); - - if (!bDone) - pObject->InitNull(); - - return pObject; - } -} diff --git a/PdfReader/old/Catalog.h b/PdfReader/old/Catalog.h deleted file mode 100644 index 3e97775456..0000000000 --- a/PdfReader/old/Catalog.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CATALOG_H -#define _PDF_READER_CATALOG_H - -#include "GlobalParams.h" - -namespace PdfReader -{ - class XRef; - class Object; - class Page; - class PageAttrs; - struct Ref; - class LinkDestination; - - //------------------------------------------------------------------------ - // Catalog - //------------------------------------------------------------------------ - - class Catalog - { - public: - - Catalog(GlobalParams *pGlobalParams, XRef *pXref); - - ~Catalog(); - - bool CheckValidation() - { - return m_bValid; - } - - int GetPagesCount() - { - return m_nPagesCount; - } - - Page *GetPage(int nIndex) - { - return m_ppPages[nIndex - 1]; - } - - Ref *GetPageRef(int nIndex) - { - return &m_pPageRefs[nIndex - 1]; - } - - StringExt *GetBaseURI() - { - return m_seBaseURI; - } - - StringExt *ReadMetadata(); - - Object *GetStructTreeRoot() - { - return &m_oStructTreeRoot; - } - - // Ищем номер страницы в списке, по ее объектным номерам. - int FindPage(int nNum, int nGen); - - // Ищем Named destination. - LinkDestination *FindDest(StringExt *seName); - - Object *GetDests() - { - return &m_oDests; - } - - Object *GetNameTree() - { - return &m_oNameTree; - } - - Object *GetOutline() - { - return &m_oOutline; - } - - Object *GetAcroForm() - { - return &m_oAcroForm; - } - - Object *GetPageLabels() - { - return &m_oPageLabels; - } - - private: - - int ReadPageTree(Dict *pPages, PageAttrs *pAttrs, int nStart, char *sAlreadyRead); - Object *FindDestInTree(Object *pTree, StringExt *seName, Object *pObject); - - private: - - XRef *m_pXref; // Таблица xref для данного PDF файла - Page **m_ppPages; // Массив страниц - Ref *m_pPageRefs; // Объектные номера всех страниц - int m_nPagesCount; // Число страниц - int m_nPagesSize; // Размер массива страниц(в байтах) - Object m_oDests; // Destination dictionary - Object m_oNameTree; // Name tree - StringExt *m_seBaseURI; // Для ссылок URI - Object m_oMetadata; // Metadata - Object m_oStructTreeRoot; // Структура страниц - Object m_oOutline; // Outline - Object m_oAcroForm; // AcroForm - Object m_oPageLabels; // PageLabels - - bool m_bValid; // True, если Сatalog - корретный - - GlobalParams *m_pGlobalParams; - }; -} - -#endif // _PDF_READER_CATALOG_H diff --git a/PdfReader/old/CharCodeToUnicode.cpp b/PdfReader/old/CharCodeToUnicode.cpp deleted file mode 100644 index 20257ce471..0000000000 --- a/PdfReader/old/CharCodeToUnicode.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "File.h" -#include "StringExt.h" -#include "GlobalParams.h" -#include "PSLexer.h" -#include "CharCodeToUnicode.h" - -namespace PdfReader -{ - #define MaxUnicodeString 8 - - struct CharCodeToUnicodeString - { - CharCode nCode; - Unicode pUnicodeString[MaxUnicodeString]; - int nLen; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - - static int GetCharFromString(void *pData) - { - int nChar = 0; - - char *sString = *(char **)pData; - - if (*sString) - { - nChar = *sString++; - *(char **)pData = sString; - } - else - { - nChar = EOF; - } - return nChar; - } - - static int GetCharFromFile(void *pData) - { - return fgetc((FILE *)pData); - } - - //------------------------------------------------------------------------------------------------------------------------------- - - CharCodeToUnicode *CharCodeToUnicode::ParseCIDToUnicode(StringExt *seFileName, StringExt *seCollection) - { - char sBuffer[64]; - Unicode nUnicode = 0; - - FILE* pFile = NSFile::CFileBinary::OpenFileNative(seFileName->GetWString(), L"rb"); - if (!pFile) - { - // TO DO: Error "Couldn't open cidToUnicode file" - return NULL; - } - - unsigned int nSize = 32768; - Unicode *pMap = (Unicode *)MemUtilsMallocArray(nSize, sizeof(Unicode)); - unsigned int nMapLen = 0; - - while (GetLine(sBuffer, sizeof(sBuffer), pFile)) - { - if (nMapLen == nSize) - { - nSize *= 2; - pMap = (Unicode *)MemUtilsReallocArray(pMap, nSize, sizeof(Unicode)); - } - if (sscanf(sBuffer, "%x", &nUnicode) == 1) - { - pMap[nMapLen] = nUnicode; - } - else - { - // TO DO: Error "Bad line in cidToUnicode file" - pMap[nMapLen] = 0; - } - ++nMapLen; - } - fclose(pFile); - - CharCodeToUnicode *pCharCodeToUnicode = new CharCodeToUnicode(seCollection->Copy(), pMap, nMapLen, true, NULL, 0, 0); - MemUtilsFree(pMap); - return pCharCodeToUnicode; - } - - CharCodeToUnicode *CharCodeToUnicode::ParseUnicodeToUnicode(StringExt *seFileName) - { - char sBuffer[256]; - char *sToken; - Unicode nUnicode0; - Unicode arrUnicodeBuffer[MaxUnicodeString]; - - FILE* pFile = NSFile::CFileBinary::OpenFileNative(seFileName->GetWString(), L"rb"); - if (!pFile) - { - // TO DO: Error ""Couldn't open unicodeToUnicode file" - return NULL; - } - - unsigned int nSize = 4096; - Unicode *pMap = (Unicode *)MemUtilsMallocArray(nSize, sizeof(Unicode)); - memset(pMap, 0, nSize * sizeof(Unicode)); - unsigned int nLen = 0; - CharCodeToUnicodeString *pSMap = NULL; - unsigned int nSMapSize = 0, nSMapLen = 0; - - int nLine = 0; - while (GetLine(sBuffer, sizeof(sBuffer), pFile)) - { - ++nLine; - if (!(sToken = strtok(sBuffer, " \t\r\n")) || sscanf(sToken, "%x", &nUnicode0) != 1) - { - // TO DO: Error "Bad line in unicodeToUnicode file" - continue; - } - int nCount = 0; - while (nCount < MaxUnicodeString) - { - if (!(sToken = strtok(NULL, " \t\r\n"))) - { - break; - } - if (sscanf(sToken, "%x", &arrUnicodeBuffer[nCount]) != 1) - { - // TO DO: Error "Bad line in unicodeToUnicode file" - break; - } - ++nCount; - } - if (nCount < 1) - { - // TO DO: Error "Bad line in unicodeToUnicode file" - continue; - } - if (nUnicode0 >= nSize) - { - unsigned int nOldSize = nSize; - while (nUnicode0 >= nSize) - { - nSize *= 2; - } - pMap = (Unicode *)MemUtilsReallocArray(pMap, nSize, sizeof(Unicode)); - memset(pMap + nOldSize, 0, (nSize - nOldSize) * sizeof(Unicode)); - } - if (nCount == 1) - { - pMap[nUnicode0] = arrUnicodeBuffer[0]; - } - else - { - pMap[nUnicode0] = 0; - if (nSMapLen == nSMapSize) - { - nSMapSize += 16; - pSMap = (CharCodeToUnicodeString *)MemUtilsReallocArray(pSMap, nSMapSize, sizeof(CharCodeToUnicodeString)); - } - pSMap[nSMapLen].nCode = nUnicode0; - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - pSMap[nSMapLen].pUnicodeString[nIndex] = arrUnicodeBuffer[nIndex]; - } - pSMap[nSMapLen].nLen = nCount; - ++nSMapLen; - } - if (nUnicode0 >= nLen) - { - nLen = nUnicode0 + 1; - } - } - fclose(pFile); - - CharCodeToUnicode *pCharCodeToUnicode = new CharCodeToUnicode(seFileName->Copy(), pMap, nLen, true, pSMap, nSMapLen, nSMapSize); - MemUtilsFree(pMap); - return pCharCodeToUnicode; - } - - CharCodeToUnicode *CharCodeToUnicode::Make8BitToUnicode(Unicode *pToUnicode) - { - return new CharCodeToUnicode(NULL, pToUnicode, 256, true, NULL, 0, 0); - } - - CharCodeToUnicode *CharCodeToUnicode::ParseCMap(StringExt *seBuffer, int nBitCount, GlobalParams *pGlobalParams) - { - CharCodeToUnicode *pCharCodeToUnicode = new CharCodeToUnicode(NULL); - char *pData = seBuffer->GetBuffer(); - pCharCodeToUnicode->ParseCMap1(&GetCharFromString, &pData, nBitCount, pGlobalParams); - return pCharCodeToUnicode; - } - - void CharCodeToUnicode::MergeCMap(StringExt *seBuffer, int nBitCount, GlobalParams *pGlobalParams) - { - char *pData = seBuffer->GetBuffer(); - ParseCMap1(&GetCharFromString, &pData, nBitCount, pGlobalParams); - } - - void CharCodeToUnicode::ParseCMap1(int(*GetCharFunc)(void *), void *pData, int nBitCount, GlobalParams *pGlobalParams) - { - char sToken1[256], sToken2[256], sToken3[256]; - int nLen1, nLen2, nLen3; - CharCode nCode1, nCode2; - - - int nDigitCount = nBitCount / 4; - PSLexer *pLexer = new PSLexer(GetCharFunc, pData); - pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - - while (pLexer->GetToken(sToken2, sizeof(sToken2), &nLen2)) - { - if (!strcmp(sToken2, "usecmap")) - { - if (sToken1[0] == '/') - { - StringExt *seName = new StringExt(sToken1 + 1); - FILE *pFile = NULL; - if (pGlobalParams && (pFile = pGlobalParams->FindToUnicodeFile(seName))) - { - ParseCMap1(&GetCharFromFile, pFile, nBitCount, pGlobalParams); - fclose(pFile); - } - else - { - // TO DO: Error "Couldn't find ToUnicode CMap file" - } - delete seName; - } - pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken2, "beginbfchar")) - { - while (pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1)) - { - if (!strcmp(sToken1, "endbfchar")) - { - break; - } - if (!pLexer->GetToken(sToken2, sizeof(sToken2), &nLen2) || !strcmp(sToken2, "endbfchar")) - { - // TO DO: Error "Illegal entry in bfchar block in ToUnicode CMap" - break; - } - if (!(nLen1 == 2 + nDigitCount && sToken1[0] == '<' && sToken1[nLen1 - 1] == '>' && sToken2[0] == '<' && sToken2[nLen2 - 1] == '>')) - { - // TO DO: Error "Illegal entry in bfchar block in ToUnicode CMap" - continue; - } - sToken1[nLen1 - 1] = sToken2[nLen2 - 1] = '\0'; - if (sscanf(sToken1 + 1, "%x", &nCode1) != 1) - { - // TO DO: Error "Illegal entry in bfchar block in ToUnicode CMap" - continue; - } - AddMapping(nCode1, sToken2 + 1, nLen2 - 2, 0); - } - pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else if (!strcmp(sToken2, "beginbfrange")) - { - while (pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1)) - { - if (!strcmp(sToken1, "endbfrange")) - { - break; - } - if (!pLexer->GetToken(sToken2, sizeof(sToken2), &nLen2) || !strcmp(sToken2, "endbfrange") || !pLexer->GetToken(sToken3, sizeof(sToken3), &nLen3) || !strcmp(sToken3, "endbfrange")) - { - // TO DO: Error "Illegal entry in bfrange block in ToUnicode CMap" - break; - } - if (!(nLen1 == 2 + nDigitCount && sToken1[0] == '<' && sToken1[nLen1 - 1] == '>' && nLen2 == 2 + nDigitCount && sToken2[0] == '<' && sToken2[nLen2 - 1] == '>')) - { - // TO DO: Error "Illegal entry in bfrange block in ToUnicode CMap" - continue; - } - sToken1[nLen1 - 1] = sToken2[nLen2 - 1] = '\0'; - if (sscanf(sToken1 + 1, "%x", &nCode1) != 1 || sscanf(sToken2 + 1, "%x", &nCode2) != 1) - { - // TO DO: Error "Illegal entry in bfrange block in ToUnicode CMap" - continue; - } - if (!strcmp(sToken3, "[")) - { - int nIndex = 0; - while (pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1) && nCode1 + nIndex <= nCode2) - { - if (!strcmp(sToken1, "]")) - { - break; - } - if (sToken1[0] == '<' && sToken1[nLen1 - 1] == '>') - { - sToken1[nLen1 - 1] = '\0'; - AddMapping(nCode1 + nIndex, sToken1 + 1, nLen1 - 2, 0); - } - else - { - // TO DO: Error "Illegal entry in bfrange block in ToUnicode CMap" - } - ++nIndex; - } - } - else if (sToken3[0] == '<' && sToken3[nLen3 - 1] == '>') - { - sToken3[nLen3 - 1] = '\0'; - for (int nIndex = 0; nCode1 <= nCode2; ++nCode1, ++nIndex) - { - AddMapping(nCode1, sToken3 + 1, nLen3 - 2, nIndex); - } - } - else - { - // TO DO: Error "Illegal entry in bfrange block in ToUnicode CMap" - } - } - pLexer->GetToken(sToken1, sizeof(sToken1), &nLen1); - } - else - { - strcpy(sToken1, sToken2); - } - } - delete pLexer; - } - - void CharCodeToUnicode::AddMapping(CharCode nCode, char *sUnicodeString, int nLen, int nOffset) - { - - if (nCode >= m_nMapLen) - { - unsigned int unOldLen = m_nMapLen; - m_nMapLen = (nCode + 256) & ~255; - m_pMap = (Unicode *)MemUtilsReallocArray(m_pMap, m_nMapLen, sizeof(Unicode)); - for (unsigned int unIndex = unOldLen; unIndex < m_nMapLen; ++unIndex) - { - m_pMap[unIndex] = 0; - } - } - if (nLen <= 4) - { - Unicode nUnicode = 0; - if (sscanf(sUnicodeString, "%x", &nUnicode) != 1) - { - // TO DO: Error Illegal entry in ToUnicode CMap" - return; - } - m_pMap[nCode] = nUnicode + nOffset; - } - else - { - if (m_nSMapLen >= m_nSMapSize) - { - m_nSMapSize = m_nSMapSize + 16; - m_pSMap = (CharCodeToUnicodeString *)MemUtilsReallocArray(m_pSMap, m_nSMapSize, sizeof(CharCodeToUnicodeString)); - } - m_pMap[nCode] = 0; - m_pSMap[m_nSMapLen].nCode = nCode; - m_pSMap[m_nSMapLen].nLen = nLen / 4; - for (int nIndex = 0; nIndex < m_pSMap[m_nSMapLen].nLen && nIndex < MaxUnicodeString; ++nIndex) - { - char pUnicodeHex[5]; - strncpy(pUnicodeHex, sUnicodeString + nIndex * 4, 4); - pUnicodeHex[4] = '\0'; - if (sscanf(pUnicodeHex, "%x", &m_pSMap[m_nSMapLen].pUnicodeString[nIndex]) != 1) - { - // TO DO: Error "Illegal entry in ToUnicode CMap" - } - } - m_pSMap[m_nSMapLen].pUnicodeString[m_pSMap[m_nSMapLen].nLen - 1] += nOffset; - ++m_nSMapLen; - } - } - - CharCodeToUnicode::CharCodeToUnicode(StringExt *seTag) - { - m_seTag = seTag; - m_nMapLen = 256; - m_pMap = (Unicode *)MemUtilsMallocArray(m_nMapLen, sizeof(Unicode)); - for (unsigned int unIndex = 0; unIndex < m_nMapLen; ++unIndex) - { - m_pMap[unIndex] = 0; - } - m_pSMap = NULL; - m_nSMapLen = m_nSMapSize = 0; - m_nRef = 1; - - m_oCS.InitializeCriticalSection(); - } - - CharCodeToUnicode::CharCodeToUnicode(StringExt *seTag, Unicode *pMap, CharCode unMapLen, bool bCopyMap, CharCodeToUnicodeString *pSMap, int nSMapLen, int nSMapSize) - { - m_seTag = seTag; - m_nMapLen = unMapLen; - if (bCopyMap) - { - m_pMap = (Unicode *)MemUtilsMallocArray(m_nMapLen, sizeof(Unicode)); - memcpy(m_pMap, pMap, m_nMapLen * sizeof(Unicode)); - } - else - { - m_pMap = pMap; - } - m_pSMap = pSMap; - m_nSMapLen = nSMapLen; - m_nSMapSize = nSMapSize; - - m_nRef = 1; - - m_oCS.InitializeCriticalSection(); - } - - CharCodeToUnicode::~CharCodeToUnicode() - { - if (m_seTag) - { - delete m_seTag; - } - MemUtilsFree(m_pMap); - MemUtilsFree(m_pSMap); - - m_oCS.DeleteCriticalSection(); - } - - void CharCodeToUnicode::AddRef() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - - ++m_nRef; - - RELEASEOBJECT(pCS); - } - - void CharCodeToUnicode::Release() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - - bool bDelete = (--m_nRef == 0); - - RELEASEOBJECT(pCS); - - if (bDelete) - { - delete this; - } - } - - bool CharCodeToUnicode::Match(StringExt *seTag) - { - return m_seTag && !m_seTag->Compare(seTag); - } - - void CharCodeToUnicode::SetMapping(CharCode nCode, Unicode *pUnicode, int nLen) - { - if (nLen == 1) - { - m_pMap[nCode] = pUnicode[0]; - } - else - { - int nIndex = 0; - for (nIndex = 0; nIndex < m_nSMapLen; ++nIndex) - { - if (m_pSMap[nIndex].nCode == nCode) - { - break; - } - } - if (nIndex == m_nSMapLen) - { - if (m_nSMapLen == m_nSMapSize) - { - m_nSMapSize += 8; - m_pSMap = (CharCodeToUnicodeString *)MemUtilsReallocArray(m_pSMap, m_nSMapSize, sizeof(CharCodeToUnicodeString)); - } - ++m_nSMapLen; - } - m_pMap[nCode] = 0; - m_pSMap[nIndex].nCode = nCode; - m_pSMap[nIndex].nLen = nLen; - - for (int nJ = 0; nJ < nLen && nJ < MaxUnicodeString; ++nJ) - { - m_pSMap[nIndex].pUnicodeString[nJ] = pUnicode[nJ]; - } - } - } - - int CharCodeToUnicode::MapToUnicode(CharCode nCode, Unicode *pUnicode, int size) - { - if (nCode >= m_nMapLen) - { - return 0; - } - if (m_pMap[nCode]) - { - pUnicode[0] = m_pMap[nCode]; - return 1; - } - for (int nIndex = 0; nIndex < m_nSMapLen; ++nIndex) - { - if (m_pSMap[nIndex].nCode == nCode) - { - int nJ = 0; - for (nJ = 0; nJ < m_pSMap[nIndex].nLen && nJ < size; ++nJ) - { - pUnicode[nJ] = m_pSMap[nIndex].pUnicodeString[nJ]; - } - return nJ; - } - } - return 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - - CharCodeToUnicodeCache::CharCodeToUnicodeCache(int nSize) - { - m_nSize = nSize; - m_ppCache = (CharCodeToUnicode **)MemUtilsMallocArray(m_nSize, sizeof(CharCodeToUnicode *)); - for (int nIndex = 0; nIndex < m_nSize; ++nIndex) - { - m_ppCache[nIndex] = NULL; - } - } - - CharCodeToUnicodeCache::~CharCodeToUnicodeCache() - { - for (int nIndex = 0; nIndex < m_nSize; ++nIndex) - { - if (m_ppCache[nIndex]) - { - m_ppCache[nIndex]->Release(); - } - } - MemUtilsFree(m_ppCache); - } - - CharCodeToUnicode *CharCodeToUnicodeCache::GetCharCodeToUnicode(StringExt *seTag) - { - if (m_ppCache[0] && m_ppCache[0]->Match(seTag)) - { - m_ppCache[0]->AddRef(); - return m_ppCache[0]; - } - - for (int nIndex = 1; nIndex < m_nSize; ++nIndex) - { - if (m_ppCache[nIndex] && m_ppCache[nIndex]->Match(seTag)) - { - CharCodeToUnicode *pCharCodeToUnicode = m_ppCache[nIndex]; - for (int nJ = nIndex; nJ >= 1; --nJ) - { - m_ppCache[nJ] = m_ppCache[nJ - 1]; - } - m_ppCache[0] = pCharCodeToUnicode; - pCharCodeToUnicode->AddRef(); - return pCharCodeToUnicode; - } - } - return NULL; - } - - void CharCodeToUnicodeCache::Add(CharCodeToUnicode *pCharCodeToUnicode) - { - if (m_ppCache[m_nSize - 1]) - { - m_ppCache[m_nSize - 1]->Release(); - } - - for (int nIndex = m_nSize - 1; nIndex >= 1; --nIndex) - { - m_ppCache[nIndex] = m_ppCache[nIndex - 1]; - } - m_ppCache[0] = pCharCodeToUnicode; - pCharCodeToUnicode->AddRef(); - } -} \ No newline at end of file diff --git a/PdfReader/old/CharCodeToUnicode.h b/PdfReader/old/CharCodeToUnicode.h deleted file mode 100644 index ef4b618664..0000000000 --- a/PdfReader/old/CharCodeToUnicode.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CHARCODE_TO_UNICODE_H -#define _PDF_READER_CHARCODE_TO_UNICODE_H - -#include "CharTypes.h" -#include "GlobalParams.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" - -namespace PdfReader -{ - struct CharCodeToUnicodeString; - - //------------------------------------------------------------------------------------------------------------------------------- - - class CharCodeToUnicode - { - public: - - static CharCodeToUnicode *ParseCIDToUnicode(StringExt *sFileName, StringExt *seCollection); - - static CharCodeToUnicode *ParseUnicodeToUnicode(StringExt *sFileName); - - static CharCodeToUnicode *Make8BitToUnicode(Unicode *pToUnicode); - - static CharCodeToUnicode *ParseCMap(StringExt *sBuffer, int nBitCount, GlobalParams *pGlobalParams); - - void MergeCMap(StringExt *sBuffer, int nBitCount, GlobalParams *pGlobalParams); - - ~CharCodeToUnicode(); - - // Считаем ссылки - void AddRef(); - void Release(); - - // Сравниваем по данному тэгу - bool Match(StringExt *seTag); - - void SetMapping(CharCode nCode, Unicode *pUnicode, int nLen); - - int MapToUnicode(CharCode nCode, Unicode *pUnicode, int nSize); - - CharCode GetLength() - { - return m_nMapLen; - } - - private: - - void ParseCMap1(int(*GetCharFunc)(void *), void *pData, int nBitCount, GlobalParams *pGlobalParams); - void AddMapping(CharCode nCode, char *sUnicodeString, int nLen, int nOffset); - CharCodeToUnicode(StringExt *sTag); - CharCodeToUnicode(StringExt *sTag, Unicode *pMap, CharCode nMapLen, bool bCopyMap, CharCodeToUnicodeString *pSMap, int nSMapLen, int nSMapSize); - - private: - - StringExt *m_seTag; - Unicode *m_pMap; - CharCode m_nMapLen; - CharCodeToUnicodeString*m_pSMap; - int m_nSMapLen; - int m_nSMapSize; - - int m_nRef; - - NSCriticalSection::CRITICAL_SECTION m_oCS; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - - class CharCodeToUnicodeCache - { - public: - - CharCodeToUnicodeCache(int nSize); - ~CharCodeToUnicodeCache(); - - CharCodeToUnicode *GetCharCodeToUnicode(StringExt *seTag); - - void Add(CharCodeToUnicode *pCharCodeToUnicode); - - private: - - CharCodeToUnicode **m_ppCache; - int m_nSize; - }; -} - -#endif // _PDF_READER_CHARCODE_TO_UNICODE_H diff --git a/PdfReader/old/CharTypes.h b/PdfReader/old/CharTypes.h deleted file mode 100644 index c487ba8a11..0000000000 --- a/PdfReader/old/CharTypes.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CHARTYPES_H -#define _PDF_READER_CHARTYPES_H - -namespace PdfReader -{ - // Unicode-символы. - typedef unsigned int Unicode; - - // Для элементов CID. - typedef unsigned int CID; - - // Общий тип, рассчитан наодин из следюущих вариантов: - // - 8-битные символы - // - 16-битный CID - // - Unicode - typedef unsigned int CharCode; -} - -#endif // _PDF_READER_CHARTYPES_H diff --git a/PdfReader/old/Constants.h b/PdfReader/old/Constants.h deleted file mode 100644 index 0e9fd06457..0000000000 --- a/PdfReader/old/Constants.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_CONSTANTS_H -#define _PDF_READER_CONSTANTS_H - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - - // Поддерживаемая версия PDF файла -#define SupportedPDFVersionStr "1.7" -#define SupportedPDFVersionNum 1.7 - - //------------------------------------------------------------------------------------------------------------------------------- - // Paper size - //------------------------------------------------------------------------------------------------------------------------------- - - // Стандартные размеры страницы (в пикселях (72dpi)) -#ifndef A4_PAPER -#define DefaultPaperWidth 595 // ISO A4 (210x297 mm) -#define DefaultPaperHeight 842 -#else -#define DefaultPaperWidth 612 // American letter (8.5x11") -#define DefaultPaperHeight 792 -#endif - - //------------------------------------------------------------------------------------------------------------------------------- - // Config file path - //------------------------------------------------------------------------------------------------------------------------------- - -#if defined(VMS) || (defined(WIN32) && !defined(__CYGWIN32__)) -#define UserConfigFile "pdfrc" -#define SysConfigFile "pdfrc" -#else -#define UserConfigFile ".pdfrc" -#define SysConfigFile ".pdfrc" -#endif -} - -#endif // _PDF_READER_CONSTANTS_H diff --git a/PdfReader/old/Decrypt.cpp b/PdfReader/old/Decrypt.cpp deleted file mode 100644 index 1b5b50e759..0000000000 --- a/PdfReader/old/Decrypt.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "MemoryUtils.h" -#include "Decrypt.h" -#include "SecurityHandler.h" - -#include "../../Common/3dParty/cryptopp/modes.h" -#include "../../Common/3dParty/cryptopp/aes.h" -#include "../../Common/3dParty/cryptopp/sha.h" -#include "../../Common/3dParty/cryptopp/md5.h" -#include "../../Common/3dParty/cryptopp/arc4.h" -#include "../../Common/3dParty/cryptopp/filters.h" - -#include "../../DesktopEditor/common/File.h" -#include "../../UnicodeConverter/UnicodeConverter.h" -namespace PdfReader -{ - static void MD5(unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) - { - CryptoPP::MD5 hash; - - hash.Update( sMessage, nMessageLen); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.BytePtr(), buffer.size()); - return; - } - static int SHA(int type, unsigned char *sMessage, int nMessageLen, unsigned char *sDigest) - { - int res = 0; - switch(type) - { - case 0: - case 256: - { - CryptoPP::SHA256 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.BytePtr(), buffer.size()); - }break; - case 1: - case 384: - { - CryptoPP::SHA384 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.BytePtr(), buffer.size()); - }break; - case 2: - case 512: - { - CryptoPP::SHA512 hash; - hash.Update( sMessage, nMessageLen > 0 ? nMessageLen : hash.DigestSize()); - - CryptoPP::SecByteBlock buffer(res = hash.DigestSize()); - hash.Final(buffer); - - memcpy(sDigest, buffer.BytePtr(), buffer.size()); - }break; - } - return res; - } - static unsigned char passwordPad[32] = - { - 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, - 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, - 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, - 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Decrypt - //------------------------------------------------------------------------------------------------------------------------------- - - bool Decrypt::MakeFileKey(StandardSecurityHandler *handler, const std::wstring &wsOwnerPassword, const std::wstring &wsUserPassword) - { - if (!handler) return false; - handler->m_bOwnerPasswordValid = false; - - if ( handler->m_nEncryptRevision < 5 ) - { - // Попытаемся, используя пароль владельца, сгенерировать пользовательский пароль - if (false == wsOwnerPassword.empty()) - { - std::string sOwnerPassword = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsOwnerPassword); - int nLen = sOwnerPassword.length(); - unsigned char arrOwnerPass[32]; - if (nLen < 32) - { - memcpy(arrOwnerPass, sOwnerPassword.c_str(), nLen); - memcpy(arrOwnerPass + nLen, passwordPad, 32 - nLen); - } - else - { - memcpy(arrOwnerPass, sOwnerPassword.c_str(), 32); - } - MD5(arrOwnerPass, 32, arrOwnerPass); - - if (handler->m_nEncryptRevision >= 3) - { - for (int nIndex = 0; nIndex < 50; ++nIndex) - { - MD5(arrOwnerPass, 16, arrOwnerPass); - } - } - - unsigned char arrOwnerKey[32]; - unsigned char arrFState[256]; - if (handler->m_nEncryptRevision == 2) - { - CryptoPP::ARC4::Decryption rc4Decryption; - rc4Decryption.SetKey(arrOwnerPass, handler->m_nFileKeyLength); - - rc4Decryption.ProcessData(arrOwnerKey, (unsigned char*)handler->m_seOwnerKey->GetBuffer(), 32); - } - else - { - memcpy(arrOwnerKey, handler->m_seOwnerKey->GetBuffer(), 32); - for (int nIndex = 19; nIndex >= 0; --nIndex) - { - unsigned char arrTempKey[16]; - for (int nJ = 0; nJ < handler->m_nFileKeyLength; ++nJ) - { - arrTempKey[nJ] = arrOwnerPass[nJ] ^ nIndex; - } - CryptoPP::ARC4::Decryption rc4Decryption; - - rc4Decryption.SetKey(arrTempKey, handler->m_nFileKeyLength); - rc4Decryption.ProcessData(arrOwnerKey, arrOwnerKey, 32); - } - } - std::string sUserPassword2((char *)arrOwnerKey, 32); - - if (MakeFileKey2(handler, sUserPassword2)) - { - handler->m_bOwnerPasswordValid = true; - return true; - } - } - // Попытаемся использовать пользовательский пароль - std::string sUserPassword = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsUserPassword); - return MakeFileKey2(handler, sUserPassword); - } - else - { - bool bValidate = false; - unsigned char empty[16]; - - NSUnicodeConverter::CUnicodeConverter conv; - std::string sUserPassword = conv.SASLprepToUtf8(wsUserPassword); - - if (sUserPassword.length() > 127) - sUserPassword = sUserPassword.substr(0, 127); - - CryptoPP::SHA256 hash; - - hash.Update( (unsigned char*) sUserPassword.c_str(), sUserPassword.length()); - hash.Update( handler->m_seUserKey->GetUBuffer() + 32, 8); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - if ( handler->m_nEncryptRevision > 5 ) - { - MakeFileKey3(sUserPassword, buffer.BytePtr(), buffer.size()); - } - - bValidate = (0 == memcmp(buffer.BytePtr(), handler->m_seUserKey->GetUBuffer(), 32)); - - if (bValidate) - { - hash.Update( (unsigned char*) sUserPassword.c_str(), sUserPassword.length()); - hash.Update( handler->m_seUserKey->GetUBuffer() + 40, 8); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - if ( handler->m_nEncryptRevision > 5 ) - { - MakeFileKey3(sUserPassword, buffer.BytePtr(), buffer.size()); - } - - memset(empty, 0, 16); - CryptoPP::AES::Decryption aesDecryption(buffer.BytePtr(), buffer.size()); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty ); - - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( (unsigned char*)handler->m_sFileKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfDecryptor.Put( handler->m_seUserEncryptionKey->GetUBuffer(), 32); - stfDecryptor.MessageEnd(); - } - else - { - std::string sOwnerPassword = conv.SASLprepToUtf8(wsOwnerPassword); - if (sOwnerPassword.length() > 127) - sOwnerPassword = sOwnerPassword.substr(0, 127); - - hash.Update( (unsigned char*) sOwnerPassword.c_str(), sOwnerPassword.length()); - hash.Update( handler->m_seOwnerKey->GetUBuffer() + 32, 8); - hash.Update( handler->m_seUserKey->GetUBuffer(), 48); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - if ( handler->m_nEncryptRevision > 5 ) - { - MakeFileKey3(sOwnerPassword, buffer.BytePtr(), buffer.size(), handler->m_seUserKey->GetUBuffer(), 48); - } - - bValidate = (0 == memcmp(buffer.BytePtr(), handler->m_seOwnerKey->GetUBuffer(), 32)); - - if (bValidate) - { - hash.Update( (unsigned char*) sOwnerPassword.c_str(), sOwnerPassword.length()); - hash.Update( handler->m_seOwnerKey->GetUBuffer() + 40, 8); - hash.Update( handler->m_seUserKey->GetUBuffer(), 48); - - CryptoPP::SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - if ( handler->m_nEncryptRevision > 5 ) - { - MakeFileKey3(sOwnerPassword, buffer.BytePtr(), buffer.size(), handler->m_seUserKey->GetUBuffer(), 48); - } - memset(empty, 0, 16); - CryptoPP::AES::Decryption aesDecryption(buffer.BytePtr(), buffer.size()); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty ); - - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( (unsigned char*)handler->m_sFileKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfDecryptor.Put(handler->m_seOwnerEncryptionKey->GetUBuffer(), 32); - stfDecryptor.MessageEnd(); - } - } - handler->m_bOwnerPasswordValid = bValidate; - return bValidate; - } - } - - bool Decrypt::MakeFileKey3(const std::string &sPassword, unsigned char *pHash, int nHashSize, unsigned char *pHash2, int nHashSize2) - { - if (!pHash) return false; - - int size = 64 * (sPassword.length() + 64 + nHashSize2); // max - - unsigned char K[64]; //max size sha - unsigned char *K1 = new unsigned char[size]; - unsigned char *E = new unsigned char[size]; - - int hash_size = nHashSize; - memcpy(K, pHash, nHashSize); - - int iteration = 0; - - while( (iteration < 64) || (iteration < E[size - 1] + 32)) - { - CryptoPP::SecByteBlock key(K, 16), iv(K + 16, 16); - - size = 0; - for (int i = 0; i < 64; i++) - { - memcpy(K1 + size, sPassword.c_str(), sPassword.length()); size += sPassword.length(); - memcpy(K1 + size, K, hash_size); size += hash_size; - if (pHash2) - { - memcpy(K1 + size, pHash2, nHashSize2); size += nHashSize2; - } - } - CryptoPP::AES::Encryption aesEncryption(key, key.size()); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv); - - CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( E, size), CryptoPP::StreamTransformationFilter::NO_PADDING); - - stfEncryption.Put( K1, size); - stfEncryption.MessageEnd(); -//---------------------------------------------------------- - int E_mod_3 = 0; - for (unsigned int i = 0; i < 16; ++i) - { - E_mod_3 += E[i]; - } - E_mod_3 %= 3; - - hash_size = SHA(E_mod_3, E, size, K); - - iteration++; - } - - delete []K1; - delete []E; - - memcpy (pHash, K, 32); // pHash - from sha256 - return true; - } - - bool Decrypt::MakeFileKey2(StandardSecurityHandler *handler, const std::string &sUserPassword) - { - if (!handler) return false; - - unsigned char sTest[32]; - unsigned char sFState[256]; - unsigned char sTempKey[16]; - unsigned char unFx, unFy; - int nLen = 0; - bool bResult = true; - - unsigned char *pBuffer = (unsigned char *)MemUtilsMalloc(72 + handler->m_seFileID->GetLength()); - - if (false == sUserPassword.empty()) - { - nLen = sUserPassword.length(); - if (nLen < 32) - { - memcpy(pBuffer, sUserPassword.c_str(), nLen); - memcpy(pBuffer + nLen, passwordPad, 32 - nLen); - } - else - { - memcpy(pBuffer, sUserPassword.c_str(), 32); - } - } - else - { - memcpy(pBuffer, passwordPad, 32); - } - - memcpy(pBuffer + 32, handler->m_seOwnerKey->GetBuffer(), 32); - - pBuffer[64] = handler->m_nPermissionFlags & 0xff; - pBuffer[65] = (handler->m_nPermissionFlags >> 8) & 0xff; - pBuffer[66] = (handler->m_nPermissionFlags >> 16) & 0xff; - pBuffer[67] = (handler->m_nPermissionFlags >> 24) & 0xff; - - memcpy(pBuffer + 68, handler->m_seFileID->GetBuffer(), handler->m_seFileID->GetLength()); - nLen = 68 + handler->m_seFileID->GetLength(); - if (!handler->m_bEncryptMetadata) - { - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - pBuffer[nLen++] = 0xff; - } - MD5(pBuffer, nLen, handler->m_sFileKey); - if (handler->m_nEncryptRevision >= 3) - { - for (int nIndex = 0; nIndex < 50; ++nIndex) - { - MD5(handler->m_sFileKey, handler->m_nFileKeyLength, handler->m_sFileKey); - } - } - - if (handler->m_nEncryptRevision == 2) - { - CryptoPP::ARC4::Decryption rc4Decryption; - rc4Decryption.SetKey(handler->m_sFileKey, handler->m_nFileKeyLength); - - rc4Decryption.ProcessData(sTest, (unsigned char*)handler->m_seUserKey->GetBuffer(), 32); - - bResult = (memcmp(sTest, passwordPad, 32) == 0); - } - else if (handler->m_nEncryptRevision >= 3) - { - memcpy(sTest, handler->m_seUserKey->GetBuffer(), 32); - for (int nIndex = 19; nIndex >= 0; --nIndex) - { - for (int nJ = 0; nJ < handler->m_nFileKeyLength; ++nJ) - { - sTempKey[nJ] = handler->m_sFileKey[nJ] ^ nIndex; - } - CryptoPP::ARC4::Decryption rc4Decryption; - - rc4Decryption.SetKey(sTempKey, handler->m_nFileKeyLength); - rc4Decryption.ProcessData(sTest, sTest, 32); - } - memcpy(pBuffer, passwordPad, 32); - memcpy(pBuffer + 32, handler->m_seFileID->GetBuffer(), handler->m_seFileID->GetLength()); - - MD5(pBuffer, 32 + handler->m_seFileID->GetLength(), pBuffer); - - bResult = (memcmp(sTest, pBuffer, 16) == 0); - } - else - { - bResult = false; - } - - MemUtilsFree(pBuffer); - return bResult; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // DecryptStream - //------------------------------------------------------------------------------------------------------------------------------- - - DecryptStream::DecryptStream(Stream *pStream, unsigned char *sFileKey, CryptAlgorithm eType, int nKeyLength, int nObjectNum, int nObjectGen) : - FilterStream(pStream), m_pUncryptedData(NULL), m_pUncryptedDataSize(0), m_nObjectKeyLength(nKeyLength) - { - m_eCryptType = eType; - memcpy(m_sObjectKey, sFileKey, nKeyLength); - - if (m_eCryptType != cryptAES256) - { - m_sObjectKey[nKeyLength + 0] = nObjectNum & 0xff; - m_sObjectKey[nKeyLength + 1] = (nObjectNum >> 8) & 0xff; - m_sObjectKey[nKeyLength + 2] = (nObjectNum >> 16) & 0xff; - m_sObjectKey[nKeyLength + 3] = nObjectGen & 0xff; - m_sObjectKey[nKeyLength + 4] = (nObjectGen >> 8) & 0xff; - - int nLen = 0; - if (m_eCryptType == cryptAES128) - { - m_sObjectKey[nKeyLength + 5] = 0x73; // 's' - m_sObjectKey[nKeyLength + 6] = 0x41; // 'A' - m_sObjectKey[nKeyLength + 7] = 0x6c; // 'l' - m_sObjectKey[nKeyLength + 8] = 0x54; // 'T' - - nLen = nKeyLength + 9; - } - else if (m_eCryptType == cryptRC4) - { - nLen = nKeyLength + 5; - } - MD5(m_sObjectKey, nLen, m_sObjectKey); - - if ((m_nObjectKeyLength = nKeyLength + 5) > 16) - { - m_nObjectKeyLength = 16; - } - } - } - - DecryptStream::~DecryptStream() - { - delete m_pStream; - - if (m_pUncryptedData) - delete []m_pUncryptedData; - } - - void DecryptStream::Reset() - { - m_pStream->Reset(); - - MemoryStream* mem_stream = dynamic_cast(m_pStream); - - unsigned int size = mem_stream->getCurrentLength(); - - if (size < 16) return; - - unsigned char* data = (unsigned char*)mem_stream->getCurrent(); - - if (!m_pUncryptedData || m_pUncryptedDataSize < size) - { - if (m_pUncryptedData) - delete []m_pUncryptedData; - - m_pUncryptedData = new unsigned char[size]; - m_pUncryptedDataSize = size; - } - m_pUncryptedDataPosition = 0; - - switch (m_eCryptType) - { - case cryptRC4: - { - CryptoPP::ARC4::Decryption rc4Decryption; - rc4Decryption.SetKey(m_sObjectKey, m_nObjectKeyLength); - - rc4Decryption.ProcessData(m_pUncryptedData, data, size); - }break; - case cryptAES128: - case cryptAES256: - { - CryptoPP::AES::Decryption aesDecryption(m_sObjectKey, m_nObjectKeyLength); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, data ); - - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( m_pUncryptedData, size), CryptoPP::StreamTransformationFilter::NO_PADDING ); - stfDecryptor.Put( data + 16, size - 16); - stfDecryptor.MessageEnd(); - - m_pUncryptedDataSize = size - 16; - }break; - } - } - - int DecryptStream::GetChar() - { - m_pStream->GetChar(); - return m_pUncryptedDataPosition < m_pUncryptedDataSize ? (m_pUncryptedData[m_pUncryptedDataPosition++] & 0xff) : EOF; - } - - int DecryptStream::LookChar() - { - return m_pUncryptedDataPosition < m_pUncryptedDataSize ? (m_pUncryptedData[m_pUncryptedDataPosition] & 0xff) : EOF; - - } - - bool DecryptStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(bLast); - } -} diff --git a/PdfReader/old/Decrypt.h b/PdfReader/old/Decrypt.h deleted file mode 100644 index 2665b399b7..0000000000 --- a/PdfReader/old/Decrypt.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_DECRYPT_H -#define _PDF_READER_DECRYPT_H - -#include "StringExt.h" -#include "Object.h" -#include "Stream.h" - -namespace PdfReader -{ - class StandardSecurityHandler; - //------------------------------------------------------------------------------------------------------------------------------- - // Decrypt - //------------------------------------------------------------------------------------------------------------------------------- - - class Decrypt - { - public: - // Строим FileKey. Параметр должен иметь место как минимум под 16 байт. Проверяем и - // и возвращаем true, если какой-нибудь корректен. Пишем = true, если был правильный. - // Один какой-нибудь или оба пароля могут быть NULL, что мы будем понимать как пустую строку. - static bool MakeFileKey(StandardSecurityHandler *handler, const std::wstring &ownerPassword, const std::wstring &userPassword); - - private: - - static bool MakeFileKey3(const std::string &sPassword, unsigned char *pHash, int nHashSize, unsigned char *pHash2 = NULL, int nHashSize2 = 0); - static bool MakeFileKey2(StandardSecurityHandler *handler, const std::string &userPassword); - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // DecryptStream - //------------------------------------------------------------------------------------------------------------------------------- - - class DecryptStream : public FilterStream - { - - public: - - DecryptStream(Stream *pStream, unsigned char *sFileKey, CryptAlgorithm eType, int nKeyLength, int nObjectNum, int nObjectGen); - virtual ~DecryptStream(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual int GetChar(); - virtual int LookChar(); - virtual bool IsBinary(bool bLast); - virtual Stream *getUndecodedStream() { return this; } - - private: - - CryptAlgorithm m_eCryptType; - int m_nObjectKeyLength; - unsigned char m_sObjectKey[(16 + 9) * 2]; - - unsigned char* m_pUncryptedData; - unsigned int m_pUncryptedDataSize; - unsigned int m_pUncryptedDataPosition; - }; -} - -#endif // _PDF_READER_DECRYPT_H diff --git a/PdfReader/old/Dict.cpp b/PdfReader/old/Dict.cpp deleted file mode 100644 index 843002d51b..0000000000 --- a/PdfReader/old/Dict.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "XRef.h" -#include "Dict.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Dict - //------------------------------------------------------------------------ - - Dict::Dict(XRef *pXref) - { - m_pXref = pXref; - m_arrEntries = NULL; - m_nEntriesSize = m_nEntriesCount = 0; - m_nRef = 1; - } - - Dict::~Dict() - { - for (int nIndex = 0; nIndex < m_nEntriesCount; ++nIndex) - { - MemUtilsFree(m_arrEntries[nIndex].sKey); - m_arrEntries[nIndex].oValue.Free(); - } - MemUtilsFree(m_arrEntries); - } - - void Dict::AddItem(char *sKey, Object *pValue) - { - if (m_nEntriesCount == m_nEntriesSize) - { - if (0 == m_nEntriesCount) - { - m_nEntriesSize = 8; - } - else - { - m_nEntriesSize *= 2; - } - m_arrEntries = (DictEntry *)MemUtilsReallocArray(m_arrEntries, m_nEntriesSize, sizeof(DictEntry)); - } - m_arrEntries[m_nEntriesCount].sKey = sKey; - m_arrEntries[m_nEntriesCount].oValue = *pValue; - ++m_nEntriesCount; - } - - inline DictEntry *Dict::Find(char *sKey) - { - for (int nIndex = 0; nIndex < m_nEntriesCount; ++nIndex) - { - if (!strcmp(sKey, m_arrEntries[nIndex].sKey)) - return &m_arrEntries[nIndex]; - } - return NULL; - } - - bool Dict::CheckType(char *sType) - { - DictEntry *pEntry = NULL; - - return (pEntry = Find("Type")) && pEntry->oValue.IsName(sType); - } - - Object *Dict::Search(char *sKey, Object *pObj) - { - DictEntry *pEntry = NULL; - - return (pEntry = Find(sKey)) ? pEntry->oValue.Fetch(m_pXref, pObj) : pObj->InitNull(); - } - - Object *Dict::SearchAndCopy(char *sKey, Object *pObj) - { - DictEntry *pEntry = NULL; - - return (pEntry = Find(sKey)) ? pEntry->oValue.Copy(pObj) : pObj->InitNull(); - } - - char *Dict::GetKey(int nIndex) - { - return m_arrEntries[nIndex].sKey; - } - - Object *Dict::GetValue(int nIndex, Object *pObj) - { - return m_arrEntries[nIndex].oValue.Fetch(m_pXref, pObj); - } - - Object *Dict::GetValueCopy(int nIndex, Object *pObj) - { - return m_arrEntries[nIndex].oValue.Copy(pObj); - } - - void Dict::ToXml(std::wstring &wsXml) - { - Object oTemp; - for (int nIndex = 0; nIndex < GetEntryCount(); ++nIndex) - { - char* sKey = GetKey(nIndex); - wsXml += L"<"; - Object::AppendStringToXml(wsXml, sKey); - wsXml += L">"; - GetValueCopy(nIndex, &oTemp); - oTemp.ToXml(wsXml); - oTemp.Free(); - wsXml += L""; - } - } - -} diff --git a/PdfReader/old/Dict.h b/PdfReader/old/Dict.h deleted file mode 100644 index 159b47ead5..0000000000 --- a/PdfReader/old/Dict.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_DICT_H -#define _PDF_READER_DICT_H - -#include "Object.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Dict - //------------------------------------------------------------------------ - struct DictEntry - { - char *sKey; - Object oValue; - }; - - class Dict - { - public: - - Dict(XRef *pXref); - - ~Dict(); - - // Счетчик ссылок. - int AddRef() - { - return ++m_nRef; - } - int Release() - { - return --m_nRef; - } - - - int GetEntryCount() - { - return m_nEntriesCount; - } - - // Добавляем элемент в словарь. При этом имя не копируется. - void AddItem(char *sKey, Object *pValue); - - // Проверяем тип обэекта по имени sType. - bool CheckType(char *sType); - - // Ищем элемент словаря. Возвращается указатель на объект. - Object *Search(char *sKey, Object *pObject); - // Ищем элемент словаря. Возвращается копия объекта. - Object *SearchAndCopy(char *sKey, Object *pObject); - - - char *GetKey(int nIndex); - Object *GetValue(int nIndex, Object *pObj); - Object *GetValueCopy(int nIndex, Object *pObj); - - // Устанавливаем указатель на таблицу Xref. Данная функция используется - // только в одном случае: словарь Trailer читается до таблицы Xref, поэтому - // для данного словаря этот указатель нужно устанавливать. - void SetXRef(XRef *pXref) - { - m_pXref = pXref; - } - - void ToXml(std::wstring& wsXml); - - private: - - DictEntry *Find(char *sKey); - - private: - - XRef *m_pXref; // таблица Xref текущего PDF файла - DictEntry *m_arrEntries; // Соержимое словаря - int m_nEntriesSize; // размер элемента в словаре - int m_nEntriesCount; // количество элементов в словаре - - int m_nRef; // Счетчик ссылок - }; -} - -#endif // _PDF_READER_DICT_H diff --git a/PdfReader/old/EncodingTables.h b/PdfReader/old/EncodingTables.h deleted file mode 100644 index 82905b6954..0000000000 --- a/PdfReader/old/EncodingTables.h +++ /dev/null @@ -1,1859 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_ENCODING_TABLES_H -#define _PDF_READER_ENCODING_TABLES_H - -namespace PdfReader -{ - - static char *c_arrMacRomanEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - NULL, - "Adieresis", - "Aring", - "Ccedilla", - "Eacute", - "Ntilde", - "Odieresis", - "Udieresis", - "aacute", - "agrave", - "acircumflex", - "adieresis", - "atilde", - "aring", - "ccedilla", - "eacute", - "egrave", - "ecircumflex", - "edieresis", - "iacute", - "igrave", - "icircumflex", - "idieresis", - "ntilde", - "oacute", - "ograve", - "ocircumflex", - "odieresis", - "otilde", - "uacute", - "ugrave", - "ucircumflex", - "udieresis", - "dagger", - "degree", - "cent", - "sterling", - "section", - "bullet", - "paragraph", - "germandbls", - "registered", - "copyright", - "trademark", - "acute", - "dieresis", - "notequal", - "AE", - "Oslash", - "infinity", - "plusminus", - "lessequal", - "greaterequal", - "yen", - "mu", - "partialdiff", - "summation", - "product", - "pi", - "integral", - "ordfeminine", - "ordmasculine", - "Omega", - "ae", - "oslash", - "questiondown", - "exclamdown", - "logicalnot", - "radical", - "florin", - "approxequal", - "Delta", - "guillemotleft", - "guillemotright", - "ellipsis", - "space", - "Agrave", - "Atilde", - "Otilde", - "OE", - "oe", - "endash", - "emdash", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "divide", - "lozenge", - "ydieresis", - "Ydieresis", - "fraction", - "currency", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "daggerdbl", - "periodcentered", - "quotesinglbase", - "quotedblbase", - "perthousand", - "Acircumflex", - "Ecircumflex", - "Aacute", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Oacute", - "Ocircumflex", - "apple", - "Ograve", - "Uacute", - "Ucircumflex", - "Ugrave", - "dotlessi", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron" - }; - - static char *c_arrMacExpertEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclamsmall", - "Hungarumlautsmall", - "centoldstyle", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "comma", - "hyphen", - "period", - "fraction", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "colon", - "semicolon", - NULL, - "threequartersemdash", - NULL, - "questionsmall", - NULL, - NULL, - NULL, - NULL, - "Ethsmall", - NULL, - NULL, - "onequarter", - "onehalf", - "threequarters", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "parenleftinferior", - NULL, - "parenrightinferior", - "Circumflexsmall", - "hypheninferior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - NULL, - NULL, - "asuperior", - "centsuperior", - NULL, - NULL, - NULL, - NULL, - "Aacutesmall", - "Agravesmall", - "Acircumflexsmall", - "Adieresissmall", - "Atildesmall", - "Aringsmall", - "Ccedillasmall", - "Eacutesmall", - "Egravesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Iacutesmall", - "Igravesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ntildesmall", - "Oacutesmall", - "Ogravesmall", - "Ocircumflexsmall", - "Odieresissmall", - "Otildesmall", - "Uacutesmall", - "Ugravesmall", - "Ucircumflexsmall", - "Udieresissmall", - NULL, - "eightsuperior", - "fourinferior", - "threeinferior", - "sixinferior", - "eightinferior", - "seveninferior", - "Scaronsmall", - NULL, - "centinferior", - "twoinferior", - NULL, - "Dieresissmall", - NULL, - "Caronsmall", - "osuperior", - "fiveinferior", - NULL, - "commainferior", - "periodinferior", - "Yacutesmall", - NULL, - "dollarinferior", - NULL, - NULL, - "Thornsmall", - NULL, - "nineinferior", - "zeroinferior", - "Zcaronsmall", - "AEsmall", - "Oslashsmall", - "questiondownsmall", - "oneinferior", - "Lslashsmall", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Cedillasmall", - NULL, - NULL, - NULL, - NULL, - NULL, - "OEsmall", - "figuredash", - "hyphensuperior", - NULL, - NULL, - NULL, - NULL, - "exclamdownsmall", - NULL, - "Ydieresissmall", - NULL, - "onesuperior", - "twosuperior", - "threesuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "ninesuperior", - "zerosuperior", - NULL, - "esuperior", - "rsuperior", - "tsuperior", - NULL, - NULL, - "isuperior", - "ssuperior", - "dsuperior", - NULL, - NULL, - NULL, - NULL, - NULL, - "lsuperior", - "Ogoneksmall", - "Brevesmall", - "Macronsmall", - "bsuperior", - "nsuperior", - "msuperior", - "commasuperior", - "periodsuperior", - "Dotaccentsmall", - "Ringsmall", - NULL, - NULL, - NULL, - NULL - }; - - static char *c_arrWinAnsiEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - "bullet", - "Euro", - "bullet", - "quotesinglbase", - "florin", - "quotedblbase", - "ellipsis", - "dagger", - "daggerdbl", - "circumflex", - "perthousand", - "Scaron", - "guilsinglleft", - "OE", - "bullet", - "Zcaron", - "bullet", - "bullet", - "quoteleft", - "quoteright", - "quotedblleft", - "quotedblright", - "bullet", - "endash", - "emdash", - "tilde", - "trademark", - "scaron", - "guilsinglright", - "oe", - "bullet", - "zcaron", - "Ydieresis", - "space", - "exclamdown", - "cent", - "sterling", - "currency", - "yen", - "brokenbar", - "section", - "dieresis", - "copyright", - "ordfeminine", - "guillemotleft", - "logicalnot", - "hyphen", - "registered", - "macron", - "degree", - "plusminus", - "twosuperior", - "threesuperior", - "acute", - "mu", - "paragraph", - "periodcentered", - "cedilla", - "onesuperior", - "ordmasculine", - "guillemotright", - "onequarter", - "onehalf", - "threequarters", - "questiondown", - "Agrave", - "Aacute", - "Acircumflex", - "Atilde", - "Adieresis", - "Aring", - "AE", - "Ccedilla", - "Egrave", - "Eacute", - "Ecircumflex", - "Edieresis", - "Igrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Eth", - "Ntilde", - "Ograve", - "Oacute", - "Ocircumflex", - "Otilde", - "Odieresis", - "multiply", - "Oslash", - "Ugrave", - "Uacute", - "Ucircumflex", - "Udieresis", - "Yacute", - "Thorn", - "germandbls", - "agrave", - "aacute", - "acircumflex", - "atilde", - "adieresis", - "aring", - "ae", - "ccedilla", - "egrave", - "eacute", - "ecircumflex", - "edieresis", - "igrave", - "iacute", - "icircumflex", - "idieresis", - "eth", - "ntilde", - "ograve", - "oacute", - "ocircumflex", - "otilde", - "odieresis", - "divide", - "oslash", - "ugrave", - "uacute", - "ucircumflex", - "udieresis", - "yacute", - "thorn", - "ydieresis" - }; - - static char *c_arrStandardEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - NULL, - "endash", - "dagger", - "daggerdbl", - "periodcentered", - NULL, - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - NULL, - "questiondown", - NULL, - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - NULL, - "ring", - "cedilla", - NULL, - "hungarumlaut", - "ogonek", - "caron", - "emdash", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "AE", - NULL, - "ordfeminine", - NULL, - NULL, - NULL, - NULL, - "Lslash", - "Oslash", - "OE", - "ordmasculine", - NULL, - NULL, - NULL, - NULL, - NULL, - "ae", - NULL, - NULL, - NULL, - "dotlessi", - NULL, - NULL, - "lslash", - "oslash", - "oe", - "germandbls", - NULL, - NULL, - NULL, - NULL - }; - - static char *c_arrExpertEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclamsmall", - "Hungarumlautsmall", - NULL, - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "comma", - "hyphen", - "period", - "fraction", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "colon", - "semicolon", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - NULL, - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - NULL, - NULL, - NULL, - "isuperior", - NULL, - NULL, - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - NULL, - NULL, - "rsuperior", - "ssuperior", - "tsuperior", - NULL, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "parenleftinferior", - NULL, - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - NULL, - NULL, - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - NULL, - "Dotaccentsmall", - NULL, - NULL, - "Macronsmall", - NULL, - NULL, - "figuredash", - "hypheninferior", - NULL, - NULL, - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - NULL, - NULL, - NULL, - "onequarter", - "onehalf", - "threequarters", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - NULL, - NULL, - "zerosuperior", - "onesuperior", - "twosuperior", - "threesuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall" - }; - - static char *c_arrSymbolEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclam", - "universal", - "numbersign", - "existential", - "percent", - "ampersand", - "suchthat", - "parenleft", - "parenright", - "asteriskmath", - "plus", - "comma", - "minus", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "congruent", - "Alpha", - "Beta", - "Chi", - "Delta", - "Epsilon", - "Phi", - "Gamma", - "Eta", - "Iota", - "theta1", - "Kappa", - "Lambda", - "Mu", - "Nu", - "Omicron", - "Pi", - "Theta", - "Rho", - "Sigma", - "Tau", - "Upsilon", - "sigma1", - "Omega", - "Xi", - "Psi", - "Zeta", - "bracketleft", - "therefore", - "bracketright", - "perpendicular", - "underscore", - "radicalex", - "alpha", - "beta", - "chi", - "delta", - "epsilon", - "phi", - "gamma", - "eta", - "iota", - "phi1", - "kappa", - "lambda", - "mu", - "nu", - "omicron", - "pi", - "theta", - "rho", - "sigma", - "tau", - "upsilon", - "omega1", - "omega", - "xi", - "psi", - "zeta", - "braceleft", - "bar", - "braceright", - "similar", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Upsilon1", - "minute", - "lessequal", - "fraction", - "infinity", - "florin", - "club", - "diamond", - "heart", - "spade", - "arrowboth", - "arrowleft", - "arrowup", - "arrowright", - "arrowdown", - "degree", - "plusminus", - "second", - "greaterequal", - "multiply", - "proportional", - "partialdiff", - "bullet", - "divide", - "notequal", - "equivalence", - "approxequal", - "ellipsis", - "arrowvertex", - "arrowhorizex", - "carriagereturn", - "aleph", - "Ifraktur", - "Rfraktur", - "weierstrass", - "circlemultiply", - "circleplus", - "emptyset", - "intersection", - "union", - "propersuperset", - "reflexsuperset", - "notsubset", - "propersubset", - "reflexsubset", - "element", - "notelement", - "angle", - "gradient", - "registerserif", - "copyrightserif", - "trademarkserif", - "product", - "radical", - "dotmath", - "logicalnot", - "logicaland", - "logicalor", - "arrowdblboth", - "arrowdblleft", - "arrowdblup", - "arrowdblright", - "arrowdbldown", - "lozenge", - "angleleft", - "registersans", - "copyrightsans", - "trademarksans", - "summation", - "parenlefttp", - "parenleftex", - "parenleftbt", - "bracketlefttp", - "bracketleftex", - "bracketleftbt", - "bracelefttp", - "braceleftmid", - "braceleftbt", - "braceex", - NULL, - "angleright", - "integral", - "integraltp", - "integralex", - "integralbt", - "parenrighttp", - "parenrightex", - "parenrightbt", - "bracketrighttp", - "bracketrightex", - "bracketrightbt", - "bracerighttp", - "bracerightmid", - "bracerightbt", - NULL - }; - - static char *c_arrZapfDingbatsEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "a1", - "a2", - "a202", - "a3", - "a4", - "a5", - "a119", - "a118", - "a117", - "a11", - "a12", - "a13", - "a14", - "a15", - "a16", - "a105", - "a17", - "a18", - "a19", - "a20", - "a21", - "a22", - "a23", - "a24", - "a25", - "a26", - "a27", - "a28", - "a6", - "a7", - "a8", - "a9", - "a10", - "a29", - "a30", - "a31", - "a32", - "a33", - "a34", - "a35", - "a36", - "a37", - "a38", - "a39", - "a40", - "a41", - "a42", - "a43", - "a44", - "a45", - "a46", - "a47", - "a48", - "a49", - "a50", - "a51", - "a52", - "a53", - "a54", - "a55", - "a56", - "a57", - "a58", - "a59", - "a60", - "a61", - "a62", - "a63", - "a64", - "a65", - "a66", - "a67", - "a68", - "a69", - "a70", - "a71", - "a72", - "a73", - "a74", - "a203", - "a75", - "a204", - "a76", - "a77", - "a78", - "a79", - "a81", - "a82", - "a83", - "a84", - "a97", - "a98", - "a99", - "a100", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "a101", - "a102", - "a103", - "a104", - "a106", - "a107", - "a108", - "a112", - "a111", - "a110", - "a109", - "a120", - "a121", - "a122", - "a123", - "a124", - "a125", - "a126", - "a127", - "a128", - "a129", - "a130", - "a131", - "a132", - "a133", - "a134", - "a135", - "a136", - "a137", - "a138", - "a139", - "a140", - "a141", - "a142", - "a143", - "a144", - "a145", - "a146", - "a147", - "a148", - "a149", - "a150", - "a151", - "a152", - "a153", - "a154", - "a155", - "a156", - "a157", - "a158", - "a159", - "a160", - "a161", - "a163", - "a164", - "a196", - "a165", - "a192", - "a166", - "a167", - "a168", - "a169", - "a170", - "a171", - "a172", - "a173", - "a162", - "a174", - "a175", - "a176", - "a177", - "a178", - "a179", - "a193", - "a180", - "a199", - "a181", - "a200", - "a182", - NULL, - "a201", - "a183", - "a184", - "a197", - "a185", - "a194", - "a198", - "a186", - "a195", - "a187", - "a188", - "a189", - "a190", - "a191", - NULL - }; -} - -#endif // _PDF_READER_ENCODING_TABLES_H diff --git a/PdfReader/old/ErrorConstants.h b/PdfReader/old/ErrorConstants.h deleted file mode 100644 index 37878f0937..0000000000 --- a/PdfReader/old/ErrorConstants.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_ERROR_CONSTANTS_H -#define _PDF_READER_ERROR_CONSTANTS_H - -namespace PdfReader -{ - typedef enum - { - errorNone = 0, // Нет ошибок - errorOpenFile = 1, // Ошибка при открытии PDF файла - errorBadCatalog = 2, // couldn't read the page catalog - errorDamaged = 3, // PDF файл был поврежден и его невозможно восстановить - errorEncrypted = 4, // Файл зашифрован, авторизация не пройдена - errorHighlightFile = 5, // nonexistent or invalid highlight file - errorBadPrinter = 6, // плохой принтер - errorPrinting = 7, // ошибка во время печати - errorPermission = 8, // Ошибка связанная с ограничениями наложенными на файл - errorBadPageNum = 9, // Неверное количество страниц - errorFileIO = 10, // Ошибка при чтении/записи - errorMemory = 11 // Memory exceed - } EError; -} - -#endif // _PDF_READER_ERROR_CONSTANTS_H diff --git a/PdfReader/old/ExtractImageOutputDev.cpp b/PdfReader/old/ExtractImageOutputDev.cpp deleted file mode 100644 index 07bd3227a6..0000000000 --- a/PdfReader/old/ExtractImageOutputDev.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "Constants.h" -#include "GState.h" -#include "Object.h" -#include "Stream.h" -#include "ExtractImageOutputDev.h" - -#include "../../DesktopEditor/common/File.h" - -namespace PdfReader -{ -#pragma pack(push, 1) - - struct ColorTableEntry - { - unsigned char nRed; - unsigned char nGreen; - unsigned char nBlue; - unsigned char nReserved; - }; - -#pragma pack(pop) - - typedef struct - { - unsigned short bfType; - unsigned int bfSize; - unsigned short bfReserved1; - unsigned short bfReserved2; - unsigned int bfOffBits; - } TBitmapFileHeader; - - typedef struct - { - unsigned int biSize; - int biWidth; - int biHeight; - unsigned short biPlanes; - unsigned short biBitCount; - unsigned int biCompression; - unsigned int biSizeImage; - int biXPelsPerMeter; - int biYPelsPerMeter; - unsigned int biClrUsed; - unsigned int biClrImportant; - } TBitmapInfoHeader; - - typedef struct - { - unsigned int bcSize; - unsigned short bcWidth; - unsigned short bcHeight; - unsigned short bcPlanes; - unsigned short bcBitCount; - } TBitmapCoreHeader; - - //------------------------------------------------------------------------------------------------------------------------------- - // ExtractImageOutputDev - //------------------------------------------------------------------------------------------------------------------------------- - - - ExtractImageOutputDev::ExtractImageOutputDev(GlobalParams *pGlobalParams, char *sFilePrefix, bool bDumpJPEG, bool bCountImages) - { - m_pGlobalParams = pGlobalParams; - if (sFilePrefix) - m_sFilePrefix = CopyString(sFilePrefix); - else - m_sFilePrefix = NULL; - - if (m_sFilePrefix) - m_sFileName = (char *)MemUtilsMalloc(strlen(m_sFilePrefix) + 20); - else - m_sFileName = NULL; - - m_bDumpJPEG = bDumpJPEG; - m_nImageCount = 0; - m_bValid = true; - - m_bCountImages = bCountImages; - } - - ExtractImageOutputDev::~ExtractImageOutputDev() - { - MemUtilsFree(m_sFileName); - MemUtilsFree(m_sFilePrefix); - } - - void ExtractImageOutputDev::DrawImageMask(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, bool bInvert, bool bInlineImage) - { - FILE *pFile = NULL; - - // JPEG - if (m_bDumpJPEG && pStream->GetType() == strDCT && !bInlineImage) - { - ++m_nImageCount; - if (m_bCountImages || !m_sFileName || !m_sFilePrefix) - return; - - sprintf(m_sFileName, "%s\\%04d.jpg", m_sFilePrefix, m_nImageCount); - - pFile = NSFile::CFileBinary::OpenFileNative(AStringToWString(m_sFileName), L"wb"); - if (!pFile) - { - // TO DO: Error "Couldn't open image file" - return; - } - pStream = ((DCTStream *)pStream)->GetRawStream(); - pStream->Reset(); - - // Копируем поток в файл - int nChar = 0; - while ((nChar = pStream->GetChar()) != EOF) - fputc(nChar, pFile); - - pStream->Close(); - fclose(pFile); - } - else - { - int nLeftBytes = 0; - while (div_t(div(((nWidth + 7) / 8), 4)).rem != 0) - { - nWidth -= 8; - nLeftBytes++; - if (nWidth <= 0) - { - // TO DO: Error "To small picture" - return; - } - } - - ++m_nImageCount; - if (m_bCountImages || !m_sFileName || !m_sFilePrefix) - return; - - sprintf(m_sFileName, "%s\\%04d.bmp", m_sFilePrefix, m_nImageCount); - - pFile = NSFile::CFileBinary::OpenFileNative(AStringToWString(m_sFileName), L"wb"); - if (!pFile) - { - // TO DO: Error "Couldn't open image file" - return; - } - - TBitmapFileHeader oFileHeader; - oFileHeader.bfType = 'M' * 256 + 'B'; - oFileHeader.bfSize = sizeof(TBitmapFileHeader) + sizeof(TBitmapInfoHeader) + 2 * sizeof(ColorTableEntry) + nHeight * ((nWidth + 7) / 8); - oFileHeader.bfReserved1 = 0; - oFileHeader.bfReserved2 = 0; - oFileHeader.bfOffBits = sizeof(TBitmapFileHeader) + sizeof(TBitmapInfoHeader) + 2 * sizeof(ColorTableEntry); - - - TBitmapInfoHeader oInfoHeader; - oInfoHeader.biSize = sizeof(TBitmapInfoHeader); - oInfoHeader.biWidth = nWidth; - oInfoHeader.biHeight = nHeight; - oInfoHeader.biPlanes = 1; - oInfoHeader.biBitCount = 1; - oInfoHeader.biCompression = 0; - oInfoHeader.biSizeImage = nHeight * ((nWidth + 7) / 8); - oInfoHeader.biXPelsPerMeter = 0; - oInfoHeader.biYPelsPerMeter = 0; - oInfoHeader.biClrUsed = 256; - oInfoHeader.biClrImportant = 0; - - ColorTableEntry oFirstColor, oSecondColor; - oFirstColor.nRed = 255; - oFirstColor.nGreen = 255; - oFirstColor.nBlue = 255; - oFirstColor.nReserved = 0; - - oSecondColor.nRed = 0; - oSecondColor.nGreen = 0; - oSecondColor.nBlue = 0; - oSecondColor.nReserved = 0; - - ::fwrite(&oFileHeader, 1, sizeof(TBitmapFileHeader), pFile); - ::fwrite(&oInfoHeader, 1, sizeof(TBitmapInfoHeader), pFile); - ::fwrite(&oFirstColor, 1, sizeof(ColorTableEntry), pFile); - ::fwrite(&oSecondColor, 1, sizeof(ColorTableEntry), pFile); - - long lPos = ::ftell(pFile); - - pStream->Reset(); - - // Копируем поток в файл - int nSize = nHeight * ((nWidth + 7) / 8); - - unsigned char *pBuffer = new unsigned char[nSize]; - if (!pBuffer) - { - // TO DO: Error "Not enough memory" - return; - } - unsigned char *pBufPointer = pBuffer; - for (int nY = 0; nY < nHeight; nY++) - { - for (int nX = 0; nX < (nWidth + 7) / 8; nX++, pBufPointer++) - { - *pBufPointer = pStream->GetChar() ^ 0xff; - } - for (int nIndex = 0; nIndex < nLeftBytes; nIndex++) - { - pStream->GetChar(); - } - } - pBufPointer = pBuffer; - int nStride = ((nWidth + 7) / 8); - pBufPointer += (nHeight - 1) * nStride; - nStride = -nStride; - - for (int nRow = nHeight; nRow > 0; --nRow, pBufPointer += nStride) - { - ::fwrite(pBufPointer, 1, abs(nStride), pFile); - } - pStream->Close(); - ::fclose(pFile); - delete[]pBuffer; - } - } - - void ExtractImageOutputDev::DrawImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, int *pnMaskColors, bool bInlineImage) - { - FILE *pFile = NULL; - // JPEG - if (m_bDumpJPEG && pStream->GetType() == strDCT && (pColorMap->GetComponentsCount() == 1 || pColorMap->GetComponentsCount() == 3) && !bInlineImage) - { - ++m_nImageCount; - if (m_bCountImages || !m_sFileName || !m_sFilePrefix) - return; - sprintf(m_sFileName, "%s\\%04d.jpg", m_sFilePrefix, m_nImageCount); - - pFile = NSFile::CFileBinary::OpenFileNative(AStringToWString(m_sFileName), L"wb"); - if (!pFile) - { - // TO DO: Error "Couldn't open image file" - return; - } - - pStream = ((DCTStream *)pStream)->GetRawStream(); - pStream->Reset(); - - // Копируем поток в файл - int nChar = 0; - while ((nChar = pStream->GetChar()) != EOF) - fputc(nChar, pFile); - - pStream->Close(); - fclose(pFile); - } - else if (pColorMap->GetComponentsCount() == 1 && pColorMap->GetBitsPerComponent() == 1) - { - int nLeftBytes = 0; - while (div_t(div(((nWidth + 7) / 8), 4)).rem != 0) - { - nWidth -= 8; - nLeftBytes++; - if (nWidth <= 0) - { - // TO DO: Error "To small picture" - return; - } - } - - ++m_nImageCount; - if (m_bCountImages || !m_sFileName || !m_sFilePrefix) - return; - - sprintf(m_sFileName, "%s\\%04d.bmp", m_sFilePrefix, m_nImageCount); - - pFile = NSFile::CFileBinary::OpenFileNative(AStringToWString(m_sFileName), L"wb"); - if (!pFile) - { - // TO DO: Error "Couldn't open image file" - return; - } - TBitmapFileHeader oFileHeader; - oFileHeader.bfType = 'M' * 256 + 'B'; - oFileHeader.bfSize = sizeof(TBitmapFileHeader) + sizeof(TBitmapInfoHeader) + 2 * sizeof(ColorTableEntry) + nHeight * ((nWidth + 7) / 8); - oFileHeader.bfReserved1 = 0; - oFileHeader.bfReserved2 = 0; - oFileHeader.bfOffBits = sizeof(TBitmapFileHeader) + sizeof(TBitmapInfoHeader) + 2 * sizeof(ColorTableEntry); - - - TBitmapInfoHeader oInfoHeader; - oInfoHeader.biSize = sizeof(TBitmapInfoHeader); - oInfoHeader.biWidth = nWidth; - oInfoHeader.biHeight = nHeight; - oInfoHeader.biPlanes = 1; - oInfoHeader.biBitCount = 1; - oInfoHeader.biCompression = 0; - oInfoHeader.biSizeImage = nHeight * ((nWidth + 7) / 8); - oInfoHeader.biXPelsPerMeter = 0; - oInfoHeader.biYPelsPerMeter = 0; - oInfoHeader.biClrUsed = 0; - oInfoHeader.biClrImportant = 0; - - ColorTableEntry oFirstColor, oSecondColor; - oFirstColor.nRed = 255; - oFirstColor.nGreen = 255; - oFirstColor.nBlue = 255; - oFirstColor.nReserved = 0; - - oSecondColor.nRed = 0; - oSecondColor.nGreen = 0; - oSecondColor.nBlue = 0; - oSecondColor.nReserved = 0; - - ::fwrite(&oFileHeader, 1, sizeof(TBitmapFileHeader), pFile); - ::fwrite(&oInfoHeader, 1, sizeof(TBitmapInfoHeader), pFile); - ::fwrite(&oFirstColor, 1, sizeof(ColorTableEntry), pFile); - ::fwrite(&oSecondColor, 1, sizeof(ColorTableEntry), pFile); - - pStream->Reset(); - - // Копируем поток в файл - int nSize = nHeight * ((nWidth + 7) / 8); - - unsigned char *pBuffer = new unsigned char[nSize]; - if (!pBuffer) - { - // TO DO: Error "Not enough memory" - return; - } - unsigned char *pBufPointer = pBuffer; - for (int nY = 0; nY < nHeight; nY++) - { - for (int nX = 0; nX < (nWidth + 7) / 8; nX++, pBufPointer++) - { - *pBufPointer = pStream->GetChar() ^ 0xff; - } - for (int nIndex = 0; nIndex < nLeftBytes; nIndex++) - { - pStream->GetChar(); - } - } - pBufPointer = pBuffer; - int nStride = ((nWidth + 7) / 8); - pBufPointer += (nHeight - 1) * nStride; - nStride = -nStride; - - for (int nRow = nHeight; nRow > 0; --nRow, pBufPointer += nStride) - { - ::fwrite(pBufPointer, 1, -nStride, pFile); - } - pStream->Close(); - ::fclose(pFile); - delete[]pBuffer; - } - else - { - ++m_nImageCount; - if (m_bCountImages || !m_sFileName || !m_sFilePrefix) - return; - - sprintf(m_sFileName, "%s\\%04d.bmp", m_sFilePrefix, m_nImageCount); - - pFile = NSFile::CFileBinary::OpenFileNative(AStringToWString(m_sFileName), L"wb"); - if (!pFile) - { - // TO DO: Error "Couldn't open image file" - return; - } - TBitmapFileHeader oFileHeader; - oFileHeader.bfType = 'M' * 256 + 'B'; - oFileHeader.bfSize = sizeof(TBitmapFileHeader) + sizeof(TBitmapCoreHeader) + nWidth * nHeight * 4; - oFileHeader.bfReserved1 = 0; - oFileHeader.bfReserved2 = 0; - oFileHeader.bfOffBits = sizeof(TBitmapFileHeader) + sizeof(TBitmapCoreHeader); - - TBitmapCoreHeader oCoreHeader; - oCoreHeader.bcSize = sizeof(TBitmapCoreHeader); - oCoreHeader.bcWidth = nWidth; - oCoreHeader.bcHeight = nHeight; - oCoreHeader.bcPlanes = 1; - oCoreHeader.bcBitCount = 32; - - ::fwrite(&oFileHeader, 1, sizeof(TBitmapFileHeader), pFile); - ::fwrite(&oCoreHeader, 1, sizeof(TBitmapCoreHeader), pFile); - - ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->GetComponentsCount(), pColorMap->GetBitsPerComponent()); - if (!pImageStream) - { - // TO DO: Error "Not enough memory" - return; - } - - pImageStream->Reset(); - - unsigned char *pBuffer = new unsigned char[nWidth * nHeight * 4]; - if (!pBuffer) - { - // TO DO: Error "Not enough memory" - delete pImageStream; - return; - } - - unsigned char *pBufPointer = pBuffer; - for (int nY = 0; nY < nHeight; nY++) - { - unsigned char *pImageLine = pImageStream->GetNextLine(); - for (int nX = 0; nX < nWidth; nX++, pBufPointer += 4) - { - GrRGB oRGB; - pColorMap->GetRGB(pImageLine, &oRGB); - - pBufPointer[0] = ColorToByte(oRGB.b); - pBufPointer[1] = ColorToByte(oRGB.g); - pBufPointer[2] = ColorToByte(oRGB.r); - pBufPointer[3] = 255; - - pImageLine += pColorMap->GetComponentsCount(); - } - } - delete pImageStream; - - pBufPointer = pBuffer; - int nStride = nWidth * 4; - pBufPointer += (nHeight - 1) * nStride; - nStride = -nStride; - - for (int nRow = nHeight; nRow > 0; --nRow, pBufPointer += nStride) - { - ::fwrite(pBufPointer, 1, -nStride, pFile); - } - - ::fclose(pFile); - delete[]pBuffer; - } - } -} \ No newline at end of file diff --git a/PdfReader/old/ExtractImageOutputDev.h b/PdfReader/old/ExtractImageOutputDev.h deleted file mode 100644 index 9f397cde3d..0000000000 --- a/PdfReader/old/ExtractImageOutputDev.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_EXTRACT_IMAGE_OUTPUTDEV_H -#define _PDF_READER_EXTRACT_IMAGE_OUTPUTDEV_H - -#include -#include "OutputDevice.h" - -namespace PdfReader -{ - class GrState; - - //------------------------------------------------------------------------------------------------------------------------------- - // ExtractImageOutputDev - //------------------------------------------------------------------------------------------------------------------------------- - - class ExtractImageOutputDev : public OutputDev - { - public: - - ExtractImageOutputDev(GlobalParams *pGlobalParams, char *sFilePrefix, bool bDumpJPEG, bool bCountImages = false); - - virtual ~ExtractImageOutputDev(); - - virtual bool CheckValidate() - { - return m_bValid; - } - - virtual bool InterpretType3Chars() - { - return false; - } - - virtual bool NeedNonText() - { - return true; - } - - - // Информация об устройстве. - virtual bool UpSideDown() - { - return false; - } - - virtual bool UseDrawChar() - { - return false; - } - - virtual void DrawImageMask(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, bool bInvert, bool bInlineImage); - virtual void DrawImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, int *pnMaskColors, bool bInlineImage); - - // - - int GetImagesCount() - { - return m_nImageCount; - } - - private: - - char *m_sFilePrefix; // - char *m_sFileName; // - bool m_bDumpJPEG; // - int m_nImageCount; // Текущее количество изображений - bool m_bCountImages; // Считаем картинки - - bool m_bValid; - }; -} - -#endif // _PDF_READER_EXTRACT_IMAGE_OUTPUTDEV_H diff --git a/PdfReader/old/File.h b/PdfReader/old/File.h deleted file mode 100644 index 9270852821..0000000000 --- a/PdfReader/old/File.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FILE_H -#define _PDF_READER_FILE_H - -#include -#include - -#include "StringExt.h" -#include "../../DesktopEditor/common/File.h" - -using namespace std; - -namespace PdfReader -{ - static void SpitPathExt(std::wstring& wsFullPath, std::wstring* pwsFilePath, std::wstring* pwsExt) - { - // Ищем '.' начиная с конца пути, и разделяем путь на расширение и остальную часть - unsigned int nPos = wsFullPath.find_last_of(L"."); - *pwsFilePath = wsFullPath.substr(0, nPos); - *pwsExt = wsFullPath.substr(nPos + 1); - } - static bool OpenTempFile(wstring* pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t *wsName = NULL) - { - return NSFile::CFileBinary::OpenTempFile(pwsName, ppFile, wsMode, wsExt, wsFolder, wsName); - } - static char*GetLine(char *sBuffer, int nSize, FILE *pFile) - { - int nChar, nCurIndex = 0; - - while (nCurIndex < nSize - 1) - { - if ((nChar = fgetc(pFile)) == EOF) - break; - - sBuffer[nCurIndex++] = (char)nChar; - if ('\x0a' == nChar) - { - break; - } - if ('\x0d' == nChar) - { - nChar = fgetc(pFile); - if ('\x0a' == nChar && nCurIndex < nSize - 1) - { - sBuffer[nCurIndex++] = (char)nChar; - } - else if (EOF != nChar) - { - ungetc(nChar, pFile); - } - break; - } - } - sBuffer[nCurIndex] = '\0'; - if (0 == nCurIndex) - return NULL; - return sBuffer; - } -} - -#endif // _PDF_READER_FILE_H diff --git a/PdfReader/old/FontFileBase.cpp b/PdfReader/old/FontFileBase.cpp deleted file mode 100644 index 047b9cf16f..0000000000 --- a/PdfReader/old/FontFileBase.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "MemoryUtils.h" -#include "FontFileBase.h" -#include "../../DesktopEditor/common/File.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // CFontFileBase - //------------------------------------------------------------------------ - - CFontFileBase::CFontFileBase(char *sFile, int nLen, bool bFreeFileData) - { - m_sFileData = m_sFile = (unsigned char *)sFile; - m_nLen = nLen; - m_bFreeFileData = bFreeFileData; - } - - CFontFileBase::~CFontFileBase() - { - if (m_bFreeFileData) - MemUtilsFree(m_sFileData); - } - - char *CFontFileBase::ReadFile(wchar_t *wsFileName, int *pnFileLen) - { - FILE* pFile = NSFile::CFileBinary::OpenFileNative(wsFileName, L"rb"); - if (!pFile) - return NULL; - - fseek(pFile, 0, SEEK_END); - int nLen = (int)ftell(pFile); - fseek(pFile, 0, SEEK_SET); - char *sBuffer = (char *)MemUtilsMalloc(nLen); - if ((int)fread(sBuffer, 1, nLen, pFile) != nLen) - { - MemUtilsFree(sBuffer); - fclose(pFile); - return NULL; - } - - fclose(pFile); - *pnFileLen = nLen; - return sBuffer; - } - - int CFontFileBase::GetS8(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - if (nRes & 0x80) - nRes |= ~0xff; - return nRes; - } - - int CFontFileBase::GetU8(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - if (nPos < 0 || nPos >= m_nLen) - { - *pbSuccess = false; - return 0; - } - return m_sFile[nPos]; - } - - int CFontFileBase::GetS16BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 1 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - if (nRes & 0x8000) - nRes |= ~0xffff; - return nRes; - } - - int CFontFileBase::GetU16BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 1 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - return nRes; - } - - int CFontFileBase::GetS32BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 3 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - nRes = (nRes << 8) + m_sFile[nPos + 2]; - nRes = (nRes << 8) + m_sFile[nPos + 3]; - if (nRes & 0x80000000) - nRes |= ~0xffffffff; - - return nRes; - } - - unsigned int CFontFileBase::GetU32BE(int nPos, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + 3 >= m_nLen) - { - *pbSuccess = false; - return 0; - } - unsigned int nRes = m_sFile[nPos]; - nRes = (nRes << 8) + m_sFile[nPos + 1]; - nRes = (nRes << 8) + m_sFile[nPos + 2]; - nRes = (nRes << 8) + m_sFile[nPos + 3]; - return nRes; - } - - unsigned int CFontFileBase::GetUVarBE(int nPos, int nSize, bool *pbSuccess) - { - *pbSuccess = true; - - if (nPos < 0 || nPos + nSize > m_nLen) - { - *pbSuccess = false; - return 0; - } - unsigned int nRes = 0; - for (int nIndex = 0; nIndex < nSize; ++nIndex) - nRes = (nRes << 8) + m_sFile[nPos + nIndex]; - - return nRes; - } - - bool CFontFileBase::CheckRegion(int nPos, int nSize) - { - return (nPos >= 0 && nPos + nSize >= nPos && nPos + nSize <= m_nLen); - } -} diff --git a/PdfReader/old/FontFileBase.h b/PdfReader/old/FontFileBase.h deleted file mode 100644 index 84424aaaec..0000000000 --- a/PdfReader/old/FontFileBase.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FONT_FILE_BASE_H -#define _PDF_READER_FONT_FILE_BASE_H - -namespace PdfReader -{ - typedef void(*FontFileOutputFunc)(void *pStream, char *sData, int nLen); - - //------------------------------------------------------------------------ - // CFontFileBase - //------------------------------------------------------------------------ - - class CFontFileBase - { - public: - - virtual ~CFontFileBase(); - - protected: - - CFontFileBase(char *sFile, int nLen, bool bFreeFileData); - - static char *ReadFile(wchar_t *wsFileName, int *pnFileLen); - - // S = signed / U = unsigned - // 8/16/32/Var = word length, in bytes - // BE = big endian - int GetS8(int nPos, bool *pbSuccess); - int GetU8(int nPos, bool *pbSuccess); - int GetS16BE(int nPos, bool *pbSuccess); - int GetU16BE(int nPos, bool *pbSuccess); - int GetS32BE(int nPos, bool *pbSuccess); - unsigned int GetU32BE(int nPos, bool *pbSuccess); - unsigned int GetUVarBE(int nPos, int nSize, bool *pbSuccess); - - bool CheckRegion(int nPos, int nSize); - - protected: - - unsigned char *m_sFileData; - unsigned char *m_sFile; - int m_nLen; - bool m_bFreeFileData; - - }; -} - -#endif // _PDF_READER_FONT_FILE_BASE_H diff --git a/PdfReader/old/FontFileEncodings.h b/PdfReader/old/FontFileEncodings.h deleted file mode 100644 index d4698a8160..0000000000 --- a/PdfReader/old/FontFileEncodings.h +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FONT_FILE_ENCODINGS_H -#define _PDF_READER_FONT_FILE_ENCODINGS_H - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Type 1 and 1C font data - //------------------------------------------------------------------------ - - static char *c_arrsFontFileType1StandardEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - NULL, - "endash", - "dagger", - "daggerdbl", - "periodcentered", - NULL, - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - NULL, - "questiondown", - NULL, - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - NULL, - "ring", - "cedilla", - NULL, - "hungarumlaut", - "ogonek", - "caron", - "emdash", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "AE", - NULL, - "ordfeminine", - NULL, - NULL, - NULL, - NULL, - "Lslash", - "Oslash", - "OE", - "ordmasculine", - NULL, - NULL, - NULL, - NULL, - NULL, - "ae", - NULL, - NULL, - NULL, - "dotlessi", - NULL, - NULL, - "lslash", - "oslash", - "oe", - "germandbls", - NULL, - NULL, - NULL, - NULL - }; - - static char *c_arrsFontFileType1ExpertEncoding[256] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "space", - "exclamsmall", - "Hungarumlautsmall", - NULL, - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "comma", - "hyphen", - "period", - "fraction", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "colon", - "semicolon", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - NULL, - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - NULL, - NULL, - NULL, - "isuperior", - NULL, - NULL, - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - NULL, - NULL, - "rsuperior", - "ssuperior", - "tsuperior", - NULL, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "parenleftinferior", - NULL, - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - NULL, - NULL, - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - NULL, - "Dotaccentsmall", - NULL, - NULL, - "Macronsmall", - NULL, - NULL, - "figuredash", - "hypheninferior", - NULL, - NULL, - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - NULL, - NULL, - NULL, - "onequarter", - "onehalf", - "threequarters", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - NULL, - NULL, - "zerosuperior", - "onesuperior", - "twosuperior", - "threesuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall" - }; - - - //------------------------------------------------------------------------ - // Type 1C font data - //------------------------------------------------------------------------ - - static char *c_arrsFontFileType1CStandardStrings[391] = - { - ".notdef", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "endash", - "dagger", - "daggerdbl", - "periodcentered", - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - "questiondown", - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", - "emdash", - "AE", - "ordfeminine", - "Lslash", - "Oslash", - "OE", - "ordmasculine", - "ae", - "dotlessi", - "lslash", - "oslash", - "oe", - "germandbls", - "onesuperior", - "logicalnot", - "mu", - "trademark", - "Eth", - "onehalf", - "plusminus", - "Thorn", - "onequarter", - "divide", - "brokenbar", - "degree", - "thorn", - "threequarters", - "twosuperior", - "registered", - "minus", - "eth", - "multiply", - "threesuperior", - "copyright", - "Aacute", - "Acircumflex", - "Adieresis", - "Agrave", - "Aring", - "Atilde", - "Ccedilla", - "Eacute", - "Ecircumflex", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Ntilde", - "Oacute", - "Ocircumflex", - "Odieresis", - "Ograve", - "Otilde", - "Scaron", - "Uacute", - "Ucircumflex", - "Udieresis", - "Ugrave", - "Yacute", - "Ydieresis", - "Zcaron", - "aacute", - "acircumflex", - "adieresis", - "agrave", - "aring", - "atilde", - "ccedilla", - "eacute", - "ecircumflex", - "edieresis", - "egrave", - "iacute", - "icircumflex", - "idieresis", - "igrave", - "ntilde", - "oacute", - "ocircumflex", - "odieresis", - "ograve", - "otilde", - "scaron", - "uacute", - "ucircumflex", - "udieresis", - "ugrave", - "yacute", - "ydieresis", - "zcaron", - "exclamsmall", - "Hungarumlautsmall", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - "isuperior", - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - "rsuperior", - "ssuperior", - "tsuperior", - "ff", - "ffi", - "ffl", - "parenleftinferior", - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - "Dotaccentsmall", - "Macronsmall", - "figuredash", - "hypheninferior", - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - "zerosuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall", - "001.000", - "001.001", - "001.002", - "001.003", - "Black", - "Bold", - "Book", - "Light", - "Medium", - "Regular", - "Roman", - "Semibold" - }; - - static unsigned short c_arrnFontFileType1CISOAdobeCharset[229] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228 - }; - - static unsigned short c_arrnFontFileType1CExpertCharset[166] = - { - 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, - 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378 - }; - - static unsigned short c_arrnFontFileType1CExpertSubsetCharset[87] = - { - 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, - 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, - 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, - 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346 - }; - - -} -#endif // _PDF_READER_FONT_FILE_ENCODINGS_H diff --git a/PdfReader/old/FontFileTrueType.cpp b/PdfReader/old/FontFileTrueType.cpp deleted file mode 100644 index f8262441b6..0000000000 --- a/PdfReader/old/FontFileTrueType.cpp +++ /dev/null @@ -1,2154 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "StringExt.h" -#include "Hash.h" -#include "FontFileType1C.h" -#include "FontFileTrueType.h" - -namespace PdfReader -{ - // - // Терминология - // ----------- - // - // character code = номер, используемый как элемент текстовой строки - // - // character name = glyph name = имя определенного символа фонта - // - // glyph index = GID = позиция (в предела некоторой внутренней таблицы - // в фонте), где приведены инструкции как рисовать - // данный символ - // - // Type 1 fonts - // ------------ - // - // Type 1 fonts contain: - // - // Encoding: char code -> glyph name - // - // Encoding[charCode] = charName - // - // CharStrings: dictionary of instructions, keyed by character names, - // maps character name to glyph data - // - // CharStrings[charName] = glyphData - // - // TrueType fonts - // -------------- - // - // TrueType fonts contain: - // - // 'cmap' table: character code -> GID; - // - // cmap[charCode] = gid - // - // 'post' table: GID -> glyph name - // - // post[gid] = glyphName - // - // Type 42 fonts - // ------------- - // - // Type 42 fonts contain: - // - // Encoding: char code -> glyph name - // - // Encoding[charCode] = charName - // - // CharStrings: dictionary of glyph indexes, keyed by character names, - // maps character name to glyph index - // - // CharStrings[charName] = gid - // - - //------------------------------------------------------------------------ - -#define ttcfTag 0x74746366 - - //------------------------------------------------------------------------ - - struct TrueTypeTable - { - unsigned int unTag; - unsigned int unChecksum; - int nOffset; - int nOrigOffset; - int nLen; - }; - - struct TrueTypeCmap - { - int nPlatform; - int nEncoding; - int nOffset; - int nLen; - int nFormat; - }; - - struct TrueTypeLoca - { - int nIndex; - int nOrigOffset; - int nNewOffset; - int nLen; - }; - -#define cmapTag 0x636d6170 -#define glyfTag 0x676c7966 -#define headTag 0x68656164 -#define hheaTag 0x68686561 -#define hmtxTag 0x686d7478 -#define locaTag 0x6c6f6361 -#define nameTag 0x6e616d65 -#define os2Tag 0x4f532f32 -#define postTag 0x706f7374 - - static int CompareTrueTypeLocaOffset(const void *pL1, const void *pL2) - { - TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; - TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; - - if (pLoca1->nOrigOffset == pLoca2->nOrigOffset) - return pLoca1->nIndex - pLoca2->nIndex; - - return pLoca1->nOrigOffset - pLoca2->nOrigOffset; - } - - static int CompareTrueTypeLocaIndex(const void *pL1, const void *pL2) - { - TrueTypeLoca *pLoca1 = (TrueTypeLoca *)pL1; - TrueTypeLoca *pLoca2 = (TrueTypeLoca *)pL2; - - return pLoca1->nIndex - pLoca2->nIndex; - } - - static int CompareTrueTypeTableTag(const void *pTab1, const void *pTab2) - { - TrueTypeTable *pTable1 = (TrueTypeTable *)pTab1; - TrueTypeTable *pTable2 = (TrueTypeTable *)pTab2; - - return (int)pTable1->unTag - (int)pTable2->unTag; - } - - //------------------------------------------------------------------------ - - struct T42Table - { - char *sTag; // 4-байтовое название - bool bRequired; // Требуется ли по спецификации TrueType? - }; - - // TrueType tables to be embedded in Type 42 fonts. - // NB: the table names must be in alphabetical order here. -#define nT42Tables 11 - static T42Table t42Tables[nT42Tables] = - { - { "cvt ", true }, - { "fpgm", true }, - { "glyf", true }, - { "head", true }, - { "hhea", true }, - { "hmtx", true }, - { "loca", true }, - { "maxp", true }, - { "prep", true }, - { "vhea", false }, - { "vmtx", false } - }; -#define t42HeadTable 3 -#define t42LocaTable 6 -#define t42GlyfTable 2 -#define t42VheaTable 9 -#define t42VmtxTable 10 - - //------------------------------------------------------------------------ - - // Названия символов в стандартном порядке, который использует Apple для - // своих TrueType фонтов. - static char *c_arrAppleGlyphNames[258] = - { - ".notdef", "null", "CR", "space", - "exclam", "quotedbl", "numbersign", "dollar", - "percent", "ampersand", "quotesingle", "parenleft", - "parenright", "asterisk", "plus", "comma", - "hyphen", "period", "slash", "zero", - "one", "two", "three", "four", - "five", "six", "seven", "eight", - "nine", "colon", "semicolon", "less", - "equal", "greater", "question", "at", - "A", "B", "C", "D", - "E", "F", "G", "H", - "I", "J", "K", "L", - "M", "N", "O", "P", - "Q", "R", "S", "T", - "U", "V", "W", "X", - "Y", "Z", "bracketleft", "backslash", - "bracketright", "asciicircum", "underscore", "grave", - "a", "b", "c", "d", - "e", "f", "g", "h", - "i", "j", "k", "l", - "m", "n", "o", "p", - "q", "r", "s", "t", - "u", "v", "w", "x", - "y", "z", "braceleft", "bar", - "braceright", "asciitilde", "Adieresis", "Aring", - "Ccedilla", "Eacute", "Ntilde", "Odieresis", - "Udieresis", "aacute", "agrave", "acircumflex", - "adieresis", "atilde", "aring", "ccedilla", - "eacute", "egrave", "ecircumflex", "edieresis", - "iacute", "igrave", "icircumflex", "idieresis", - "ntilde", "oacute", "ograve", "ocircumflex", - "odieresis", "otilde", "uacute", "ugrave", - "ucircumflex", "udieresis", "dagger", "degree", - "cent", "sterling", "section", "bullet", - "paragraph", "germandbls", "registered", "copyright", - "trademark", "acute", "dieresis", "notequal", - "AE", "Oslash", "infinity", "plusminus", - "lessequal", "greaterequal", "yen", "mu1", - "partialdiff", "summation", "product", "pi", - "integral", "ordfeminine", "ordmasculine", "Ohm", - "ae", "oslash", "questiondown", "exclamdown", - "logicalnot", "radical", "florin", "approxequal", - "increment", "guillemotleft", "guillemotright", "ellipsis", - "nbspace", "Agrave", "Atilde", "Otilde", - "OE", "oe", "endash", "emdash", - "quotedblleft", "quotedblright", "quoteleft", "quoteright", - "divide", "lozenge", "ydieresis", "Ydieresis", - "fraction", "currency", "guilsinglleft", "guilsinglright", - "fi", "fl", "daggerdbl", "periodcentered", - "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", - "Ecircumflex", "Aacute", "Edieresis", "Egrave", - "Iacute", "Icircumflex", "Idieresis", "Igrave", - "Oacute", "Ocircumflex", "applelogo", "Ograve", - "Uacute", "Ucircumflex", "Ugrave", "dotlessi", - "circumflex", "tilde", "overscore", "breve", - "dotaccent", "ring", "cedilla", "hungarumlaut", - "ogonek", "caron", "Lslash", "lslash", - "Scaron", "scaron", "Zcaron", "zcaron", - "brokenbar", "Eth", "eth", "Yacute", - "yacute", "Thorn", "thorn", "minus", - "multiply", "onesuperior", "twosuperior", "threesuperior", - "onehalf", "onequarter", "threequarters", "franc", - "Gbreve", "gbreve", "Idot", "Scedilla", - "scedilla", "Cacute", "cacute", "Ccaron", - "ccaron", "dmacron" - }; - - //------------------------------------------------------------------------ - // CFontFileTrueType - //------------------------------------------------------------------------ - - CFontFileTrueType *CFontFileTrueType::LoadFromBuffer(char *sBuffer, int nLen) - { - CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, false); - if (!pTTF->m_bSuccess) - { - delete pTTF; - return NULL; - } - return pTTF; - } - - CFontFileTrueType *CFontFileTrueType::LoadFromFile(wchar_t *wsFileName) - { - char *sBuffer; - int nLen = 0; - - if (!(sBuffer = CFontFileBase::ReadFile(wsFileName, &nLen))) - return NULL; - - CFontFileTrueType *pTTF = new CFontFileTrueType(sBuffer, nLen, true); - if (!pTTF->m_bSuccess) - { - delete pTTF; - return NULL; - } - return pTTF; - } - - CFontFileTrueType::CFontFileTrueType(char *sBuffer, int nLen, bool bFreeFileData) : - CFontFileBase(sBuffer, nLen, bFreeFileData) - { - m_pTables = NULL; - m_nTablesCount = 0; - m_pCMaps = NULL; - m_nCMapsCount = 0; - m_pNameToGID = NULL; - m_bSuccess = false; - - Parse(); - } - - CFontFileTrueType::~CFontFileTrueType() - { - MemUtilsFree(m_pTables); - MemUtilsFree(m_pCMaps); - if (m_pNameToGID) - delete m_pNameToGID; - } - - int CFontFileTrueType::GetCmapsCount() - { - return m_nCMapsCount; - } - - int CFontFileTrueType::GetCmapPlatform(int nIndex) - { - return m_pCMaps[nIndex].nPlatform; - } - - int CFontFileTrueType::GetCmapEncoding(int nIndex) - { - return m_pCMaps[nIndex].nEncoding; - } - - int CFontFileTrueType::FindCmap(int nPlatform, int nEncoding) - { - for (int nIndex = 0; nIndex < m_nCMapsCount; ++nIndex) - { - if (m_pCMaps[nIndex].nPlatform == nPlatform && m_pCMaps[nIndex].nEncoding == nEncoding) - return nIndex; - } - return -1; - } - - unsigned short CFontFileTrueType::MapCodeToGID(int nCMapIndex, int nChar) - { - unsigned short unGid = 0; - int nSegmentCount = 0, nSegmentEnd = 0, nSegmentStart = 0, nSegmentDelta = 0, nSegmentOffset = 0; - int nCMapFirst = 0, nCMapLen = 0; - int a, b, m; - bool bSuccess = true; - - if (nCMapIndex < 0 || nCMapIndex >= m_nCMapsCount) - return 0; - - int nPos = m_pCMaps[nCMapIndex].nOffset; - switch (m_pCMaps[nCMapIndex].nFormat) - { - case 0: - if (nChar < 0 || nChar >= m_pCMaps[nCMapIndex].nLen - 6) - return 0; - unGid = GetU8(m_pCMaps[nCMapIndex].nOffset + 6 + nChar, &bSuccess); - break; - case 4: - nSegmentCount = GetU16BE(nPos + 6, &bSuccess) / 2; - a = -1; - b = nSegmentCount - 1; - nSegmentEnd = GetU16BE(nPos + 14 + 2 * b, &bSuccess); - if (nChar > nSegmentEnd) - return 0; - - while (b - a > 1 && bSuccess) - { - m = (a + b) / 2; - nSegmentEnd = GetU16BE(nPos + 14 + 2 * m, &bSuccess); - if (nSegmentEnd < nChar) - { - a = m; - } - else - { - b = m; - } - } - nSegmentStart = GetU16BE(nPos + 16 + 2 * nSegmentCount + 2 * b, &bSuccess); - nSegmentDelta = GetU16BE(nPos + 16 + 4 * nSegmentCount + 2 * b, &bSuccess); - nSegmentOffset = GetU16BE(nPos + 16 + 6 * nSegmentCount + 2 * b, &bSuccess); - if (nChar < nSegmentStart) - return 0; - if (0 == nSegmentOffset) - { - unGid = (nChar + nSegmentDelta) & 0xffff; - } - else - { - unGid = GetU16BE(nPos + 16 + 6 * nSegmentCount + 2 * b + nSegmentOffset + 2 * (nChar - nSegmentStart), &bSuccess); - if (0 != unGid) - unGid = (unGid + nSegmentDelta) & 0xffff; - } - break; - case 6: - nCMapFirst = GetU16BE(nPos + 6, &bSuccess); - nCMapLen = GetU16BE(nPos + 8, &bSuccess); - if (nChar < nCMapFirst || nChar >= nCMapFirst + nCMapLen) - return 0; - unGid = GetU16BE(nPos + 10 + 2 * (nChar - nCMapFirst), &bSuccess); - break; - default: - return 0; - } - - if (!bSuccess) - return 0; - - return unGid; - } - - int CFontFileTrueType::MapNameToGID(char *sName) - { - if (!m_pNameToGID) - return 0; - - return m_pNameToGID->LookupInt(sName); - } - - unsigned short *CFontFileTrueType::GetCIDToGIDMap(int *pnCIDs) - { - CFontFileType1C *pC1FF; - - *pnCIDs = 0; - if (!m_bOpenTypeCFF) - return NULL; - - int nIndex = SeekTable("CFF "); - - if (!CheckRegion(m_pTables[nIndex].nOffset, m_pTables[nIndex].nLen)) - return NULL; - - if (!(pC1FF = CFontFileType1C::LoadFromBuffer((char *)m_sFile + m_pTables[nIndex].nOffset, m_pTables[nIndex].nLen))) - return NULL; - - unsigned short *pMap = pC1FF->GetCIDToGIDMap(pnCIDs); - delete pC1FF; - return pMap; - } - - int CFontFileTrueType::GetEmbeddingRestrictions() - { - int nIndex = -1; - - if ((nIndex = SeekTable("OS/2")) < 0) - return 4; - - bool bSuccess = true; - int nType = GetU16BE(m_pTables[nIndex].nOffset + 8, &bSuccess); - - if (!bSuccess) - return 4; - - if (0x0008 & nType) - return 2; - - if (0x0004 & nType) - return 1; - if (0x0002 & nType) - return 0; - - return 3; - } - - void CFontFileTrueType::ToType42(char *sPSName, char **ppEncoding, unsigned short *pCodeToGID, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - StringExt *seBuffer; - - if (m_bOpenTypeCFF) - return; - - // пишем заголовок - bool bSuccess = true; - seBuffer = StringExt::Format("%!PS-TrueTypeFont-{0:2g}\n", (double)GetS32BE(0, &bSuccess) / 65536.0); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "10 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, " def\n", 5); - (*pOutputFunc)(pOutputStream, "/FontType 42 def\n", 17); - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - seBuffer = StringExt::Format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n", m_arrBBox[0], m_arrBBox[1], m_arrBBox[2], m_arrBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, "/PaintType 0 def\n", 17); - - // записываем содержимое библиотеки шрифта - ConvertEncoding(ppEncoding, pOutputFunc, pOutputStream); - ConvertCharStrings(ppEncoding, pCodeToGID, pOutputFunc, pOutputStream); - ConvertSfnts(pOutputFunc, pOutputStream, NULL, false); - - // закончили запись библиотеки - (*pOutputFunc)(pOutputStream, "FontName currentdict end definefont pop\n", 40); - } - - void CFontFileTrueType::ToType1(char *sPSName, char **ppNewEncoding, bool bASKII, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - CFontFileType1C *pT1CFF; - - if (!m_bOpenTypeCFF) - return; - - int nTableIndex = SeekTable("CFF "); - if (!CheckRegion(m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen)) - return; - - if (!(pT1CFF = CFontFileType1C::LoadFromBuffer((char *)m_sFile + m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen))) - return; - - pT1CFF->ToType1(sPSName, ppNewEncoding, bASKII, pOutputFunc, pOutputStream); - delete pT1CFF; - } - - void CFontFileTrueType::ToCIDType2(char *sPSName, unsigned short *pCIDMap, int nCIDCount, bool bNeedVerticalMetrics, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - unsigned short nCID = 0; - - if (m_bOpenTypeCFF) - return; - - // write the header - bool bSuccess = true; - StringExt *seBuffer = StringExt::Format("%!PS-TrueTypeFont-{0:2g}\n", (double)GetS32BE(0, &bSuccess) / 65536.0); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - // begin the font dictionary - (*pOutputFunc)(pOutputStream, "20 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/CIDFontName /", 14); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, " def\n", 5); - (*pOutputFunc)(pOutputStream, "/CIDFontType 2 def\n", 19); - (*pOutputFunc)(pOutputStream, "/FontType 42 def\n", 17); - (*pOutputFunc)(pOutputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); - (*pOutputFunc)(pOutputStream, " /Registry (Adobe) def\n", 24); - (*pOutputFunc)(pOutputStream, " /Ordering (Identity) def\n", 27); - (*pOutputFunc)(pOutputStream, " /Supplement 0 def\n", 20); - (*pOutputFunc)(pOutputStream, " end def\n", 10); - (*pOutputFunc)(pOutputStream, "/GDBytes 2 def\n", 15); - if (pCIDMap) - { - seBuffer = StringExt::Format("/CIDCount {0:d} def\n", nCIDCount); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - if (nCIDCount > 32767) - { - (*pOutputFunc)(pOutputStream, "/CIDMap [", 9); - for (int nI = 0; nI < nCIDCount; nI += 32768 - 16) - { - (*pOutputFunc)(pOutputStream, "<\n", 2); - for (int nJ = 0; nJ < 32768 - 16 && nI + nJ < nCIDCount; nJ += 16) - { - (*pOutputFunc)(pOutputStream, " ", 2); - for (int nK = 0; nK < 16 && nI + nJ + nK < nCIDCount; ++nK) - { - nCID = pCIDMap[nI + nJ + nK]; - seBuffer = StringExt::Format("{0:02x}{1:02x}", (nCID >> 8) & 0xff, nCID & 0xff); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "\n", 1); - } - (*pOutputFunc)(pOutputStream, " >", 3); - } - (*pOutputFunc)(pOutputStream, "\n", 1); - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - else - { - (*pOutputFunc)(pOutputStream, "/CIDMap <\n", 10); - for (int nI = 0; nI < nCIDCount; nI += 16) - { - (*pOutputFunc)(pOutputStream, " ", 2); - for (int nJ = 0; nJ < 16 && nI + nJ < nCIDCount; ++nJ) - { - nCID = pCIDMap[nI + nJ]; - seBuffer = StringExt::Format("{0:02x}{1:02x}", (nCID >> 8) & 0xff, nCID & 0xff); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "\n", 1); - } - (*pOutputFunc)(pOutputStream, "> def\n", 6); - } - } - else - { - // direct mapping - just fill the string(s) with s[i]=i - seBuffer = StringExt::Format("/CIDCount {0:d} def\n", m_nGlyphs); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - if (m_nGlyphs > 32767) - { - (*pOutputFunc)(pOutputStream, "/CIDMap [\n", 10); - for (int nI = 0; nI < m_nGlyphs; nI += 32767) - { - int nTemp = m_nGlyphs - nI < 32767 ? m_nGlyphs - nI : 32767; - seBuffer = StringExt::Format(" {0:d} string 0 1 {1:d} {{\n", 2 * nTemp, nTemp - 1); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - seBuffer = StringExt::Format(" 2 copy dup 2 mul exch {0:d} add -8 bitshift put\n", nI); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - seBuffer = StringExt::Format(" 1 index exch dup 2 mul 1 add exch {0:d} add 255 and put\n", nI); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, " } for\n", 8); - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - else - { - seBuffer = StringExt::Format("/CIDMap {0:d} string\n", 2 * m_nGlyphs); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - seBuffer = StringExt::Format(" 0 1 {0:d} {{\n", m_nGlyphs - 1); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, " 2 copy dup 2 mul exch -8 bitshift put\n", 42); - (*pOutputFunc)(pOutputStream, " 1 index exch dup 2 mul 1 add exch 255 and put\n", 50); - (*pOutputFunc)(pOutputStream, " } for\n", 8); - (*pOutputFunc)(pOutputStream, "def\n", 4); - } - } - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - seBuffer = StringExt::Format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n", m_arrBBox[0], m_arrBBox[1], m_arrBBox[2], m_arrBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, "/PaintType 0 def\n", 17); - (*pOutputFunc)(pOutputStream, "/Encoding [] readonly def\n", 26); - (*pOutputFunc)(pOutputStream, "/CharStrings 1 dict dup begin\n", 30); - (*pOutputFunc)(pOutputStream, " /.notdef 0 def\n", 17); - (*pOutputFunc)(pOutputStream, " end readonly def\n", 19); - - // write the guts of the dictionary - ConvertSfnts(pOutputFunc, pOutputStream, NULL, bNeedVerticalMetrics); - - // end the dictionary and define the font - (*pOutputFunc)(pOutputStream, "CIDFontName currentdict end /CIDFont defineresource pop\n", 56); - } - - void CFontFileTrueType::ToCIDType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - CFontFileType1C *pT1CFF; - - if (!m_bOpenTypeCFF) - return; - - int nTableIndex = SeekTable("CFF "); - if (!CheckRegion(m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen)) - return; - - if (!(pT1CFF = CFontFileType1C::LoadFromBuffer((char *)m_sFile + m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen))) - return; - - pT1CFF->ToCIDType0(sPSName, pOutputFunc, pOutputStream); - delete pT1CFF; - } - - void CFontFileTrueType::ToType0(char *sPSName, unsigned short *pCIDMap, int nCIDCount, bool bNeedVerticalMetrics, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - StringExt *seBuffer; - - if (m_bOpenTypeCFF) - return; - - // write the Type 42 sfnts array - StringExt *seSfntsName = (new StringExt(sPSName))->Append("_sfnts"); - ConvertSfnts(pOutputFunc, pOutputStream, seSfntsName, bNeedVerticalMetrics); - delete seSfntsName; - - // write the descendant Type 42 fonts - int nCount = pCIDMap ? nCIDCount : m_nGlyphs; - for (int nIndex = 0; nIndex < nCount; nIndex += 256) - { - (*pOutputFunc)(pOutputStream, "10 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - seBuffer = StringExt::Format("_{0:02x} def\n", nIndex >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, "/FontType 42 def\n", 17); - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - seBuffer = StringExt::Format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n", m_arrBBox[0], m_arrBBox[1], m_arrBBox[2], m_arrBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, "/PaintType 0 def\n", 17); - (*pOutputFunc)(pOutputStream, "/sfnts ", 7); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, "_sfnts def\n", 11); - (*pOutputFunc)(pOutputStream, "/Encoding 256 array\n", 20); - for (int nJ = 0; nJ < 256 && nIndex + nJ < nCount; ++nJ) - { - seBuffer = StringExt::Format("dup {0:d} /c{1:02x} put\n", nJ, nJ); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "readonly def\n", 13); - (*pOutputFunc)(pOutputStream, "/CharStrings 257 dict dup begin\n", 32); - (*pOutputFunc)(pOutputStream, "/.notdef 0 def\n", 15); - for (int nJ = 0; nJ < 256 && nIndex + nJ < nCount; ++nJ) - { - seBuffer = StringExt::Format("/c{0:02x} {1:d} def\n", nJ, pCIDMap ? pCIDMap[nIndex + nJ] : nIndex + nJ); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "end readonly def\n", 17); - (*pOutputFunc)(pOutputStream, - "FontName currentdict end definefont pop\n", 40); - } - - // write the Type 0 parent font - (*pOutputFunc)(pOutputStream, "16 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, " def\n", 5); - (*pOutputFunc)(pOutputStream, "/FontType 0 def\n", 16); - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - (*pOutputFunc)(pOutputStream, "/FMapType 2 def\n", 16); - (*pOutputFunc)(pOutputStream, "/Encoding [\n", 12); - for (int nIndex = 0; nIndex < nCount; nIndex += 256) - { - seBuffer = StringExt::Format("{0:d}\n", nIndex >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - (*pOutputFunc)(pOutputStream, "/FDepVector [\n", 14); - for (int nIndex =0; nIndex < nCount; nIndex += 256) - { - (*pOutputFunc)(pOutputStream, "/", 1); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - seBuffer = StringExt::Format("_{0:02x} findfont\n", nIndex >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - (*pOutputFunc)(pOutputStream, "FontName currentdict end definefont pop\n", 40); - } - - void CFontFileTrueType::ToType0(char *psName, FontFileOutputFunc outputFunc, void *outputStream) - { - CFontFileType1C *pT1CFF; - - if (!m_bOpenTypeCFF) - return; - - int nTableIndex = SeekTable("CFF "); - if (!CheckRegion(m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen)) - return; - - if (!(pT1CFF = CFontFileType1C::LoadFromBuffer((char *)m_sFile + m_pTables[nTableIndex].nOffset, m_pTables[nTableIndex].nLen))) - return; - - pT1CFF->ToType0(psName, outputFunc, outputStream); - delete pT1CFF; - } - - void CFontFileTrueType::WriteTTF(FontFileOutputFunc pOutputFunc, void *pOutputStream, char *sName, unsigned short *pCodeToGID) - { - static char arrCMapTab[36] = - { - 0, 0, // table version number - 0, 1, // number of encoding tables - 0, 1, // platform ID - 0, 0, // encoding ID - 0, 0, 0, 12, // offset of subtable - 0, 4, // subtable format - 0, 24, // subtable length - 0, 0, // subtable version - 0, 2, // segment count * 2 - 0, 2, // 2 * 2 ^ floor(log2(segCount)) - 0, 0, // floor(log2(segCount)) - 0, 0, // 2*segCount - 2*2^floor(log2(segCount)) - (char)0xff, (char)0xff, // endCount[0] - 0, 0, // reserved - 0, 0, // startCount[0] - 0, 0, // idDelta[0] - 0, 0 // pad to a mulitple of four bytes - }; - - static char arrNameTab[8] = - { - 0, 0, // format - 0, 0, // number of name records - 0, 6, // offset to start of string storage - 0, 0 // pad to multiple of four bytes - }; - static char arrPostTab[32] = - { - 0, 1, 0, 0, // format - 0, 0, 0, 0, // italic angle - 0, 0, // underline position - 0, 0, // underline thickness - 0, 0, 0, 0, // fixed pitch - 0, 0, 0, 0, // min Type 42 memory - 0, 0, 0, 0, // max Type 42 memory - 0, 0, 0, 0, // min Type 1 memory - 0, 0, 0, 0 // max Type 1 memory - }; - static char arrOS2Tab[86] = - { - 0, 1, // version - 0, 1, // xAvgCharWidth - 0, 0, // usWeightClass - 0, 0, // usWidthClass - 0, 0, // fsType - 0, 0, // ySubscriptXSize - 0, 0, // ySubscriptYSize - 0, 0, // ySubscriptXOffset - 0, 0, // ySubscriptYOffset - 0, 0, // ySuperscriptXSize - 0, 0, // ySuperscriptYSize - 0, 0, // ySuperscriptXOffset - 0, 0, // ySuperscriptYOffset - 0, 0, // yStrikeoutSize - 0, 0, // yStrikeoutPosition - 0, 0, // sFamilyClass - 0, 0, 0, 0, 0, // panose - 0, 0, 0, 0, 0, - 0, 0, 0, 0, // ulUnicodeRange1 - 0, 0, 0, 0, // ulUnicodeRange2 - 0, 0, 0, 0, // ulUnicodeRange3 - 0, 0, 0, 0, // ulUnicodeRange4 - 0, 0, 0, 0, // achVendID - 0, 0, // fsSelection - 0, 0, // usFirstCharIndex - 0, 0, // usLastCharIndex - 0, 0, // sTypoAscender - 0, 0, // sTypoDescender - 0, 0, // sTypoLineGap - 0, 0, // usWinAscent - 0, 0, // usWinDescent - 0, 0, 0, 0, // ulCodePageRange1 - 0, 0, 0, 0 // ulCodePageRange2 - }; - bool badCmapLen, abbrevHMTX; - - int nZeroLengthTables; - int nHMetrics, nAdvWidth, nLeftSideBearing; - TrueTypeTable *pNewTables; - char *arrNewNameTable, *arrNewCmapTable, *arrNewHHEATable, *arrNewHMTXTable; - int nNewTables, nCmapIndex, nCmapLen, nGlyphLen, nNewNameLen, nNewCmapLen, nNext; - int nNewHHEALen, nNewHMTXLen; - unsigned int nLocaChecksum, nGlyphChecksum, nFileChecksum; - char *arrTableDir; - char arrLocaBuf[4], arrChecksumBuf[4]; - unsigned int t; - int nPos = 0, i, j, k, n; - - if (m_bOpenTypeCFF) - return; - - // check for missing tables - // (Note: if the OS/2 table is missing, the Microsoft PCL5 driver - // will embed a PCL TrueType font with the pitch field set to zero, - // which apparently causes divide-by-zero errors. As far as I can - // tell, the only important field in the OS/2 table is - // xAvgCharWidth.) - bool bMissingCmap = (nCmapIndex = SeekTable("cmap")) < 0; - bool bMissingName = SeekTable("name") < 0; - bool bMissingPost = SeekTable("post") < 0; - bool bMissingOS2 = SeekTable("OS/2") < 0; - - TrueTypeLoca *pLocaTable = (TrueTypeLoca *)MemUtilsMallocArray(m_nGlyphs + 1, sizeof(TrueTypeLoca)); - bool bUnsortedLoca = false; - i = SeekTable("loca"); - nPos = m_pTables[i].nOffset; - bool bSuccess = true; - for (i = 0; i <= m_nGlyphs; ++i) - { - if (m_nLocaFormat) - { - pLocaTable[i].nOrigOffset = (int)GetU32BE(nPos + i * 4, &bSuccess); - } - else - { - pLocaTable[i].nOrigOffset = 2 * GetU16BE(nPos + i * 2, &bSuccess); - } - if (i > 0 && pLocaTable[i].nOrigOffset < pLocaTable[i - 1].nOrigOffset) - { - bUnsortedLoca = true; - } - // glyph descriptions must be at least 12 bytes long (nContours, - // xMin, yMin, xMax, yMax, instructionLength - two bytes each); - // invalid glyph descriptions (even if they're never used) make - // Windows choke, so we work around that problem here (ideally, - // this would parse the glyph descriptions in the glyf table and - // remove any that were invalid, but this quick test is a decent - // start) - if (i > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset > 0 && pLocaTable[i].nOrigOffset - pLocaTable[i - 1].nOrigOffset < 12) - { - pLocaTable[i - 1].nOrigOffset = pLocaTable[i].nOrigOffset; - bUnsortedLoca = true; - } - pLocaTable[i].nIndex = i; - } - - // check for zero-length tables - nZeroLengthTables = 0; - for (i = 0; i < m_nTablesCount; ++i) - { - if (m_pTables[i].nLen == 0) - ++nZeroLengthTables; - } - - // check for an incorrect cmap table length - badCmapLen = false; - nCmapLen = 0; - if (!bMissingCmap) - { - nCmapLen = m_pCMaps[0].nOffset + m_pCMaps[0].nLen; - for (i = 1; i < m_nCMapsCount; ++i) - { - if (m_pCMaps[i].nOffset + m_pCMaps[i].nLen > nCmapLen) - { - nCmapLen = m_pCMaps[i].nOffset + m_pCMaps[i].nLen; - } - } - nCmapLen -= m_pTables[nCmapIndex].nOffset; - if (nCmapLen > m_pTables[nCmapIndex].nLen) - { - badCmapLen = true; - } - } - - // check for an abbreviated hmtx table (this is completely legal, - // but confuses the Microsoft PCL5 printer driver, which generates - // embedded fonts with the pitch field set to zero) - i = SeekTable("hhea"); - nHMetrics = GetU16BE(m_pTables[i].nOffset + 34, &bSuccess); - abbrevHMTX = nHMetrics < m_nGlyphs; - - // if nothing is broken, just write the TTF file as is - if (!bMissingCmap && !bMissingName && !bMissingPost && !bMissingOS2 && !bUnsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 && !sName && !pCodeToGID) - { - (*pOutputFunc)(pOutputStream, (char *)m_sFile, m_nLen); - MemUtilsFree(pLocaTable); - return; - } - - // sort the 'loca' table: some (non-compliant) fonts have - // out-of-order loca tables; in order to correctly handle the case - // where (compliant) fonts have empty entries in the middle of the - // table, cmpTrueTypeLocaOffset uses offset as its primary sort key, - // and idx as its secondary key (ensuring that adjacent entries with - // the same pos value remain in the same order) - nGlyphLen = 0; - if (bUnsortedLoca) - { - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaOffset); - for (i = 0; i < m_nGlyphs; ++i) - { - pLocaTable[i].nLen = pLocaTable[i + 1].nOrigOffset - pLocaTable[i].nOrigOffset; - } - pLocaTable[m_nGlyphs].nLen = 0; - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); - nPos = 0; - - for (i = 0; i <= m_nGlyphs; ++i) - { - pLocaTable[i].nNewOffset = nPos; - nPos += pLocaTable[i].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - nGlyphLen = nPos; - } - - // compute checksums for the loca and glyf tables - nLocaChecksum = nGlyphChecksum = 0; - if (bUnsortedLoca) - { - if (m_nLocaFormat) - { - for (j = 0; j <= m_nGlyphs; ++j) - { - nLocaChecksum += pLocaTable[j].nNewOffset; - } - } - else - { - for (j = 0; j <= m_nGlyphs; j += 2) - { - nLocaChecksum += pLocaTable[j].nNewOffset << 16; - if (j + 1 <= m_nGlyphs) - { - nLocaChecksum += pLocaTable[j + 1].nNewOffset; - } - } - } - nPos = m_pTables[SeekTable("glyf")].nOffset; - for (j = 0; j < m_nGlyphs; ++j) - { - n = pLocaTable[j].nLen; - if (n > 0) - { - k = pLocaTable[j].nOrigOffset; - if (CheckRegion(nPos + k, n)) - { - nGlyphChecksum += ComputeTableChecksum(m_sFile + nPos + k, n); - } - } - } - } - - // construct the new name table - if (sName) - { - n = strlen(sName); - nNewNameLen = (6 + 4 * 12 + 2 * (3 * n + 7) + 3) & ~3; - arrNewNameTable = (char *)MemUtilsMalloc(nNewNameLen); - memset(arrNewNameTable, 0, nNewNameLen); - arrNewNameTable[0] = 0; // format selector - arrNewNameTable[1] = 0; - arrNewNameTable[2] = 0; // number of name records - arrNewNameTable[3] = 4; - arrNewNameTable[4] = 0; // offset to start of string storage - arrNewNameTable[5] = 6 + 4 * 12; - nNext = 0; - for (i = 0; i < 4; ++i) - { - arrNewNameTable[6 + i * 12 + 0] = 0; // platform ID = Microsoft - arrNewNameTable[6 + i * 12 + 1] = 3; - arrNewNameTable[6 + i * 12 + 2] = 0; // encoding ID = Unicode - arrNewNameTable[6 + i * 12 + 3] = 1; - arrNewNameTable[6 + i * 12 + 4] = 0x04; // language ID = American English - arrNewNameTable[6 + i * 12 + 5] = 0x09; - arrNewNameTable[6 + i * 12 + 6] = 0; // name ID - arrNewNameTable[6 + i * 12 + 7] = i + 1; - arrNewNameTable[6 + i * 12 + 8] = i + 1 == 2 ? 0 : ((2 * n) >> 8); // string length - arrNewNameTable[6 + i * 12 + 9] = i + 1 == 2 ? 14 : ((2 * n) & 0xff); - arrNewNameTable[6 + i * 12 + 10] = nNext >> 8; // string offset - arrNewNameTable[6 + i * 12 + 11] = nNext & 0xff; - if (i + 1 == 2) - { - memcpy(arrNewNameTable + 6 + 4 * 12 + nNext, "\0R\0e\0g\0u\0l\0a\0r", 14); - nNext += 14; - } - else - { - for (j = 0; j < n; ++j) - { - arrNewNameTable[6 + 4 * 12 + nNext + 2 * j] = 0; - arrNewNameTable[6 + 4 * 12 + nNext + 2 * j + 1] = sName[j]; - } - nNext += 2 * n; - } - } - } - else - { - nNewNameLen = 0; - arrNewNameTable = NULL; - } - - // construct the new cmap table - if (pCodeToGID) - { - nNewCmapLen = 44 + 256 * 2; - arrNewCmapTable = (char *)MemUtilsMalloc(nNewCmapLen); - arrNewCmapTable[0] = 0; // table version number = 0 - arrNewCmapTable[1] = 0; - arrNewCmapTable[2] = 0; // number of encoding tables = 1 - arrNewCmapTable[3] = 1; - arrNewCmapTable[4] = 0; // platform ID = Microsoft - arrNewCmapTable[5] = 3; - arrNewCmapTable[6] = 0; // encoding ID = Unicode - arrNewCmapTable[7] = 1; - arrNewCmapTable[8] = 0; // offset of subtable - arrNewCmapTable[9] = 0; - arrNewCmapTable[10] = 0; - arrNewCmapTable[11] = 12; - arrNewCmapTable[12] = 0; // subtable format = 4 - arrNewCmapTable[13] = 4; - arrNewCmapTable[14] = 0x02; // subtable length - arrNewCmapTable[15] = 0x20; - arrNewCmapTable[16] = 0; // subtable version = 0 - arrNewCmapTable[17] = 0; - arrNewCmapTable[18] = 0; // segment count * 2 - arrNewCmapTable[19] = 4; - arrNewCmapTable[20] = 0; // 2 * 2 ^ floor(log2(segCount)) - arrNewCmapTable[21] = 4; - arrNewCmapTable[22] = 0; // floor(log2(segCount)) - arrNewCmapTable[23] = 1; - arrNewCmapTable[24] = 0; // 2*segCount - 2*2^floor(log2(segCount)) - arrNewCmapTable[25] = 0; - arrNewCmapTable[26] = 0x00; // endCount[0] - arrNewCmapTable[27] = (char)0xff; - arrNewCmapTable[28] = (char)0xff; // endCount[1] - arrNewCmapTable[29] = (char)0xff; - arrNewCmapTable[30] = 0; // reserved - arrNewCmapTable[31] = 0; - arrNewCmapTable[32] = 0x00; // startCount[0] - arrNewCmapTable[33] = 0x00; - arrNewCmapTable[34] = (char)0xff; // startCount[1] - arrNewCmapTable[35] = (char)0xff; - arrNewCmapTable[36] = 0; // idDelta[0] - arrNewCmapTable[37] = 0; - arrNewCmapTable[38] = 0; // idDelta[1] - arrNewCmapTable[39] = 1; - arrNewCmapTable[40] = 0; // idRangeOffset[0] - arrNewCmapTable[41] = 4; - arrNewCmapTable[42] = 0; // idRangeOffset[1] - arrNewCmapTable[43] = 0; - for (i = 0; i < 256; ++i) - { - arrNewCmapTable[44 + 2 * i] = pCodeToGID[i] >> 8; - arrNewCmapTable[44 + 2 * i + 1] = pCodeToGID[i] & 0xff; - } - } - else - { - nNewCmapLen = 0; - arrNewCmapTable = NULL; - } - - // generate the new hmtx table and the updated hhea table - if (abbrevHMTX) - { - i = SeekTable("hhea"); - nPos = m_pTables[i].nOffset; - nNewHHEALen = 36; - arrNewHHEATable = (char *)MemUtilsMalloc(nNewHHEALen); - for (i = 0; i < nNewHHEALen; ++i) - { - arrNewHHEATable[i] = GetU8(nPos++, &bSuccess); - } - arrNewHHEATable[34] = m_nGlyphs >> 8; - arrNewHHEATable[35] = m_nGlyphs & 0xff; - i = SeekTable("hmtx"); - nPos = m_pTables[i].nOffset; - nNewHMTXLen = 4 * m_nGlyphs; - arrNewHMTXTable = (char *)MemUtilsMalloc(nNewHMTXLen); - nAdvWidth = 0; - for (i = 0; i < nHMetrics; ++i) - { - nAdvWidth = GetU16BE(nPos, &bSuccess); - nLeftSideBearing = GetU16BE(nPos + 2, &bSuccess); - nPos += 4; - arrNewHMTXTable[4 * i] = nAdvWidth >> 8; - arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; - arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; - arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; - } - for (; i < m_nGlyphs; ++i) - { - nLeftSideBearing = GetU16BE(nPos, &bSuccess); - nPos += 2; - arrNewHMTXTable[4 * i] = nAdvWidth >> 8; - arrNewHMTXTable[4 * i + 1] = nAdvWidth & 0xff; - arrNewHMTXTable[4 * i + 2] = nLeftSideBearing >> 8; - arrNewHMTXTable[4 * i + 3] = nLeftSideBearing & 0xff; - } - } - else - { - arrNewHHEATable = arrNewHMTXTable = NULL; - nNewHHEALen = nNewHMTXLen = 0; - } - - // construct the new table directory: - // - keep all original tables with non-zero length - // - fix the cmap table's length, if necessary - // - add missing tables - // - sort the table by tag - // - compute new table positions, including 4-byte alignment - // - (re)compute table checksums - nNewTables = m_nTablesCount - nZeroLengthTables + (bMissingCmap ? 1 : 0) + (bMissingName ? 1 : 0) + (bMissingPost ? 1 : 0) + (bMissingOS2 ? 1 : 0); - pNewTables = (TrueTypeTable *)MemUtilsMallocArray(nNewTables, sizeof(TrueTypeTable)); - j = 0; - for (i = 0; i < m_nTablesCount; ++i) - { - if (m_pTables[i].nLen > 0) - { - pNewTables[j] = m_pTables[i]; - pNewTables[j].nOrigOffset = m_pTables[i].nOffset; - if (CheckRegion(m_pTables[i].nOffset, pNewTables[i].nLen)) - { - pNewTables[j].unChecksum = ComputeTableChecksum(m_sFile + m_pTables[i].nOffset, m_pTables[i].nLen); - if (m_pTables[i].unTag == headTag) - { - // don't include the file checksum - pNewTables[j].unChecksum -= GetU32BE(m_pTables[i].nOffset + 8, &bSuccess); - } - } - if (pNewTables[j].unTag == cmapTag && pCodeToGID) - { - pNewTables[j].nLen = nNewCmapLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); - } - else if (pNewTables[j].unTag == cmapTag && badCmapLen) - { - pNewTables[j].nLen = nCmapLen; - } - else if (pNewTables[j].unTag == locaTag && bUnsortedLoca) - { - pNewTables[j].nLen = (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2); - pNewTables[j].unChecksum = nLocaChecksum; - } - else if (pNewTables[j].unTag == glyfTag && bUnsortedLoca) - { - pNewTables[j].nLen = nGlyphLen; - pNewTables[j].unChecksum = nGlyphChecksum; - } - else if (pNewTables[j].unTag == nameTag && sName) - { - pNewTables[j].nLen = nNewNameLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); - } - else if (pNewTables[j].unTag == hheaTag && abbrevHMTX) - { - pNewTables[j].nLen = nNewHHEALen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHHEATable, nNewHHEALen); - } - else if (pNewTables[j].unTag == hmtxTag && abbrevHMTX) - { - pNewTables[j].nLen = nNewHMTXLen; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewHMTXTable, nNewHMTXLen); - } - ++j; - } - } - if (bMissingCmap) - { - pNewTables[j].unTag = cmapTag; - if (pCodeToGID) - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewCmapTable, nNewCmapLen); - pNewTables[j].nLen = nNewCmapLen; - } - else - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrCMapTab, sizeof(arrCMapTab)); - pNewTables[j].nLen = sizeof(arrCMapTab); - } - ++j; - } - if (bMissingName) - { - pNewTables[j].unTag = nameTag; - if (sName) - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNewNameTable, nNewNameLen); - pNewTables[j].nLen = nNewNameLen; - } - else - { - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrNameTab, sizeof(arrNameTab)); - pNewTables[j].nLen = sizeof(arrNameTab); - } - ++j; - } - if (bMissingPost) - { - pNewTables[j].unTag = postTag; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrPostTab, sizeof(arrPostTab)); - pNewTables[j].nLen = sizeof(arrPostTab); - ++j; - } - if (bMissingOS2) - { - pNewTables[j].unTag = os2Tag; - pNewTables[j].unChecksum = ComputeTableChecksum((unsigned char *)arrOS2Tab, sizeof(arrOS2Tab)); - pNewTables[j].nLen = sizeof(arrOS2Tab); - ++j; - } - qsort(pNewTables, nNewTables, sizeof(TrueTypeTable), CompareTrueTypeTableTag); - nPos = 12 + nNewTables * 16; - for (i = 0; i < nNewTables; ++i) - { - pNewTables[i].nOffset = nPos; - nPos += pNewTables[i].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - - // write the table directory - arrTableDir = (char *)MemUtilsMalloc(12 + nNewTables * 16); - arrTableDir[0] = 0x00; // sfnt version - arrTableDir[1] = 0x01; - arrTableDir[2] = 0x00; - arrTableDir[3] = 0x00; - arrTableDir[4] = (char)((nNewTables >> 8) & 0xff); // numTables - arrTableDir[5] = (char)(nNewTables & 0xff); - for (i = -1, t = (unsigned int)nNewTables; t; ++i, t >>= 1); - t = 1 << (4 + i); - arrTableDir[6] = (char)((t >> 8) & 0xff); // searchRange - arrTableDir[7] = (char)(t & 0xff); - arrTableDir[8] = (char)((i >> 8) & 0xff); // entrySelector - arrTableDir[9] = (char)(i & 0xff); - t = nNewTables * 16 - t; - arrTableDir[10] = (char)((t >> 8) & 0xff); // rangeShift - arrTableDir[11] = (char)(t & 0xff); - nPos = 12; - for (i = 0; i < nNewTables; ++i) - { - arrTableDir[nPos] = (char)(pNewTables[i].unTag >> 24); - arrTableDir[nPos + 1] = (char)(pNewTables[i].unTag >> 16); - arrTableDir[nPos + 2] = (char)(pNewTables[i].unTag >> 8); - arrTableDir[nPos + 3] = (char)pNewTables[i].unTag; - arrTableDir[nPos + 4] = (char)(pNewTables[i].unChecksum >> 24); - arrTableDir[nPos + 5] = (char)(pNewTables[i].unChecksum >> 16); - arrTableDir[nPos + 6] = (char)(pNewTables[i].unChecksum >> 8); - arrTableDir[nPos + 7] = (char)pNewTables[i].unChecksum; - arrTableDir[nPos + 8] = (char)(pNewTables[i].nOffset >> 24); - arrTableDir[nPos + 9] = (char)(pNewTables[i].nOffset >> 16); - arrTableDir[nPos + 10] = (char)(pNewTables[i].nOffset >> 8); - arrTableDir[nPos + 11] = (char)pNewTables[i].nOffset; - arrTableDir[nPos + 12] = (char)(pNewTables[i].nLen >> 24); - arrTableDir[nPos + 13] = (char)(pNewTables[i].nLen >> 16); - arrTableDir[nPos + 14] = (char)(pNewTables[i].nLen >> 8); - arrTableDir[nPos + 15] = (char)pNewTables[i].nLen; - nPos += 16; - } - (*pOutputFunc)(pOutputStream, arrTableDir, 12 + nNewTables * 16); - - // compute the file checksum - nFileChecksum = ComputeTableChecksum((unsigned char *)arrTableDir, 12 + nNewTables * 16); - for (i = 0; i < nNewTables; ++i) - { - nFileChecksum += pNewTables[i].unChecksum; - } - nFileChecksum = 0xb1b0afba - nFileChecksum; - - // write the tables - for (i = 0; i < nNewTables; ++i) - { - if (pNewTables[i].unTag == headTag) - { - if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) - { - (*pOutputFunc)(pOutputStream, (char *)m_sFile + pNewTables[i].nOrigOffset, 8); - arrChecksumBuf[0] = nFileChecksum >> 24; - arrChecksumBuf[1] = nFileChecksum >> 16; - arrChecksumBuf[2] = nFileChecksum >> 8; - arrChecksumBuf[3] = nFileChecksum; - (*pOutputFunc)(pOutputStream, arrChecksumBuf, 4); - (*pOutputFunc)(pOutputStream, (char *)m_sFile + pNewTables[i].nOrigOffset + 12, pNewTables[i].nLen - 12); - } - else - { - for (j = 0; j < pNewTables[i].nLen; ++j) - { - (*pOutputFunc)(pOutputStream, "\0", 1); - } - } - } - else if (pNewTables[i].unTag == cmapTag && pCodeToGID) - (*pOutputFunc)(pOutputStream, arrNewCmapTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == cmapTag && bMissingCmap) - (*pOutputFunc)(pOutputStream, arrCMapTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == nameTag && sName) - (*pOutputFunc)(pOutputStream, arrNewNameTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == nameTag && bMissingName) - (*pOutputFunc)(pOutputStream, arrNameTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == postTag && bMissingPost) - (*pOutputFunc)(pOutputStream, arrPostTab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == os2Tag && bMissingOS2) - (*pOutputFunc)(pOutputStream, arrOS2Tab, pNewTables[i].nLen); - else if (pNewTables[i].unTag == hheaTag && abbrevHMTX) - (*pOutputFunc)(pOutputStream, arrNewHHEATable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == hmtxTag && abbrevHMTX) - (*pOutputFunc)(pOutputStream, arrNewHMTXTable, pNewTables[i].nLen); - else if (pNewTables[i].unTag == locaTag && bUnsortedLoca) - { - for (j = 0; j <= m_nGlyphs; ++j) - { - if (m_nLocaFormat) - { - arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 24); - arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 16); - arrLocaBuf[2] = (char)(pLocaTable[j].nNewOffset >> 8); - arrLocaBuf[3] = (char)pLocaTable[j].nNewOffset; - (*pOutputFunc)(pOutputStream, arrLocaBuf, 4); - } - else - { - arrLocaBuf[0] = (char)(pLocaTable[j].nNewOffset >> 9); - arrLocaBuf[1] = (char)(pLocaTable[j].nNewOffset >> 1); - (*pOutputFunc)(pOutputStream, arrLocaBuf, 2); - } - } - } - else if (pNewTables[i].unTag == glyfTag && bUnsortedLoca) - { - nPos = m_pTables[SeekTable("glyf")].nOffset; - for (j = 0; j < m_nGlyphs; ++j) - { - n = pLocaTable[j].nLen; - if (n > 0) - { - k = pLocaTable[j].nOrigOffset; - if (CheckRegion(nPos + k, n)) - { - (*pOutputFunc)(pOutputStream, (char *)m_sFile + nPos + k, n); - } - else - { - for (k = 0; k < n; ++k) - { - (*pOutputFunc)(pOutputStream, "\0", 1); - } - } - if ((k = pLocaTable[j].nLen & 3)) - { - (*pOutputFunc)(pOutputStream, "\0\0\0\0", 4 - k); - } - } - } - } - else - { - if (CheckRegion(pNewTables[i].nOrigOffset, pNewTables[i].nLen)) - { - (*pOutputFunc)(pOutputStream, (char *)m_sFile + pNewTables[i].nOrigOffset, pNewTables[i].nLen); - } - else - { - for (j = 0; j < pNewTables[i].nLen; ++j) - { - (*pOutputFunc)(pOutputStream, "\0", 1); - } - } - } - if (pNewTables[i].nLen & 3) - { - (*pOutputFunc)(pOutputStream, "\0\0\0", 4 - (pNewTables[i].nLen & 3)); - } - } - - MemUtilsFree(arrNewHMTXTable); - MemUtilsFree(arrNewHHEATable); - MemUtilsFree(arrNewCmapTable); - MemUtilsFree(arrNewNameTable); - MemUtilsFree(arrTableDir); - MemUtilsFree(pNewTables); - MemUtilsFree(pLocaTable); - } - - void CFontFileTrueType::ConvertEncoding(char **ppEncoding, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - // конвертация кодировки в тип Type42 - char *sName; - StringExt *seBuffer; - - (*pOutputFunc)(pOutputStream, "/Encoding 256 array\n", 20); - if (ppEncoding) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (!(sName = ppEncoding[nIndex])) - { - sName = ".notdef"; - } - seBuffer = StringExt::Format("dup {0:d} /", nIndex); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - (*pOutputFunc)(pOutputStream, sName, strlen(sName)); - (*pOutputFunc)(pOutputStream, " put\n", 5); - } - } - else - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - seBuffer = StringExt::Format("dup {0:d} /c{1:02x} put\n", nIndex, nIndex); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - } - (*pOutputFunc)(pOutputStream, "readonly def\n", 13); - } - - void CFontFileTrueType::ConvertCharStrings(char **ppEncoding, unsigned short *pnCodeToGID, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - char *sName; - StringExt *seBuffer; - char sBuf[16]; - - (*pOutputFunc)(pOutputStream, "/CharStrings 256 dict dup begin\n", 32); - (*pOutputFunc)(pOutputStream, "/.notdef 0 def\n", 15); - - if (m_nCMapsCount == 0) - { - (*pOutputFunc)(pOutputStream, "end readonly def\n", 17); - return; - } - - // Ставим в соответствие названию символа glyph индекс: - // 1. Используем ppEncoding для отображения имени символа в его номер - // 2. Используем pnCodeToGID для отображения номера символа в glyph индекс - int nGlyphIndex = 0; - for (int nIndex = 255; nIndex >= 0; --nIndex) - { - if (ppEncoding) - { - sName = ppEncoding[nIndex]; - } - else - { - sprintf(sBuf, "c%02x", nIndex); - sName = sBuf; - } - if (sName && strcmp(sName, ".notdef")) - { - nGlyphIndex = pnCodeToGID[nIndex]; - - if (nGlyphIndex > 0 && nGlyphIndex < m_nGlyphs) - { - (*pOutputFunc)(pOutputStream, "/", 1); - (*pOutputFunc)(pOutputStream, sName, strlen(sName)); - seBuffer = StringExt::Format(" {0:d} def\n", nGlyphIndex); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - } - } - } - - void CFontFileTrueType::ConvertSfnts(FontFileOutputFunc pOutputFunc, void *pOutputStream, StringExt *seName, bool bNeedVerticalMetrics) - { - unsigned char pHeadData[54]; - TrueTypeLoca *pLocaTable; - unsigned char *pLocaData; - TrueTypeTable arrNewTables[nT42Tables]; - unsigned char arrTableDir[12 + nT42Tables * 16]; - unsigned int nChecksum = 0; - int nNewTables; - int nLength = 0, nGlyphfPos = 0, nJ = 0; - - unsigned char arrVheaTable[36] = - { - 0, 1, 0, 0, // table version number - 0, 0, // ascent - 0, 0, // descent - 0, 0, // reserved - 0, 0, // max advance height - 0, 0, // min top side bearing - 0, 0, // min bottom side bearing - 0, 0, // y max extent - 0, 0, // caret slope rise - 0, 1, // caret slope run - 0, 0, // caret offset - 0, 0, // reserved - 0, 0, // reserved - 0, 0, // reserved - 0, 0, // reserved - 0, 0, // metric data format - 0, 1 // number of advance heights in vmtx table - }; - - unsigned char *arrVmtxTable; - bool bNeedVhea, bNeedVmtx; - - int nCurTable = SeekTable("head"); - int nPos = m_pTables[nCurTable].nOffset; - if (!CheckRegion(nPos, 54)) - return; - - memcpy(pHeadData, m_sFile + nPos, 54); - pHeadData[8] = pHeadData[9] = pHeadData[10] = pHeadData[11] = (unsigned char)0; - - pLocaTable = (TrueTypeLoca *)MemUtilsMallocArray(m_nGlyphs + 1, sizeof(TrueTypeLoca)); - nCurTable = SeekTable("loca"); - nPos = m_pTables[nCurTable].nOffset; - bool bSuccess = true; - for (int nIndex = 0; nIndex <= m_nGlyphs; ++nIndex) - { - pLocaTable[nIndex].nIndex = nIndex; - if (m_nLocaFormat) - pLocaTable[nIndex].nOrigOffset = (int)GetU32BE(nPos + nIndex * 4, &bSuccess); - else - pLocaTable[nIndex].nOrigOffset = 2 * GetU16BE(nPos + nIndex * 2, &bSuccess); - } - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaOffset); - - for (int nIndex = 0; nIndex < m_nGlyphs; ++nIndex) - { - pLocaTable[nIndex].nLen = pLocaTable[nIndex + 1].nOrigOffset - pLocaTable[nIndex].nOrigOffset; - } - - pLocaTable[m_nGlyphs].nLen = 0; - qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); - nPos = 0; - for (int nIndex = 0; nIndex <= m_nGlyphs; ++nIndex) - { - pLocaTable[nIndex].nNewOffset = nPos; - nPos += pLocaTable[nIndex].nLen; - if (nPos & 3) - { - nPos += 4 - (nPos & 3); - } - } - - // Создаем новую таблицу 'loca' - pLocaData = (unsigned char *)MemUtilsMallocArray(m_nGlyphs + 1, (m_nLocaFormat ? 4 : 2)); - for (int nIndex = 0; nIndex <= m_nGlyphs; ++nIndex) - { - nPos = pLocaTable[nIndex].nNewOffset; - if (m_nLocaFormat) - { - pLocaData[4 * nIndex] = (unsigned char)(nPos >> 24); - pLocaData[4 * nIndex + 1] = (unsigned char)(nPos >> 16); - pLocaData[4 * nIndex + 2] = (unsigned char)(nPos >> 8); - pLocaData[4 * nIndex + 3] = (unsigned char)nPos; - } - else - { - pLocaData[2 * nIndex] = (unsigned char)(nPos >> 9); - pLocaData[2 * nIndex + 1] = (unsigned char)(nPos >> 1); - } - } - - // считаем число таблиц - nNewTables = 0; - for (int nIndex = 0; nIndex < nT42Tables; ++nIndex) - { - if (t42Tables[nIndex].bRequired || SeekTable(t42Tables[nIndex].sTag) >= 0) - { - ++nNewTables; - } - } - arrVmtxTable = NULL; - int nAdvance = 0; - if (bNeedVerticalMetrics) - { - bNeedVhea = SeekTable("vhea") < 0; - bNeedVmtx = SeekTable("vmtx") < 0; - if (bNeedVhea || bNeedVmtx) - { - nCurTable = SeekTable("head"); - nAdvance = GetU16BE(m_pTables[nCurTable].nOffset + 18, &bSuccess); // units per em - if (bNeedVhea) - { - ++nNewTables; - } - if (bNeedVmtx) - { - ++nNewTables; - } - } - } - - nPos = 12 + nNewTables * 16; - int nTableIndex = 0; - for (int nIndex = 0; nIndex < nT42Tables; ++nIndex) - { - nLength = -1; - nChecksum = 0; - if (t42HeadTable == nIndex) - { - nLength = 54; - nChecksum = ComputeTableChecksum(pHeadData, 54); - } - else if (t42LocaTable == nIndex) - { - nLength = (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2); - nChecksum = ComputeTableChecksum(pLocaData, nLength); - } - else if (t42GlyfTable == nIndex) - { - nLength = 0; - nChecksum = 0; - nGlyphfPos = m_pTables[SeekTable("glyf")].nOffset; - for (nJ = 0; nJ < m_nGlyphs; ++nJ) - { - nLength += pLocaTable[nJ].nLen; - if (nLength & 3) - { - nLength += 4 - (nLength & 3); - } - if (CheckRegion(nGlyphfPos + pLocaTable[nJ].nOrigOffset, pLocaTable[nJ].nLen)) - { - nChecksum += ComputeTableChecksum(m_sFile + nGlyphfPos + pLocaTable[nJ].nOrigOffset, pLocaTable[nJ].nLen); - } - } - } - else - { - if ((nJ = SeekTable(t42Tables[nIndex].sTag)) >= 0) - { - nLength = m_pTables[nJ].nLen; - if (CheckRegion(m_pTables[nJ].nOffset, nLength)) - { - nChecksum = ComputeTableChecksum(m_sFile + m_pTables[nJ].nOffset, nLength); - } - } - else if (bNeedVerticalMetrics && nIndex == t42VheaTable) - { - arrVheaTable[10] = nAdvance / 256; // max advance height - arrVheaTable[11] = nAdvance % 256; - nLength = sizeof(arrVheaTable); - nChecksum = ComputeTableChecksum(arrVheaTable, nLength); - } - else if (bNeedVerticalMetrics && nIndex == t42VmtxTable) - { - nLength = 4 + (m_nGlyphs - 1) * 4; - arrVmtxTable = (unsigned char *)MemUtilsMalloc(nLength); - arrVmtxTable[0] = nAdvance / 256; - arrVmtxTable[1] = nAdvance % 256; - for (nJ = 2; nJ < nLength; nJ += 2) - { - arrVmtxTable[nJ] = 0; - arrVmtxTable[nJ + 1] = 0; - } - nChecksum = ComputeTableChecksum(arrVmtxTable, nLength); - } - else if (t42Tables[nIndex].bRequired) - { - // TO DO : "Embedded TrueType font is missing a required table t42Tables[i].tag - nLength = 0; - nChecksum = 0; - } - } - if (nLength >= 0) - { - arrNewTables[nTableIndex].unTag = ((t42Tables[nIndex].sTag[0] & 0xff) << 24) | ((t42Tables[nIndex].sTag[1] & 0xff) << 16) | ((t42Tables[nIndex].sTag[2] & 0xff) << 8) | (t42Tables[nIndex].sTag[3] & 0xff); - arrNewTables[nTableIndex].unChecksum = nChecksum; - arrNewTables[nTableIndex].nOffset = nPos; - arrNewTables[nTableIndex].nLen = nLength; - nPos += nLength; - if (nPos & 3) - { - nPos += 4 - (nLength & 3); - } - ++nTableIndex; - } - } - - // construct the table directory - arrTableDir[0] = 0x00; // sfnt version - arrTableDir[1] = 0x01; - arrTableDir[2] = 0x00; - arrTableDir[3] = 0x00; - arrTableDir[4] = 0; // numTables - arrTableDir[5] = nNewTables; - arrTableDir[6] = 0; // searchRange - arrTableDir[7] = (unsigned char)128; - arrTableDir[8] = 0; // entrySelector - arrTableDir[9] = 3; - arrTableDir[10] = 0; // rangeShift - arrTableDir[11] = (unsigned char)(16 * nNewTables - 128); - nPos = 12; - for (int nIndex = 0; nIndex < nNewTables; ++nIndex) - { - arrTableDir[nPos] = (unsigned char)(arrNewTables[nIndex].unTag >> 24); - arrTableDir[nPos + 1] = (unsigned char)(arrNewTables[nIndex].unTag >> 16); - arrTableDir[nPos + 2] = (unsigned char)(arrNewTables[nIndex].unTag >> 8); - arrTableDir[nPos + 3] = (unsigned char)arrNewTables[nIndex].unTag; - arrTableDir[nPos + 4] = (unsigned char)(arrNewTables[nIndex].unChecksum >> 24); - arrTableDir[nPos + 5] = (unsigned char)(arrNewTables[nIndex].unChecksum >> 16); - arrTableDir[nPos + 6] = (unsigned char)(arrNewTables[nIndex].unChecksum >> 8); - arrTableDir[nPos + 7] = (unsigned char)arrNewTables[nIndex].unChecksum; - arrTableDir[nPos + 8] = (unsigned char)(arrNewTables[nIndex].nOffset >> 24); - arrTableDir[nPos + 9] = (unsigned char)(arrNewTables[nIndex].nOffset >> 16); - arrTableDir[nPos + 10] = (unsigned char)(arrNewTables[nIndex].nOffset >> 8); - arrTableDir[nPos + 11] = (unsigned char)arrNewTables[nIndex].nOffset; - arrTableDir[nPos + 12] = (unsigned char)(arrNewTables[nIndex].nLen >> 24); - arrTableDir[nPos + 13] = (unsigned char)(arrNewTables[nIndex].nLen >> 16); - arrTableDir[nPos + 14] = (unsigned char)(arrNewTables[nIndex].nLen >> 8); - arrTableDir[nPos + 15] = (unsigned char)arrNewTables[nIndex].nLen; - nPos += 16; - } - - // вычисляем checksum и сохраняем ее в заголовке таблицы - nChecksum = ComputeTableChecksum(arrTableDir, 12 + nNewTables * 16); - for (int nIndex = 0; nIndex < nNewTables; ++nIndex) - { - nChecksum += arrNewTables[nIndex].unChecksum; - } - nChecksum = 0xb1b0afba - nChecksum; // по спецификации TrueType - pHeadData[8] = (unsigned char)(nChecksum >> 24); - pHeadData[9] = (unsigned char)(nChecksum >> 16); - pHeadData[10] = (unsigned char)(nChecksum >> 8); - pHeadData[11] = (unsigned char)nChecksum; - - // начинаем писать массив sfnts - if (seName) - { - (*pOutputFunc)(pOutputStream, "/", 1); - (*pOutputFunc)(pOutputStream, seName->GetBuffer(), seName->GetLength()); - (*pOutputFunc)(pOutputStream, " [\n", 3); - } - else - { - (*pOutputFunc)(pOutputStream, "/sfnts [\n", 9); - } - - DumpString(arrTableDir, 12 + nNewTables * 16, pOutputFunc, pOutputStream); - - // пишем таблицы - for (int nIndex = 0; nIndex < nNewTables; ++nIndex) - { - if (t42HeadTable == nIndex) - { - DumpString(pHeadData, 54, pOutputFunc, pOutputStream); - } - else if (t42LocaTable == nIndex) - { - nLength = (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2); - DumpString(pLocaData, nLength, pOutputFunc, pOutputStream); - } - else if (t42GlyfTable == nIndex) - { - nGlyphfPos = m_pTables[SeekTable("glyf")].nOffset; - for (nJ = 0; nJ < m_nGlyphs; ++nJ) - { - if (pLocaTable[nJ].nLen > 0 && CheckRegion(nGlyphfPos + pLocaTable[nJ].nOrigOffset, pLocaTable[nJ].nLen)) - { - DumpString(m_sFile + nGlyphfPos + pLocaTable[nJ].nOrigOffset, pLocaTable[nJ].nLen, pOutputFunc, pOutputStream); - } - } - } - else - { - // nLength == 0 означает, что таблица не найдена, а ошибка уже была выдана - // во время конструирования таблицы - if ((nLength = arrNewTables[nIndex].nLen) > 0) - { - if ((nJ = SeekTable(t42Tables[nIndex].sTag)) >= 0 && CheckRegion(m_pTables[nJ].nOffset, m_pTables[nJ].nLen)) - { - DumpString(m_sFile + m_pTables[nJ].nOffset, m_pTables[nJ].nLen, pOutputFunc, pOutputStream); - } - else if (bNeedVerticalMetrics && t42VheaTable == nIndex) - { - DumpString(arrVheaTable, nLength, pOutputFunc, pOutputStream); - } - else if (bNeedVerticalMetrics && t42VmtxTable == nIndex) - { - DumpString(arrVmtxTable, nLength, pOutputFunc, pOutputStream); - MemUtilsFree(arrVmtxTable); - } - } - } - } - - // закончили писать массив sfnts - (*pOutputFunc)(pOutputStream, "] def\n", 6); - - MemUtilsFree(pLocaData); - MemUtilsFree(pLocaTable); - } - - void CFontFileTrueType::DumpString(unsigned char *sString, int nLength, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - StringExt *seBuffer; - int nPad = 0; - - (*pOutputFunc)(pOutputStream, "<", 1); - for (int nIndex = 0; nIndex < nLength; nIndex += 32) - { - for (int nJ = 0; nJ < 32 && nIndex + nJ < nLength; ++nJ) - { - seBuffer = StringExt::Format("{0:02x}", sString[nIndex + nJ] & 0xff); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (nIndex % (65536 - 32) == 65536 - 64) - { - (*pOutputFunc)(pOutputStream, ">\n<", 3); - } - else if (nIndex + 32 < nLength) - { - (*pOutputFunc)(pOutputStream, "\n", 1); - } - } - if (nLength & 3) - { - nPad = 4 - (nLength & 3); - for (int nIndex = 0; nIndex < nPad; ++nIndex) - { - (*pOutputFunc)(pOutputStream, "00", 2); - } - } - // Добавляем дополнительный нулевой байт, по спецификации Adobe Type 42 - (*pOutputFunc)(pOutputStream, "00>\n", 4); - } - - unsigned int CFontFileTrueType::ComputeTableChecksum(unsigned char *sData, int nLength) - { - unsigned int nWord = 0; - - unsigned int nChecksum = 0; - for (int nIndex = 0; nIndex + 3 < nLength; nIndex += 4) - { - nWord = ((sData[nIndex] & 0xff) << 24) + ((sData[nIndex + 1] & 0xff) << 16) + ((sData[nIndex + 2] & 0xff) << 8) + (sData[nIndex + 3] & 0xff); - nChecksum += nWord; - } - if (nLength & 3) - { - nWord = 0; - int nTemp = nLength & ~3; - switch (nLength & 3) - { - case 3: - nWord |= (sData[nTemp + 2] & 0xff) << 8; - case 2: - nWord |= (sData[nTemp + 1] & 0xff) << 16; - case 1: - nWord |= (sData[nTemp] & 0xff) << 24; - break; - } - nChecksum += nWord; - } - return nChecksum; - } - - void CFontFileTrueType::Parse() - { - int nPos = 0, nIndex = 0, nJ; - - m_bSuccess = true; - - // Проверяем является ли данный файл (TTC) - unsigned int usTopTag = GetU32BE(0, &m_bSuccess); - if (!m_bSuccess) - return; - - if (usTopTag == ttcfTag) - { - nPos = GetU32BE(12, &m_bSuccess); - if (!m_bSuccess) - return; - } - else - nPos = 0; - - // Проверяем sfnt версию - int nSfntVersion = GetU32BE(nPos, &m_bSuccess); - if (!m_bSuccess) - return; - - // Проверяем на формат данных. CCF или нет? - m_bOpenTypeCFF = (nSfntVersion == 0x4f54544f); // 'OTTO' - - m_nTablesCount = GetU16BE(nPos + 4, &m_bSuccess); - if (!m_bSuccess) - return; - - m_pTables = (TrueTypeTable *)MemUtilsMallocArray(m_nTablesCount, sizeof(TrueTypeTable)); - nPos += 12; - - for (nIndex = 0; nIndex < m_nTablesCount; ++nIndex) - { - m_pTables[nIndex].unTag = GetU32BE(nPos, &m_bSuccess); - m_pTables[nIndex].unChecksum = GetU32BE(nPos + 4, &m_bSuccess); - m_pTables[nIndex].nOffset = (int)GetU32BE(nPos + 8, &m_bSuccess); - m_pTables[nIndex].nLen = (int)GetU32BE(nPos + 12, &m_bSuccess); - if (m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen < m_pTables[nIndex].nOffset || m_pTables[nIndex].nOffset + m_pTables[nIndex].nLen > m_nLen) - { - m_bSuccess = false; - } - nPos += 16; - } - if (!m_bSuccess) - return; - - // ищем таблицы необходимые как и для TrueType так и для Type 42 - if (SeekTable("head") < 0 || SeekTable("hhea") < 0 || SeekTable("maxp") < 0 || SeekTable("hmtx") < 0 || (!m_bOpenTypeCFF && SeekTable("loca") < 0) || (!m_bOpenTypeCFF && SeekTable("glyf") < 0) || (m_bOpenTypeCFF && SeekTable("CFF ") < 0)) - { - m_bSuccess = false; - return; - } - - // читаем таблицы CMaps - if ((nIndex = SeekTable("cmap")) >= 0) - { - nPos = m_pTables[nIndex].nOffset + 2; - m_nCMapsCount = GetU16BE(nPos, &m_bSuccess); - nPos += 2; - if (!m_bSuccess) - return; - - m_pCMaps = (TrueTypeCmap *)MemUtilsMallocArray(m_nCMapsCount, sizeof(TrueTypeCmap)); - - for (nJ = 0; nJ < m_nCMapsCount; ++nJ) - { - m_pCMaps[nJ].nPlatform = GetU16BE(nPos, &m_bSuccess); - m_pCMaps[nJ].nEncoding = GetU16BE(nPos + 2, &m_bSuccess); - unsigned int nTemp = GetU32BE(nPos + 4, &m_bSuccess); - m_pCMaps[nJ].nOffset = m_pTables[nIndex].nOffset + GetU32BE(nPos + 4, &m_bSuccess); - nPos += 8; - m_pCMaps[nJ].nFormat = GetU16BE(m_pCMaps[nJ].nOffset, &m_bSuccess); - m_pCMaps[nJ].nLen = GetU16BE(m_pCMaps[nJ].nOffset + 2, &m_bSuccess); - } - if (!m_bSuccess) - return; - } - else - m_nCMapsCount = 0; - - nIndex = SeekTable("maxp"); - m_nGlyphs = GetU16BE(m_pTables[nIndex].nOffset + 4, &m_bSuccess); - if (!m_bSuccess) - return; - - nIndex = SeekTable("head"); - m_arrBBox[0] = GetS16BE(m_pTables[nIndex].nOffset + 36, &m_bSuccess); - m_arrBBox[1] = GetS16BE(m_pTables[nIndex].nOffset + 38, &m_bSuccess); - m_arrBBox[2] = GetS16BE(m_pTables[nIndex].nOffset + 40, &m_bSuccess); - m_arrBBox[3] = GetS16BE(m_pTables[nIndex].nOffset + 42, &m_bSuccess); - m_nLocaFormat = GetS16BE(m_pTables[nIndex].nOffset + 50, &m_bSuccess); - if (!m_bSuccess) - return; - - // Проверяем корректность таблицы loca - if (!m_bOpenTypeCFF) - { - nIndex = SeekTable("loca"); - if (m_pTables[nIndex].nLen < 0) - { - m_bSuccess = false; - return; - } - if (m_pTables[nIndex].nLen < (m_nGlyphs + 1) * (m_nLocaFormat ? 4 : 2)) - { - m_nGlyphs = m_pTables[nIndex].nLen / (m_nLocaFormat ? 4 : 2) - 1; - } - for (nJ = 0; nJ <= m_nGlyphs; ++nJ) - { - if (m_nLocaFormat) - nPos = (int)GetU32BE(m_pTables[nIndex].nOffset + nJ * 4, &m_bSuccess); - else - nPos = GetU16BE(m_pTables[nIndex].nOffset + nJ * 2, &m_bSuccess); - - if (nPos < 0 || nPos > m_nLen) - m_bSuccess = false; - } - if (!m_bSuccess) - return; - } - - // Читаем таблицу post - ReadPostTable(); - } - - void CFontFileTrueType::ReadPostTable() - { - StringExt *seName; - int nStringIndex, nStringPos; - bool bSuccess = true; - int nTemp, nJ, nCount = 0, nTempLen = 0; - - if ((nTemp = SeekTable("post")) < 0) - return; - - int nTablePos = m_pTables[nTemp].nOffset; - int nPostFormat = GetU32BE(nTablePos, &bSuccess); - - if (!bSuccess) - goto error; - - if (0x00010000 == nPostFormat) - { - m_pNameToGID = new CHash(true); - for (nTemp = 0; nTemp < 258; ++nTemp) - { - m_pNameToGID->Add(new StringExt(c_arrAppleGlyphNames[nTemp]), nTemp); - } - } - else if (0x00020000 == nPostFormat) - { - m_pNameToGID = new CHash(true); - nCount = GetU16BE(nTablePos + 32, &bSuccess); - if (!bSuccess) - goto error; - if (nCount > m_nGlyphs) - { - nCount = m_nGlyphs; - } - nStringIndex = 0; - nStringPos = nTablePos + 34 + 2 * nCount; - for (nTemp = 0; nTemp < nCount; ++nTemp) - { - nJ = GetU16BE(nTablePos + 34 + 2 * nTemp, &bSuccess); - if (nJ < 258) - { - m_pNameToGID->RemoveInt(c_arrAppleGlyphNames[nJ]); - m_pNameToGID->Add(new StringExt(c_arrAppleGlyphNames[nJ]), nTemp); - } - else - { - nJ -= 258; - if (nJ != nStringIndex) - { - for (nStringIndex = 0, nStringPos = nTablePos + 34 + 2 * nCount; nStringIndex < nJ; ++nStringIndex, nStringPos += 1 + GetU8(nStringPos, &bSuccess)); - if (!bSuccess) - goto error; - } - nTempLen = GetU8(nStringPos, &bSuccess); - if (!bSuccess || !CheckRegion(nStringPos + 1, nTempLen)) - goto error; - seName = new StringExt((char *)&m_sFile[nStringPos + 1], nTempLen); - m_pNameToGID->RemoveInt(seName); - m_pNameToGID->Add(seName, nTemp); - ++nStringIndex; - nStringPos += 1 + nTempLen; - } - } - } - else if (0x00028000 == nPostFormat) - { - m_pNameToGID = new CHash(true); - for (nTemp = 0; nTemp < m_nGlyphs; ++nTemp) - { - nJ = GetU8(nTablePos + 32 + nTemp, &bSuccess); - if (!bSuccess) - goto error; - if (nJ < 258) - { - m_pNameToGID->RemoveInt(c_arrAppleGlyphNames[nJ]); - m_pNameToGID->Add(new StringExt(c_arrAppleGlyphNames[nJ]), nTemp); - } - } - } - - return; - - error: - if (m_pNameToGID) - { - delete m_pNameToGID; - m_pNameToGID = NULL; - } - } - - int CFontFileTrueType::SeekTable(char *sTag) - { - unsigned int nTagIndex = ((sTag[0] & 0xff) << 24) | ((sTag[1] & 0xff) << 16) | ((sTag[2] & 0xff) << 8) | (sTag[3] & 0xff); - for (int nIndex = 0; nIndex < m_nTablesCount; ++nIndex) - { - if (m_pTables[nIndex].unTag == nTagIndex) - { - return nIndex; - } - } - return -1; - } -} \ No newline at end of file diff --git a/PdfReader/old/FontFileTrueType.h b/PdfReader/old/FontFileTrueType.h deleted file mode 100644 index 5be38b933c..0000000000 --- a/PdfReader/old/FontFileTrueType.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FONT_FILE_TRUETYPE_H -#define _PDF_READER_FONT_FILE_TRUETYPE_H - -#include "FontFileBase.h" - -namespace PdfReader -{ - class StringExt; - class CHash; - struct TrueTypeTable; - struct TrueTypeCmap; - - //------------------------------------------------------------------------ - // CFontFileTrueType - //------------------------------------------------------------------------ - - class CFontFileTrueType : public CFontFileBase - { - public: - - // Создаем объект TTF из буфера. - static CFontFileTrueType *LoadFromBuffer(char *sBuffer, int lenA); - - // Создаем объект TTF из файла. - static CFontFileTrueType *LoadFromFile(wchar_t *wsFileName); - - virtual ~CFontFileTrueType(); - - // true, если данный OpenType фонт содержите данные формата CFF. - // false,если это TrueType фонт ( или OpenType фонт с данными в формате TrueType). - bool IsOpenTypeCFF() - { - return m_bOpenTypeCFF; - } - - int GetCmapsCount(); - - int GetCmapPlatform(int nIndex); - - int GetCmapEncoding(int nIndex); - - int FindCmap(int nPlatform, int nEncoding); - - // Возвращает GID, соответствующий символу в ной CMap. - unsigned short MapCodeToGID(int nCMapIndex, int nChar); - - // Возвращает GID, соответствующий в таблице post. Возвращает 0, - // если символа с таким именем не нашли, или таблицы post нет. - int MapNameToGID(char *sName); - - // Возвращает карту CIDs в GIDs, и возваращет количество элементов - // CIDs в *. Только для CID фонтов( OpenType CFF ) - unsigned short *GetCIDToGIDMap(int *pnCIDs); - - // Лицензионные ограничения на включение фонта( в соответствие со - // спецификацией True Type): - - // * 4: таблицы OS/2 не найдена или некорректна - // * 3: разрешено устанавливать - // * 2: разрешено редактировать - // * 1: разрешено просматривать и печатать - // * 0: ограничено лицензией - int GetEmbeddingRestrictions(); - - // Convert to a Type 42 font, suitable for embedding in a PostScript - // file. will be used as the PostScript font name (so we - // don't need to depend on the 'name' table in the font). The - // array specifies the mapping from char codes to names. - // If is NULL, the encoding is unknown or undefined. The - // array specifies the mapping from char codes to GIDs. - // (Not useful for OpenType CFF fonts.) - void ToType42(char *sPSName, char **ppEncoding, unsigned short *pCodeToGID, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 1 font, suitable for embedding in a PostScript - // file. This is only useful with 8-bit fonts. If is - // not NULL, it will be used in place of the encoding in the Type 1C - // font. If is true the eexec section will be hex-encoded, - // otherwise it will be left as binary data. If is - // non-NULL, it will be used as the PostScript font name. (Only - // useful for OpenType CFF fonts.) - void ToType1(char *sPSName, char **ppNewEncoding, bool bASKII, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 2 CIDFont, suitable for embedding in a - // PostScript file. will be used as the PostScript font - // name (so we don't need to depend on the 'name' table in the - // font). The array maps CIDs to GIDs; it has - // entries. (Not useful for OpenType CFF fonts.) - void ToCIDType2(char *sPSName, unsigned short *pCIDMap, int nCIDCount, bool bNeedVerticalMetrics, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 0 CIDFont, suitable for embedding in a - // PostScript file. will be used as the PostScript font - // name. (Only useful for OpenType CFF fonts.) - void ToCIDType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 0 (but non-CID) composite font, suitable for - // embedding in a PostScript file. will be used as the - // PostScript font name (so we don't need to depend on the 'name' - // table in the font). The array maps CIDs to GIDs; it has - // entries. (Not useful for OpenType CFF fonts.) - void ToType0(char *sPSName, unsigned short *pCIDMap, int nCIDCount, bool bNeedVerticalMetrics, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 0 (but non-CID) composite font, suitable for - // embedding in a PostScript file. will be used as the - // PostScript font name. (Only useful for OpenType CFF fonts.) - void ToType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Write a clean TTF file, filling in missing tables and correcting - // various other errors. If is non-NULL, the font is renamed - // to . If is non-NULL, the font is re-encoded, - // using a Windows Unicode cmap. If is NULL and the font is - // complete and correct, it will be written unmodified. (Not useful - // for OpenType CFF fonts.) - void WriteTTF(FontFileOutputFunc pOutputFunc, void *pOutputStream, char *sName = NULL, unsigned short *pCodeToGID = NULL); - - private: - - CFontFileTrueType(char *sFileName, int nLen, bool bFreeFileData); - - void ConvertEncoding(char **ppEncoding, FontFileOutputFunc pOutputFunc, void *pOutputStream); - void ConvertCharStrings(char **ppEncoding, unsigned short *pnCodeToGID, FontFileOutputFunc pOutputFunc, void *pOutputStream); - void ConvertSfnts(FontFileOutputFunc pOutputFunc, void *pOutputStream, StringExt *seName, bool bNeedVerticalMetrics); - void DumpString(unsigned char *sString, int nLength, FontFileOutputFunc pOutputFunc, void *pOutputStream); - unsigned int ComputeTableChecksum(unsigned char *sData, int nLength); - void Parse(); - void ReadPostTable(); - int SeekTable(char *sTag); - - private: - - TrueTypeTable *m_pTables; - int m_nTablesCount; - TrueTypeCmap *m_pCMaps; - int m_nCMapsCount; - int m_nGlyphs; - int m_nLocaFormat; - int m_arrBBox[4]; - CHash *m_pNameToGID; - bool m_bOpenTypeCFF; - - bool m_bSuccess; - }; -} -#endif // _PDF_READER_FONT_FILE_TRUETYPE_H diff --git a/PdfReader/old/FontFileType1.cpp b/PdfReader/old/FontFileType1.cpp deleted file mode 100644 index a81be16211..0000000000 --- a/PdfReader/old/FontFileType1.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "FontFileEncodings.h" -#include "FontFileType1.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // CFontFileType1 - //------------------------------------------------------------------------ - - CFontFileType1 *CFontFileType1::LoadFromBuffer(char *sBuffer, int nLen) - { - return new CFontFileType1(sBuffer, nLen, false); - } - - CFontFileType1 *CFontFileType1::LoadFromFile(wchar_t *wsFileName) - { - char *sBuffer; - int nLen = 0; - - if (!(sBuffer = CFontFileBase::ReadFile(wsFileName, &nLen))) - return NULL; - - return new CFontFileType1(sBuffer, nLen, true); - } - - CFontFileType1::CFontFileType1(char *sBuffer, int nLen, bool bFreeData) : - CFontFileBase(sBuffer, nLen, bFreeData) - { - m_sName = NULL; - m_arrEncoding = NULL; - m_bParsed = false; - } - - CFontFileType1::~CFontFileType1() - { - if (m_sName) - MemUtilsFree(m_sName); - - if (m_arrEncoding && m_arrEncoding != c_arrsFontFileType1StandardEncoding) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - MemUtilsFree(m_arrEncoding[nIndex]); - } - MemUtilsFree(m_arrEncoding); - } - } - - char *CFontFileType1::GetName() - { - if (!m_bParsed) - Parse(); - - return m_sName; - } - - char **CFontFileType1::GetEncoding() - { - if (!m_bParsed) - Parse(); - - return m_arrEncoding; - } - - void CFontFileType1::WriteEncoded(char **ppNewEncoding, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - char sBuffer[512]; - char *sLine, *sLine2, *sCurChar; - - // копируем все до строчки /Encoding - for (sLine = (char *)m_sFile; sLine && strncmp(sLine, "/Encoding", 9); sLine = GetNextLine(sLine)); - if (!sLine) - { - // не нашли кодировку, тогда копируем целиком фонт файл - (*pOutputFunc)(pOutputStream, (char *)m_sFile, m_nLen); - return; - } - (*pOutputFunc)(pOutputStream, (char *)m_sFile, sLine - (char *)m_sFile); - - // пишем новую кодировку - (*pOutputFunc)(pOutputStream, "/Encoding 256 array\n", 20); - (*pOutputFunc)(pOutputStream, "0 1 255 {1 index exch /.notdef put} for\n", 40); - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (ppNewEncoding[nIndex]) - { - sprintf(sBuffer, "dup %d /%s put\n", nIndex, ppNewEncoding[nIndex]); - (*pOutputFunc)(pOutputStream, sBuffer, strlen(sBuffer)); - } - } - (*pOutputFunc)(pOutputStream, "readonly def\n", 13); - - if (!strncmp(sLine, "/Encoding StandardEncoding def", 30)) - { - sLine = GetNextLine(sLine); - } - else - { - sCurChar = sLine + 10; - sLine = NULL; - for (; sCurChar < (char *)m_sFile + m_nLen; ++sCurChar) - { - if ((*sCurChar == ' ' || *sCurChar == '\t' || *sCurChar == '\x0a' || *sCurChar == '\x0d' || *sCurChar == '\x0c' || *sCurChar == '\0') && sCurChar + 4 <= (char *)m_sFile + m_nLen && !strncmp(sCurChar + 1, "def", 3)) - { - sLine = sCurChar + 4; - break; - } - } - } - - // У некоторых фонтов две записи /Encoding, поэтому проверяем наличие второй записи - if (sLine) - { - int nIndex; - for (sLine2 = sLine, nIndex = 0; nIndex < 20 && sLine2 && strncmp(sLine2, "/Encoding", 9); sLine2 = GetNextLine(sLine2), ++nIndex); - if (nIndex < 20 && sLine2) - { - (*pOutputFunc)(pOutputStream, sLine, sLine2 - sLine); - if (!strncmp(sLine2, "/Encoding StandardEncoding def", 30)) - { - sLine = GetNextLine(sLine2); - } - else - { - sCurChar = sLine2 + 10; - sLine = NULL; - for (; sCurChar < (char *)m_sFile + m_nLen; ++sCurChar) - { - if ((*sCurChar == ' ' || *sCurChar == '\t' || *sCurChar == '\x0a' || *sCurChar == '\x0d' || *sCurChar == '\x0c' || *sCurChar == '\0') && sCurChar + 4 <= (char *)m_sFile + m_nLen && !strncmp(sCurChar + 1, "def", 3)) - { - sLine = sCurChar + 4; - break; - } - } - } - } - - // копируем все после кодировки - if (sLine) - { - (*pOutputFunc)(pOutputStream, sLine, ((char *)m_sFile + m_nLen) - sLine); - } - } - } - - char *CFontFileType1::GetNextLine(char *sLine) - { - while (sLine < (char *)m_sFile + m_nLen && *sLine != '\x0a' && *sLine != '\x0d') - ++sLine; - - if (sLine < (char *)m_sFile + m_nLen && *sLine == '\x0d') - ++sLine; - - if (sLine < (char *)m_sFile + m_nLen && *sLine == '\x0a') - ++sLine; - - if (sLine >= (char *)m_sFile + m_nLen) - return NULL; - - return sLine; - } - - void CFontFileType1::Parse() - { - char *sLine, *sLine1, *pCur, *pTemp; - char sBuffer[256]; - int nCount, nCode; - int nIndex = 0; - - for (nIndex = 1, sLine = (char *)m_sFile; nIndex <= 100 && sLine && (!m_sName || !m_arrEncoding); ++nIndex) - { - if (!m_sName && !strncmp(sLine, "/FontName", 9)) - { - strncpy(sBuffer, sLine, 255); - sBuffer[255] = '\0'; - if ((pCur = strchr(sBuffer + 9, '/')) && (pCur = strtok(pCur + 1, " \t\n\r"))) - { - m_sName = CopyString(pCur); - } - sLine = GetNextLine(sLine); - - } - else if (!m_arrEncoding && !strncmp(sLine, "/Encoding StandardEncoding def", 30)) - { - m_arrEncoding = c_arrsFontFileType1StandardEncoding; - } - else if (!m_arrEncoding && !strncmp(sLine, "/Encoding 256 array", 19)) - { - m_arrEncoding = (char **)MemUtilsMallocArray(256, sizeof(char *)); - int nJ = 0; - for (nJ = 0; nJ < 256; ++nJ) - { - m_arrEncoding[nJ] = NULL; - } - for (nJ = 0, sLine = GetNextLine(sLine); nJ < 300 && sLine && (sLine1 = GetNextLine(sLine)); ++nJ, sLine = sLine1) - { - if ((nCount = sLine1 - sLine) > 255) - { - nCount = 255; - } - strncpy(sBuffer, sLine, nCount); - sBuffer[nCount] = '\0'; - for (pCur = sBuffer; *pCur == ' ' || *pCur == '\t'; ++pCur); - if (!strncmp(pCur, "dup", 3)) - { - for (pCur += 3; *pCur == ' ' || *pCur == '\t'; ++pCur); - for (pTemp = pCur; *pTemp >= '0' && *pTemp <= '9'; ++pTemp); - if (*pTemp) - { - char nChar = *pTemp; - *pTemp = '\0'; - nCode = atoi(pCur); - *pTemp = nChar; - if (nCode == 8 && *pTemp == '#') - { - nCode = 0; - for (++pTemp; *pTemp >= '0' && *pTemp <= '7'; ++pTemp) - { - nCode = nCode * 8 + (*pTemp - '0'); - } - } - if (nCode < 256) - { - for (pCur = pTemp; *pCur == ' ' || *pCur == '\t'; ++pCur); - if (*pCur == '/') - { - ++pCur; - for (pTemp = pCur; *pTemp && *pTemp != ' ' && *pTemp != '\t'; ++pTemp); - *pTemp = '\0'; - m_arrEncoding[nCode] = CopyString(pCur); - } - } - } - } - else - { - if (strtok(sBuffer, " \t") && (pCur = strtok(NULL, " \t\n\r")) && !strcmp(pCur, "def")) - { - break; - } - } - } - } - else - { - sLine = GetNextLine(sLine); - } - } - - m_bParsed = true; - } -} \ No newline at end of file diff --git a/PdfReader/old/FontFileType1.h b/PdfReader/old/FontFileType1.h deleted file mode 100644 index af322ebcdd..0000000000 --- a/PdfReader/old/FontFileType1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FONT_FILE_TYPE1_H -#define _PDF_READER_FONT_FILE_TYPE1_H - -#include "FontFileBase.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // CFontFileType1 - //------------------------------------------------------------------------ - - class CFontFileType1 : public CFontFileBase - { - public: - - static CFontFileType1 *LoadFromBuffer(char *sBuffer, int nLen); - static CFontFileType1 *LoadFromFile(wchar_t *wsFileName); - - virtual ~CFontFileType1(); - - char *GetName(); - - char **GetEncoding(); - - void WriteEncoded(char **ppNewEncoding, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - private: - - CFontFileType1(char *sBuffer, int nLen, bool bFreeData); - - char *GetNextLine(char *sLine); - void Parse(); - - private: - - char *m_sName; - char **m_arrEncoding; - bool m_bParsed; - }; -} - -#endif // _PDF_READER_FONT_FILE_TYPE1_H diff --git a/PdfReader/old/FontFileType1C.cpp b/PdfReader/old/FontFileType1C.cpp deleted file mode 100644 index e298e31e1d..0000000000 --- a/PdfReader/old/FontFileType1C.cpp +++ /dev/null @@ -1,2927 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include "MemoryUtils.h" -#include "StringExt.h" -#include "FontFileEncodings.h" -#include "FontFileType1C.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - - static char c_sHexChars[17] = "0123456789ABCDEF"; - - //------------------------------------------------------------------------ - // CFontFileType1C - //------------------------------------------------------------------------ - - CFontFileType1C *CFontFileType1C::LoadFromBuffer(char *sBuffer, int nLen) - { - CFontFileType1C *pT1CFF = new CFontFileType1C(sBuffer, nLen, false); - if (!pT1CFF->Parse()) - { - delete pT1CFF; - return NULL; - } - return pT1CFF; - } - - CFontFileType1C *CFontFileType1C::LoadFromFile(wchar_t *wsFileName) - { - char *sBuffer; - int nLen = 0; - - if (!(sBuffer = CFontFileBase::ReadFile(wsFileName, &nLen))) - return NULL; - - CFontFileType1C *pT1CFF = new CFontFileType1C(sBuffer, nLen, true); - - if (!pT1CFF->Parse()) - { - delete pT1CFF; - return NULL; - } - return pT1CFF; - } - - CFontFileType1C::CFontFileType1C(char *sBuffer, int nLen, bool bFreeData) : - CFontFileBase(sBuffer, nLen, bFreeData) - { - m_seName = NULL; - m_arrEncoding = NULL; - m_pPrivateDicts = NULL; - m_pnFDSelect = NULL; - m_pnCharset = NULL; - } - - CFontFileType1C::~CFontFileType1C() - { - if (m_seName) - delete m_seName; - - if (m_arrEncoding && m_arrEncoding != c_arrsFontFileType1StandardEncoding && m_arrEncoding != c_arrsFontFileType1ExpertEncoding) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - MemUtilsFree(m_arrEncoding[nIndex]); - } - MemUtilsFree(m_arrEncoding); - } - - if (m_pPrivateDicts) - { - MemUtilsFree(m_pPrivateDicts); - } - if (m_pnFDSelect) - { - MemUtilsFree(m_pnFDSelect); - } - - if (m_pnCharset && m_pnCharset != c_arrnFontFileType1CISOAdobeCharset && m_pnCharset != c_arrnFontFileType1CExpertCharset && m_pnCharset != c_arrnFontFileType1CExpertSubsetCharset) - { - MemUtilsFree(m_pnCharset); - } - } - - char *CFontFileType1C::GetName() - { - return m_seName ? m_seName->GetBuffer() : (char *)NULL; - } - - char **CFontFileType1C::GetEncoding() - { - return m_arrEncoding; - } - - unsigned short *CFontFileType1C::GetCIDToGIDMap(int *arrCIDs) - { - if (m_oTopDict.nFirstOperator != 0x0c1e) - { - *arrCIDs = 0; - return NULL; - } - - int nCount = 0; - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - if (m_pnCharset[nIndex] > nCount) - { - nCount = m_pnCharset[nIndex]; - } - } - ++nCount; - unsigned short *pMap = (unsigned short *)MemUtilsMallocArray(nCount, sizeof(unsigned short)); - memset(pMap, 0, nCount * sizeof(unsigned short)); - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - pMap[m_pnCharset[nIndex]] = nIndex; - } - *arrCIDs = nCount; - return pMap; - } - - void CFontFileType1C::ToType1(char *sPSName, char **ppNewEncoding, bool bASKII, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - int nPSNameLen; - StringExt *seBuffer; - char sBuf[256]; - - if (sPSName) - { - nPSNameLen = strlen(sPSName); - } - else - { - sPSName = m_seName->GetBuffer(); - nPSNameLen = m_seName->GetLength(); - } - - bool bSuccess = true; - (*pOutputFunc)(pOutputStream, "%!FontType1-1.0: ", 17); - (*pOutputFunc)(pOutputStream, sPSName, nPSNameLen); - if (m_oTopDict.nVersionSID != 0) - { - GetString(m_oTopDict.nVersionSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - } - (*pOutputFunc)(pOutputStream, "\n", 1); - // Для словаря нужно место для 12 полей: следующие 9 + - // Private и CharStrings (в eexec секции) и FID. - (*pOutputFunc)(pOutputStream, "12 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontInfo 10 dict dup begin\n", 28); - if (m_oTopDict.nVersionSID != 0) - { - (*pOutputFunc)(pOutputStream, "/version (", 10); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nNoticeSID != 0) - { - GetString(m_oTopDict.nNoticeSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, "/Notice (", 9); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nCopyrightSID != 0) - { - GetString(m_oTopDict.nCopyrightSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, "/Copyright (", 12); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nFullNameSID != 0) - { - GetString(m_oTopDict.nFullNameSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, "/FullName (", 11); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nFamilyNameSID != 0) - { - GetString(m_oTopDict.nFamilyNameSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, "/FamilyName (", 13); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nWeightSID != 0) - { - GetString(m_oTopDict.nWeightSID, sBuf, &bSuccess); - (*pOutputFunc)(pOutputStream, "/Weight (", 9); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") readonly def\n", 15); - } - if (m_oTopDict.nIsFixedPitch) - { - (*pOutputFunc)(pOutputStream, "/isFixedPitch true def\n", 23); - } - else - { - (*pOutputFunc)(pOutputStream, "/isFixedPitch false def\n", 24); - } - - seBuffer = StringExt::Format("/ItalicAngle {0:.4g} def\n", m_oTopDict.dItalicAngle); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/UnderlinePosition {0:.4g} def\n", m_oTopDict.dUnderlinePosition); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/UnderlineThickness {0:.4g} def\n", m_oTopDict.dUnderlineThickness); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "end readonly def\n", 17); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, nPSNameLen); - (*pOutputFunc)(pOutputStream, " def\n", 5); - - seBuffer = StringExt::Format("/PaintType {0:d} def\n", m_oTopDict.nPaintType); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/FontType 1 def\n", 16); - seBuffer = StringExt::Format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] readonly def\n", m_oTopDict.arrdFontMatrix[0], m_oTopDict.arrdFontMatrix[1], m_oTopDict.arrdFontMatrix[2], m_oTopDict.arrdFontMatrix[3], m_oTopDict.arrdFontMatrix[4], m_oTopDict.arrdFontMatrix[5]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] readonly def\n", m_oTopDict.arrdFontBBox[0], m_oTopDict.arrdFontBBox[1], m_oTopDict.arrdFontBBox[2], m_oTopDict.arrdFontBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/StrokeWidth {0:.4g} def\n", m_oTopDict.dStrokeWidth); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - if (m_oTopDict.nUniqueID != 0) - { - seBuffer = StringExt::Format("/UniqueID {0:d} def\n", m_oTopDict.nUniqueID); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - - // Запись кодировки - (*pOutputFunc)(pOutputStream, "/Encoding ", 10); - if (!ppNewEncoding && m_arrEncoding == c_arrsFontFileType1ExpertEncoding) - { - (*pOutputFunc)(pOutputStream, "StandardEncoding def\n", 21); - } - else - { - (*pOutputFunc)(pOutputStream, "256 array\n", 10); - (*pOutputFunc)(pOutputStream, "0 1 255 {1 index exch /.notdef put} for\n", 40); - char **ppEnc = ppNewEncoding ? ppNewEncoding : m_arrEncoding; - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (ppEnc[nIndex]) - { - seBuffer = StringExt::Format("dup {0:d} /{1:s} put\n", nIndex, ppEnc[nIndex]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - } - (*pOutputFunc)(pOutputStream, "readonly def\n", 13); - } - (*pOutputFunc)(pOutputStream, "currentdict end\n", 16); - - // Бинарная секция (eexec) - Type1CEexecBuf oEexecBuffer; - (*pOutputFunc)(pOutputStream, "currentfile eexec\n", 18); - oEexecBuffer.pOutputFunc = pOutputFunc; - oEexecBuffer.pOutputStream = pOutputStream; - oEexecBuffer.bASKII = bASKII; - oEexecBuffer.unEncryptionKey = 55665; - oEexecBuffer.nLine = 0; - - // Private Dictionary - EexecWrite(&oEexecBuffer, "\x83\xca\x73\xd5"); - EexecWrite(&oEexecBuffer, "dup /Private 32 dict dup begin\n"); - EexecWrite(&oEexecBuffer, "/RD {string currentfile exch readstring pop} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/ND {noaccess def} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/NP {noaccess put} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/MinFeature {16 16} def\n"); - EexecWrite(&oEexecBuffer, "/password 5839 def\n"); - - if (m_pPrivateDicts[0].nBlueValues) - { - EexecWrite(&oEexecBuffer, "/BlueValues ["); - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nBlueValues; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:d}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrnBlueValues[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[0].nOtherBlues) - { - EexecWrite(&oEexecBuffer, "/OtherBlues ["); - - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nOtherBlues; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:d}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrnOtherBlues[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[0].nFamilyBlues) - { - EexecWrite(&oEexecBuffer, "/FamilyBlues ["); - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nFamilyBlues; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:d}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrnFamilyBlues[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - - if (m_pPrivateDicts[0].nFamilyOtherBlues) - { - EexecWrite(&oEexecBuffer, "/FamilyOtherBlues ["); - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nFamilyOtherBlues; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:d}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrnFamilyOtherBlues[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[0].dBlueScale != 0.039625) - { - seBuffer = StringExt::Format("/BlueScale {0:.4g} def\n", m_pPrivateDicts[0].dBlueScale); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].nBlueShift != 7) - { - seBuffer = StringExt::Format("/BlueShift {0:d} def\n", m_pPrivateDicts[0].nBlueShift); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].nBlueFuzz != 1) - { - seBuffer = StringExt::Format("/BlueFuzz {0:d} def\n", m_pPrivateDicts[0].nBlueFuzz); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].bHasStdHW) - { - seBuffer = StringExt::Format("/StdHW [{0:.4g}] def\n", m_pPrivateDicts[0].dStdHW); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].bHasStdVW) - { - seBuffer = StringExt::Format("/StdVW [{0:.4g}] def\n", m_pPrivateDicts[0].dStdVW); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].nStemSnapH) - { - EexecWrite(&oEexecBuffer, "/StemSnapH ["); - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nStemSnapH; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrdStemSnapH[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[0].nStemSnapV) - { - EexecWrite(&oEexecBuffer, "/StemSnapV ["); - for (int nIndex = 0; nIndex < m_pPrivateDicts[0].nStemSnapV; ++nIndex) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", nIndex > 0 ? " " : "", m_pPrivateDicts[0].arrdStemSnapV[nIndex]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[0].bHasForceBold) - { - seBuffer = StringExt::Format("/ForceBold {0:s} def\n", m_pPrivateDicts[0].bForceBold ? "true" : "false"); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].dForceBoldThreshold != 0) - { - seBuffer = StringExt::Format("/ForceBoldThreshold {0:.4g} def\n", m_pPrivateDicts[0].dForceBoldThreshold); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].nLanguageGroup != 0) - { - seBuffer = StringExt::Format("/LanguageGroup {0:d} def\n", m_pPrivateDicts[0].nLanguageGroup); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[0].dExpansionFactor != 0.06) - { - seBuffer = StringExt::Format("/ExpansionFactor {0:.4g} def\n", m_pPrivateDicts[0].dExpansionFactor); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - - bSuccess = true; - Type1CIndex oSubrIndex; - GetIndex(m_pPrivateDicts[0].nSubrsOffset, &oSubrIndex, &bSuccess); - if (!bSuccess) - { - oSubrIndex.nPos = -1; - } - - // CharStrings - seBuffer = StringExt::Format("2 index /CharStrings {0:d} dict dup begin\n", m_nGlyphsCount); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - Type1CIndexVal oIndexVal; - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - bSuccess = true; - GetIndexVal(&m_oCharStringsIndex, nIndex, &oIndexVal, &bSuccess); - if (bSuccess) - { - GetString(m_pnCharset[nIndex], sBuf, &bSuccess); - if (bSuccess) - { - EexecConvertGlyph(&oEexecBuffer, sBuf, oIndexVal.nPos, oIndexVal.nLen, &oSubrIndex, &m_pPrivateDicts[0]); - } - } - } - EexecWrite(&oEexecBuffer, "end\n"); - EexecWrite(&oEexecBuffer, "end\n"); - EexecWrite(&oEexecBuffer, "readonly put\n"); - EexecWrite(&oEexecBuffer, "noaccess put\n"); - EexecWrite(&oEexecBuffer, "dup /FontName get exch definefont pop\n"); - EexecWrite(&oEexecBuffer, "mark currentfile closefile\n"); - - // Trailer - if (bASKII && oEexecBuffer.nLine > 0) - { - (*pOutputFunc)(pOutputStream, "\n", 1); - } - for (int nIndex = 0; nIndex < 8; ++nIndex) - { - (*pOutputFunc)(pOutputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); - } - (*pOutputFunc)(pOutputStream, "cleartomark\n", 12); - } - - void CFontFileType1C::ToCIDType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - StringExt *charStrings; - int *charStringOffsets; - StringExt *seBuffer; - char sBuf[256]; - bool bSuccess = true; - int nGID = 0, i, j, k; - - // Вычислим количество CID и построим отображение CID->GID - int nCIDsCount = 0; - for (i = 0; i < m_nGlyphsCount; ++i) - { - if (m_pnCharset[i] >= nCIDsCount) - { - nCIDsCount = m_pnCharset[i] + 1; - } - } - int *arrCIDdMap = (int *)MemUtilsMallocArray(nCIDsCount, sizeof(int)); - for (i = 0; i < nCIDsCount; ++i) - { - arrCIDdMap[i] = -1; - } - for (i = 0; i < m_nGlyphsCount; ++i) - { - arrCIDdMap[m_pnCharset[i]] = i; - } - - // Build Charstrings - charStrings = new StringExt(); - charStringOffsets = (int *)MemUtilsMallocArray(nCIDsCount + 1, sizeof(int)); - for (i = 0; i < nCIDsCount; ++i) - { - charStringOffsets[i] = charStrings->GetLength(); - if ((nGID = arrCIDdMap[i]) >= 0) - { - Type1CIndexVal oIndexVal; - bSuccess = true; - GetIndexVal(&m_oCharStringsIndex, nGID, &oIndexVal, &bSuccess); - if (bSuccess) - { - Type1CIndex oSubrIndex; - GetIndex(m_pPrivateDicts[m_pnFDSelect[nGID]].nSubrsOffset, &oSubrIndex, &bSuccess); - if (!bSuccess) - { - oSubrIndex.nPos = -1; - } - ConvertGlyph(oIndexVal.nPos, oIndexVal.nLen, charStrings, &oSubrIndex, &m_pPrivateDicts[m_pnFDSelect[nGID]], true); - } - } - } - charStringOffsets[nCIDsCount] = charStrings->GetLength(); - - // Вычислим nNeedBytes = количество байт, необходимых для charstring offsets - int nNeedBytes = 0; - i = (nCIDsCount + 1) * 5 + charStrings->GetLength(); - if (i < 0x100) - { - nNeedBytes = 1; - } - else if (i < 0x10000) - { - nNeedBytes = 2; - } - else if (i < 0x1000000) - { - nNeedBytes = 3; - } - else - { - nNeedBytes = 4; - } - - // Начинаем запись Font Dictionary - (*pOutputFunc)(pOutputStream, "/CIDInit /ProcSet findresource begin\n", 37); - (*pOutputFunc)(pOutputStream, "20 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/CIDFontName /", 14); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, " def\n", 5); - (*pOutputFunc)(pOutputStream, "/CIDFontType 0 def\n", 19); - (*pOutputFunc)(pOutputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); - - if (m_oTopDict.nRegistrySID > 0 && m_oTopDict.nOrderingSID > 0) - { - bSuccess = true; - GetString(m_oTopDict.nRegistrySID, sBuf, &bSuccess); - if (bSuccess) - { - (*pOutputFunc)(pOutputStream, " /Registry (", 13); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") def\n", 6); - } - bSuccess = true; - GetString(m_oTopDict.nOrderingSID, sBuf, &bSuccess); - if (bSuccess) - { - (*pOutputFunc)(pOutputStream, " /Ordering (", 13); - (*pOutputFunc)(pOutputStream, sBuf, strlen(sBuf)); - (*pOutputFunc)(pOutputStream, ") def\n", 6); - } - } - else - { - (*pOutputFunc)(pOutputStream, " /Registry (Adobe) def\n", 24); - (*pOutputFunc)(pOutputStream, " /Ordering (Identity) def\n", 27); - } - seBuffer = StringExt::Format(" /Supplement {0:d} def\n", m_oTopDict.nSupplement); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "end def\n", 8); - - if (m_oTopDict.bHasFontMatrix) - { - seBuffer = StringExt::Format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n", m_oTopDict.arrdFontMatrix[0], m_oTopDict.arrdFontMatrix[1], m_oTopDict.arrdFontMatrix[2], m_oTopDict.arrdFontMatrix[3], m_oTopDict.arrdFontMatrix[4], m_oTopDict.arrdFontMatrix[5]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - else if (m_pPrivateDicts[0].bHasFontMatrix) - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - } - else - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); - } - seBuffer = StringExt::Format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] def\n", m_oTopDict.arrdFontBBox[0], m_oTopDict.arrdFontBBox[1], m_oTopDict.arrdFontBBox[2], m_oTopDict.arrdFontBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/FontInfo 1 dict dup begin\n", 27); - (*pOutputFunc)(pOutputStream, " /FSType 8 def\n", 16); - (*pOutputFunc)(pOutputStream, "end def\n", 8); - - // CIDFont-specific - seBuffer = StringExt::Format("/CIDCount {0:d} def\n", nCIDsCount); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/FDBytes 1 def\n", 15); - seBuffer = StringExt::Format("/GDBytes {0:d} def\n", nNeedBytes); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/CIDMapOffset 0 def\n", 20); - - if (m_oTopDict.nPaintType != 0) - { - seBuffer = StringExt::Format("/PaintType {0:d} def\n", m_oTopDict.nPaintType); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/StrokeWidth {0:.4g} def\n", m_oTopDict.dStrokeWidth); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - - // FDArray - seBuffer = StringExt::Format("/FDArray {0:d} array\n", m_nFDsCount); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - for (i = 0; i < m_nFDsCount; ++i) - { - seBuffer = StringExt::Format("dup {0:d} 10 dict begin\n", i); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/FontType 1 def\n", 16); - - if (m_pPrivateDicts[i].bHasFontMatrix) - { - seBuffer = StringExt::Format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n", m_pPrivateDicts[i].arrdFontMatrix[0], m_pPrivateDicts[i].arrdFontMatrix[1], m_pPrivateDicts[i].arrdFontMatrix[2], m_pPrivateDicts[i].arrdFontMatrix[3], m_pPrivateDicts[i].arrdFontMatrix[4], m_pPrivateDicts[i].arrdFontMatrix[5]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - else - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - } - seBuffer = StringExt::Format("/PaintType {0:d} def\n", m_oTopDict.nPaintType); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/Private 32 dict begin\n", 23); - if (m_pPrivateDicts[i].nBlueValues) - { - (*pOutputFunc)(pOutputStream, "/BlueValues [", 13); - for (j = 0; j < m_pPrivateDicts[i].nBlueValues; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:d}", j > 0 ? " " : "", m_pPrivateDicts[i].arrnBlueValues[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].nOtherBlues) - { - (*pOutputFunc)(pOutputStream, "/OtherBlues [", 13); - for (j = 0; j < m_pPrivateDicts[i].nOtherBlues; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:d}", j > 0 ? " " : "", m_pPrivateDicts[i].arrnOtherBlues[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].nFamilyBlues) - { - (*pOutputFunc)(pOutputStream, "/FamilyBlues [", 14); - for (j = 0; j < m_pPrivateDicts[i].nFamilyBlues; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:d}", j > 0 ? " " : "", m_pPrivateDicts[i].arrnFamilyBlues[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].nFamilyOtherBlues) - { - (*pOutputFunc)(pOutputStream, "/FamilyOtherBlues [", 19); - for (j = 0; j < m_pPrivateDicts[i].nFamilyOtherBlues; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:d}", j > 0 ? " " : "", m_pPrivateDicts[i].arrnFamilyOtherBlues[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].dBlueScale != 0.039625) - { - seBuffer = StringExt::Format("/BlueScale {0:.4g} def\n", m_pPrivateDicts[i].dBlueScale); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].nBlueShift != 7) - { - seBuffer = StringExt::Format("/BlueShift {0:d} def\n", m_pPrivateDicts[i].nBlueShift); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].nBlueFuzz != 1) - { - seBuffer = StringExt::Format("/BlueFuzz {0:d} def\n", m_pPrivateDicts[i].nBlueFuzz); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].bHasStdHW) - { - seBuffer = StringExt::Format("/StdHW [{0:.4g}] def\n", m_pPrivateDicts[i].dStdHW); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].bHasStdVW) - { - seBuffer = StringExt::Format("/StdVW [{0:.4g}] def\n", m_pPrivateDicts[i].dStdVW); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].nStemSnapH) - { - (*pOutputFunc)(pOutputStream, "/StemSnapH [", 12); - for (j = 0; j < m_pPrivateDicts[i].nStemSnapH; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", j > 0 ? " " : "", m_pPrivateDicts[i].arrdStemSnapH[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].nStemSnapV) - { - (*pOutputFunc)(pOutputStream, "/StemSnapV [", 12); - for (j = 0; j < m_pPrivateDicts[i].nStemSnapV; ++j) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", j > 0 ? " " : "", m_pPrivateDicts[i].arrdStemSnapV[j]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "] def\n", 6); - } - if (m_pPrivateDicts[i].bHasForceBold) - { - seBuffer = StringExt::Format("/ForceBold {0:s} def\n", m_pPrivateDicts[i].bForceBold ? "true" : "false"); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].dForceBoldThreshold != 0) - { - seBuffer = StringExt::Format("/ForceBoldThreshold {0:.4g} def\n", m_pPrivateDicts[i].dForceBoldThreshold); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].nLanguageGroup != 0) - { - seBuffer = StringExt::Format("/LanguageGroup {0:d} def\n", m_pPrivateDicts[i].nLanguageGroup); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (m_pPrivateDicts[i].dExpansionFactor != 0.06) - { - seBuffer = StringExt::Format("/ExpansionFactor {0:.4g} def\n", m_pPrivateDicts[i].dExpansionFactor); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "currentdict end def\n", 20); - (*pOutputFunc)(pOutputStream, "currentdict end put\n", 20); - } - (*pOutputFunc)(pOutputStream, "def\n", 4); - - // Binary section - int nOffset = (nCIDsCount + 1) * (1 + nNeedBytes); - seBuffer = StringExt::Format("(Hex) {0:d} StartData\n", nOffset + charStrings->GetLength()); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - int nLen = 0; - - // write the charstring offset (CIDMap) table - for (i = 0; i <= nCIDsCount; i += 6) - { - for (j = 0; j < 6 && i + j <= nCIDsCount; ++j) - { - if (i + j < nCIDsCount && arrCIDdMap[i + j] >= 0) - { - sBuf[0] = (char)m_pnFDSelect[arrCIDdMap[i + j]]; - } - else - { - sBuf[0] = (char)0; - } - nLen = nOffset + charStringOffsets[i + j]; - for (k = nNeedBytes; k >= 1; --k) - { - sBuf[k] = (char)(nLen & 0xff); - nLen >>= 8; - } - for (k = 0; k <= nNeedBytes; ++k) - { - seBuffer = StringExt::Format("{0:02x}", sBuf[k] & 0xff); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - } - (*pOutputFunc)(pOutputStream, "\n", 1); - } - - // Charstring - nLen = charStrings->GetLength(); - for (i = 0; i < nLen; i += 32) - { - for (j = 0; j < 32 && i + j < nLen; ++j) - { - seBuffer = StringExt::Format("{0:02x}", charStrings->GetAt(i + j) & 0xff); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (i + 32 >= nLen) - { - (*pOutputFunc)(pOutputStream, ">", 1); - } - (*pOutputFunc)(pOutputStream, "\n", 1); - } - - MemUtilsFree(charStringOffsets); - delete charStrings; - MemUtilsFree(arrCIDdMap); - } - - void CFontFileType1C::ToType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream) - { - StringExt *seBuffer; - bool bSuccess = true; - int i, j, k; - - int nCurFD = 0; - - // Вычислим количество CID и построим отображение CID->GID - int nCIDsCount = 0; - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - if (m_pnCharset[nIndex] >= nCIDsCount) - { - nCIDsCount = m_pnCharset[nIndex] + 1; - } - } - int *arrCIDMap = (int *)MemUtilsMallocArray(nCIDsCount, sizeof(int)); - for (int nIndex = 0; nIndex < nCIDsCount; ++nIndex) - { - arrCIDMap[nIndex] = -1; - } - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - arrCIDMap[m_pnCharset[nIndex]] = nIndex; - } - - // Запись Type 1 фонта - for (i = 0; i < nCIDsCount; i += 256) - { - // Игнорируем CID = 0, т.е. ".notdef" - nCurFD = 0; - for (j = ((i == 0) ? 1 : 0); j < 256 && i + j < nCIDsCount; ++j) - { - if (arrCIDMap[i + j] >= 0) - { - nCurFD = m_pnFDSelect[arrCIDMap[i + j]]; - break; - } - } - - // Font Dictionary (незашифрованная часть) - (*pOutputFunc)(pOutputStream, "16 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - - seBuffer = StringExt::Format("_{0:02x} def\n", i >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - (*pOutputFunc)(pOutputStream, "/FontType 1 def\n", 16); - if (m_pPrivateDicts[nCurFD].bHasFontMatrix) - { - seBuffer = StringExt::Format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n", m_pPrivateDicts[nCurFD].arrdFontMatrix[0], m_pPrivateDicts[nCurFD].arrdFontMatrix[1], m_pPrivateDicts[nCurFD].arrdFontMatrix[2], m_pPrivateDicts[nCurFD].arrdFontMatrix[3], m_pPrivateDicts[nCurFD].arrdFontMatrix[4], m_pPrivateDicts[nCurFD].arrdFontMatrix[5]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - else if (m_oTopDict.bHasFontMatrix) - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - } - else - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); - } - seBuffer = StringExt::Format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] def\n", m_oTopDict.arrdFontBBox[0], m_oTopDict.arrdFontBBox[1], m_oTopDict.arrdFontBBox[2], m_oTopDict.arrdFontBBox[3]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - seBuffer = StringExt::Format("/PaintType {0:d} def\n", m_oTopDict.nPaintType); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - - if (m_oTopDict.nPaintType != 0) - { - seBuffer = StringExt::Format("/StrokeWidth {0:.4g} def\n", m_oTopDict.dStrokeWidth); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "/Encoding 256 array\n", 20); - for (j = 0; j < 256 && i + j < nCIDsCount; ++j) - { - seBuffer = StringExt::Format("dup {0:d} /c{1:02x} put\n", j, j); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - if (j < 256) - { - seBuffer = StringExt::Format("{0:d} 1 255 {{ 1 index exch /.notdef put }} for\n", j); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - (*pOutputFunc)(pOutputStream, "readonly def\n", 13); - (*pOutputFunc)(pOutputStream, "currentdict end\n", 16); - - // start the binary section - Type1CEexecBuf oEexecBuffer; - (*pOutputFunc)(pOutputStream, "currentfile eexec\n", 18); - oEexecBuffer.pOutputFunc = pOutputFunc; - oEexecBuffer.pOutputStream = pOutputStream; - oEexecBuffer.bASKII = true; - oEexecBuffer.unEncryptionKey = 55665; - oEexecBuffer.nLine = 0; - - // start the private dictionary - EexecWrite(&oEexecBuffer, "\x83\xca\x73\xd5"); - EexecWrite(&oEexecBuffer, "dup /Private 32 dict dup begin\n"); - EexecWrite(&oEexecBuffer, "/RD {string currentfile exch readstring pop} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/ND {noaccess def} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/NP {noaccess put} executeonly def\n"); - EexecWrite(&oEexecBuffer, "/MinFeature {16 16} def\n"); - EexecWrite(&oEexecBuffer, "/password 5839 def\n"); - if (m_pPrivateDicts[nCurFD].nBlueValues) - { - EexecWrite(&oEexecBuffer, "/BlueValues ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nBlueValues; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:d}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrnBlueValues[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].nOtherBlues) - { - EexecWrite(&oEexecBuffer, "/OtherBlues ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nOtherBlues; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:d}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrnOtherBlues[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].nFamilyBlues) - { - EexecWrite(&oEexecBuffer, "/FamilyBlues ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nFamilyBlues; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:d}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrnFamilyBlues[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].nFamilyOtherBlues) - { - EexecWrite(&oEexecBuffer, "/FamilyOtherBlues ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nFamilyOtherBlues; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:d}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrnFamilyOtherBlues[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].dBlueScale != 0.039625) - { - seBuffer = StringExt::Format("/BlueScale {0:.4g} def\n", m_pPrivateDicts[nCurFD].dBlueScale); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].nBlueShift != 7) - { - seBuffer = StringExt::Format("/BlueShift {0:d} def\n", m_pPrivateDicts[nCurFD].nBlueShift); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].nBlueFuzz != 1) - { - seBuffer = StringExt::Format("/BlueFuzz {0:d} def\n", m_pPrivateDicts[nCurFD].nBlueFuzz); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].bHasStdHW) - { - seBuffer = StringExt::Format("/StdHW [{0:.4g}] def\n", m_pPrivateDicts[nCurFD].dStdHW); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].bHasStdVW) - { - seBuffer = StringExt::Format("/StdVW [{0:.4g}] def\n", m_pPrivateDicts[nCurFD].dStdVW); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].nStemSnapH) - { - EexecWrite(&oEexecBuffer, "/StemSnapH ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nStemSnapH; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrdStemSnapH[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].nStemSnapV) - { - EexecWrite(&oEexecBuffer, "/StemSnapV ["); - for (k = 0; k < m_pPrivateDicts[nCurFD].nStemSnapV; ++k) - { - seBuffer = StringExt::Format("{0:s}{1:.4g}", k > 0 ? " " : "", m_pPrivateDicts[nCurFD].arrdStemSnapV[k]); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - EexecWrite(&oEexecBuffer, "] def\n"); - } - if (m_pPrivateDicts[nCurFD].bHasForceBold) - { - seBuffer = StringExt::Format("/ForceBold {0:s} def\n", m_pPrivateDicts[nCurFD].bForceBold ? "true" : "false"); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].dForceBoldThreshold != 0) - { - seBuffer = StringExt::Format("/ForceBoldThreshold {0:.4g} def\n", m_pPrivateDicts[nCurFD].dForceBoldThreshold); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].nLanguageGroup != 0) - { - seBuffer = StringExt::Format("/LanguageGroup {0:d} def\n", m_pPrivateDicts[nCurFD].nLanguageGroup); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - if (m_pPrivateDicts[nCurFD].dExpansionFactor != 0.06) - { - seBuffer = StringExt::Format("/ExpansionFactor {0:.4g} def\n", m_pPrivateDicts[nCurFD].dExpansionFactor); - EexecWrite(&oEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - } - - bSuccess = true; - Type1CIndex oSubrIndex; - GetIndex(m_pPrivateDicts[nCurFD].nSubrsOffset, &oSubrIndex, &bSuccess); - if (!bSuccess) - { - oSubrIndex.nPos = -1; - } - - // CharStrings - EexecWrite(&oEexecBuffer, "2 index /CharStrings 256 dict dup begin\n"); - - // .notdef CharString - Type1CIndexVal oIndexVal; - bSuccess = true; - GetIndexVal(&m_oCharStringsIndex, 0, &oIndexVal, &bSuccess); - if (bSuccess) - { - EexecConvertGlyph(&oEexecBuffer, ".notdef", oIndexVal.nPos, oIndexVal.nLen, &oSubrIndex, &m_pPrivateDicts[nCurFD]); - } - - // CharStrings - for (j = 0; j < 256 && i + j < nCIDsCount; ++j) - { - if (arrCIDMap[i + j] >= 0) - { - bSuccess = true; - GetIndexVal(&m_oCharStringsIndex, arrCIDMap[i + j], &oIndexVal, &bSuccess); - if (bSuccess) - { - seBuffer = StringExt::Format("c{0:02x}", j); - EexecConvertGlyph(&oEexecBuffer, seBuffer->GetBuffer(), oIndexVal.nPos, oIndexVal.nLen, &oSubrIndex, &m_pPrivateDicts[nCurFD]); - delete seBuffer; - } - } - } - EexecWrite(&oEexecBuffer, "end\n"); - EexecWrite(&oEexecBuffer, "end\n"); - EexecWrite(&oEexecBuffer, "readonly put\n"); - EexecWrite(&oEexecBuffer, "noaccess put\n"); - EexecWrite(&oEexecBuffer, "dup /FontName get exch definefont pop\n"); - EexecWrite(&oEexecBuffer, "mark currentfile closefile\n"); - - // trailer - if (oEexecBuffer.nLine > 0) - { - (*pOutputFunc)(pOutputStream, "\n", 1); - } - for (j = 0; j < 8; ++j) - { - (*pOutputFunc)(pOutputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); - } - (*pOutputFunc)(pOutputStream, "cleartomark\n", 12); - } - - // write the Type 0 parent font - (*pOutputFunc)(pOutputStream, "16 dict begin\n", 14); - (*pOutputFunc)(pOutputStream, "/FontName /", 11); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - (*pOutputFunc)(pOutputStream, " def\n", 5); - (*pOutputFunc)(pOutputStream, "/FontType 0 def\n", 16); - if (m_oTopDict.bHasFontMatrix) - { - seBuffer = StringExt::Format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} {4:.8g} {5:.8g}] def\n", m_oTopDict.arrdFontMatrix[0], m_oTopDict.arrdFontMatrix[1], m_oTopDict.arrdFontMatrix[2], m_oTopDict.arrdFontMatrix[3], m_oTopDict.arrdFontMatrix[4], m_oTopDict.arrdFontMatrix[5]); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - else - { - (*pOutputFunc)(pOutputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); - } - (*pOutputFunc)(pOutputStream, "/FMapType 2 def\n", 16); - (*pOutputFunc)(pOutputStream, "/Encoding [\n", 12); - - for (i = 0; i < nCIDsCount; i += 256) - { - seBuffer = StringExt::Format("{0:d}\n", i >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - - (*pOutputFunc)(pOutputStream, "] def\n", 6); - (*pOutputFunc)(pOutputStream, "/FDepVector [\n", 14); - - for (i = 0; i < nCIDsCount; i += 256) - { - (*pOutputFunc)(pOutputStream, "/", 1); - (*pOutputFunc)(pOutputStream, sPSName, strlen(sPSName)); - seBuffer = StringExt::Format("_{0:02x} findfont\n", i >> 8); - (*pOutputFunc)(pOutputStream, seBuffer->GetBuffer(), seBuffer->GetLength()); - delete seBuffer; - } - - (*pOutputFunc)(pOutputStream, "] def\n", 6); - (*pOutputFunc)(pOutputStream, "FontName currentdict end definefont pop\n", 40); - - MemUtilsFree(arrCIDMap); - } - - void CFontFileType1C::EexecConvertGlyph(Type1CEexecBuf *pEexecBuffer, char *sGlyphName, int nOffset, int nBytes, Type1CIndex *pSubrIndex, Type1CPrivateDict *pDict) - { - StringExt *seCharBuffer = new StringExt(); - ConvertGlyph(nOffset, nBytes, seCharBuffer, pSubrIndex, pDict, true); - - StringExt *seBuffer = StringExt::Format("/{0:s} {1:d} RD ", sGlyphName, seCharBuffer->GetLength()); - EexecWrite(pEexecBuffer, seBuffer->GetBuffer()); - delete seBuffer; - EexecWriteCharString(pEexecBuffer, (unsigned char *)seCharBuffer->GetBuffer(), seCharBuffer->GetLength()); - EexecWrite(pEexecBuffer, " ND\n"); - - delete seCharBuffer; - } - - void CFontFileType1C::ConvertGlyph(int nOffset, int nBytes, StringExt *seCharBuffer, Type1CIndex *pSubrIndex, Type1CPrivateDict *pDict, bool bTop) - { - Type1CIndexVal oIndexVal; - double dTemp = 0, dX = 0, dY = 0; - unsigned char unByte = 0; - int nSubrBias = 0, k = 0; - bool bDouble = false; - - int nStart = seCharBuffer->GetLength(); - - if (bTop) - { - seCharBuffer->Append((char)73); - seCharBuffer->Append((char)58); - seCharBuffer->Append((char)147); - seCharBuffer->Append((char)134); - m_nOperatorsCount = 0; - m_nHints = 0; - m_bFirstOperator = true; - m_bOpenPath = false; - } - - int nPos = nOffset; - while (nPos < nOffset + nBytes) - { - bool bSuccess = true; - nPos = GetOperator(nPos, true, &bSuccess); - if (!bSuccess) - break; - - if (!m_arrOperators[m_nOperatorsCount - 1].bIsNumber) - { - --m_nOperatorsCount; - switch (m_arrOperators[m_nOperatorsCount].nOperator) - { - case 0x0001: // hstem - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hstem" - } - dTemp = 0; - bDouble = false; - for (k = 0; k < m_nOperatorsCount; k += 2) - { - // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints - if (m_arrOperators[k + 1].dNumber < 0) - { - dTemp += m_arrOperators[k].dNumber + m_arrOperators[k + 1].dNumber; - bDouble |= m_arrOperators[k].bIsFloat | m_arrOperators[k + 1].bIsFloat; - ConvertNum(dTemp, bDouble, seCharBuffer); - ConvertNum(-m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - } - else - { - dTemp += m_arrOperators[k].dNumber; - bDouble |= m_arrOperators[k].bIsFloat; - ConvertNum(dTemp, bDouble, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - dTemp += m_arrOperators[k + 1].dNumber; - bDouble |= m_arrOperators[k + 1].bIsFloat; - } - seCharBuffer->Append((char)1); - } - m_nHints += m_nOperatorsCount / 2; - m_nOperatorsCount = 0; - break; - case 0x0003: // vstem - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 vstem" - } - dTemp = 0; - bDouble = false; - for (k = 0; k < m_nOperatorsCount; k += 2) - { - // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints - if (m_arrOperators[k + 1].dNumber < 0) - { - dTemp += m_arrOperators[k].dNumber + m_arrOperators[k + 1].dNumber; - bDouble |= m_arrOperators[k].bIsFloat | m_arrOperators[k + 1].bIsFloat; - ConvertNum(dTemp, bDouble, seCharBuffer); - ConvertNum(-m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - } - else - { - dTemp += m_arrOperators[k].dNumber; - bDouble |= m_arrOperators[k].bIsFloat; - ConvertNum(dTemp, bDouble, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - dTemp += m_arrOperators[k + 1].dNumber; - bDouble |= m_arrOperators[k + 1].bIsFloat; - } - seCharBuffer->Append((char)3); - } - m_nHints += m_nOperatorsCount / 2; - m_nOperatorsCount = 0; - break; - case 0x0004: // vmoveto - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount == 2, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_bOpenPath) - { - seCharBuffer->Append((char)9); - m_bOpenPath = false; - } - if (m_nOperatorsCount != 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 vmoveto" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)4); - m_nOperatorsCount = 0; - break; - case 0x0005: // rlineto - if (m_nOperatorsCount < 2 || m_nOperatorsCount % 2 != 0) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 rlineto" - } - for (k = 0; k < m_nOperatorsCount; k += 2) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)5); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0006: // hlineto - if (m_nOperatorsCount < 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hlineto" - } - for (k = 0; k < m_nOperatorsCount; ++k) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)((k & 1) ? 7 : 6)); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0007: // vlineto - if (m_nOperatorsCount < 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 vlineto" - } - for (k = 0; k < m_nOperatorsCount; ++k) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)((k & 1) ? 6 : 7)); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0008: // rrcurveto - if (m_nOperatorsCount < 6 || m_nOperatorsCount % 6 != 0) - { - // TO DO: error "Wrong number of args (%d) to Type 2 rrcurveto", m_nOperatorsCount); - } - for (k = 0; k < m_nOperatorsCount; k += 6) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 5].dNumber, m_arrOperators[k + 5].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x000a: // callsubr - if (m_nOperatorsCount >= 1) - { - nSubrBias = (pSubrIndex->nCount < 1240) ? 107 : (pSubrIndex->nCount < 33900) ? 1131 : 32768; - k = nSubrBias + (int)m_arrOperators[m_nOperatorsCount - 1].dNumber; - --m_nOperatorsCount; - bSuccess = true; - GetIndexVal(pSubrIndex, k, &oIndexVal, &bSuccess); - if (bSuccess) - { - ConvertGlyph(oIndexVal.nPos, oIndexVal.nLen, seCharBuffer, pSubrIndex, pDict, false); - } - } - else - { - // TO DO: error "Too few args to Type 2 callsubr" - } - // не очищаем стек - break; - case 0x000b: // return - // не очищаем стек - break; - case 0x000e: // endchar / seac - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount == 1 || m_nOperatorsCount == 5, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_bOpenPath) - { - seCharBuffer->Append((char)9); - m_bOpenPath = false; - } - if (m_nOperatorsCount == 4) - { - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)12)->Append((char)6); - } - else if (m_nOperatorsCount == 0) - { - seCharBuffer->Append((char)14); - - } - else - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 endchar" - } - m_nOperatorsCount = 0; - break; - case 0x000f: // (obsolete) - // Данная операция игнорируется, но нам нужна ширина символа - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount > 0, seCharBuffer, pDict); - m_bFirstOperator = false; - } - m_nOperatorsCount = 0; - break; - case 0x0010: // blend - // TO DO: error "Unimplemented Type 2 charstring op: file[i]" - m_nOperatorsCount = 0; - break; - case 0x0012: // hstemhm - // Данная операция игнорируется - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hstemhm" - } - m_nHints += m_nOperatorsCount / 2; - m_nOperatorsCount = 0; - break; - case 0x0013: // hintmask - // Данная операция игнорируется - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount > 0) - { - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hintmask/vstemhm" - } - m_nHints += m_nOperatorsCount / 2; - } - nPos += (m_nHints + 7) >> 3; - m_nOperatorsCount = 0; - break; - case 0x0014: // cntrmask - // Данная операция игнорируется - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount > 0) - { - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 cntrmask/vstemhm" - } - m_nHints += m_nOperatorsCount / 2; - } - nPos += (m_nHints + 7) >> 3; - m_nOperatorsCount = 0; - break; - case 0x0015: // rmoveto - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount == 3, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_bOpenPath) - { - seCharBuffer->Append((char)9); - m_bOpenPath = false; - } - if (m_nOperatorsCount != 2) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 rmoveto" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)21); - m_nOperatorsCount = 0; - break; - case 0x0016: // hmoveto - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount == 2, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_bOpenPath) - { - seCharBuffer->Append((char)9); - m_bOpenPath = false; - } - if (m_nOperatorsCount != 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hmoveto" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)22); - m_nOperatorsCount = 0; - break; - case 0x0017: // vstemhm - // Данная операция игнорируется - if (m_bFirstOperator) - { - ConvertGlyphWidth(m_nOperatorsCount & 1, seCharBuffer, pDict); - m_bFirstOperator = false; - } - if (m_nOperatorsCount & 1) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 vstemhm" - } - m_nHints += m_nOperatorsCount / 2; - m_nOperatorsCount = 0; - break; - case 0x0018: // rcurveline - if (m_nOperatorsCount < 8 || (m_nOperatorsCount - 2) % 6 != 0) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 rcurveline" - } - for (k = 0; k < m_nOperatorsCount - 2; k += 6) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 5].dNumber, m_arrOperators[k + 5].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - } - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)5); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0019: // rlinecurve - if (m_nOperatorsCount < 8 || (m_nOperatorsCount - 6) % 2 != 0) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 rlinecurve" - } - for (k = 0; k < m_nOperatorsCount - 6; k += 2) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)5); - } - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 5].dNumber, m_arrOperators[k + 5].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x001a: // vvcurveto - if (m_nOperatorsCount < 4 || !(m_nOperatorsCount % 4 == 0 || (m_nOperatorsCount - 1) % 4 == 0)) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 vvcurveto" - } - if (m_nOperatorsCount % 2 == 1) - { - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - k = 5; - } - else - { - k = 0; - } - for (; k < m_nOperatorsCount; k += 4) - { - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x001b: // hhcurveto - if (m_nOperatorsCount < 4 || !(m_nOperatorsCount % 4 == 0 || (m_nOperatorsCount - 1) % 4 == 0)) - { - // TO DO: error "Wrong number of args (m_nOperatorsCount) to Type 2 hhcurveto" - } - if (m_nOperatorsCount % 2 == 1) - { - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - seCharBuffer->Append((char)8); - k = 5; - } - else - { - k = 0; - } - for (; k < m_nOperatorsCount; k += 4) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - seCharBuffer->Append((char)8); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x001d: // callgsubr - if (m_nOperatorsCount >= 1) - { - k = m_nGsubrBias + (int)m_arrOperators[m_nOperatorsCount - 1].dNumber; - --m_nOperatorsCount; - bSuccess = true; - GetIndexVal(&m_oGsubrIndex, k, &oIndexVal, &bSuccess); - if (bSuccess) - { - ConvertGlyph(oIndexVal.nPos, oIndexVal.nLen, seCharBuffer, pSubrIndex, pDict, false); - } - } - else - { - // TO DO: error "Too few args to Type 2 callgsubr" - } - // не очищаем стек - break; - case 0x001e: // vhcurveto - if (m_nOperatorsCount < 4 || !(m_nOperatorsCount % 4 == 0 || (m_nOperatorsCount - 1) % 4 == 0)) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 vhcurveto" - } - for (k = 0; k < m_nOperatorsCount && k != m_nOperatorsCount - 5; k += 4) - { - if (k % 8 == 0) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)30); - } - else - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)31); - } - } - if (k == m_nOperatorsCount - 5) - { - if (k % 8 == 0) - { - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - } - else - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - } - seCharBuffer->Append((char)8); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x001f: // hvcurveto - if (m_nOperatorsCount < 4 || !(m_nOperatorsCount % 4 == 0 || (m_nOperatorsCount - 1) % 4 == 0)) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 hvcurveto" - } - for (k = 0; k < m_nOperatorsCount && k != m_nOperatorsCount - 5; k += 4) - { - if (k % 8 == 0) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)31); - } - else - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)30); - } - } - if (k == m_nOperatorsCount - 5) - { - if (k % 8 == 0) - { - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - } - else - { - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[k].dNumber, m_arrOperators[k].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 1].dNumber, m_arrOperators[k + 1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 2].dNumber, m_arrOperators[k + 2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 3].dNumber, m_arrOperators[k + 3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[k + 4].dNumber, m_arrOperators[k + 4].bIsFloat, seCharBuffer); - } - seCharBuffer->Append((char)8); - } - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0c00: // dotsection (should be Type 1 only?) - // игнорируем - m_nOperatorsCount = 0; - break; - case 0x0c03: // and - case 0x0c04: // or - case 0x0c05: // not - case 0x0c08: // store - case 0x0c09: // abs - case 0x0c0a: // add - case 0x0c0b: // sub - case 0x0c0c: // div - case 0x0c0d: // load - case 0x0c0e: // neg - case 0x0c0f: // eq - case 0x0c12: // drop - case 0x0c14: // put - case 0x0c15: // get - case 0x0c16: // ifelse - case 0x0c17: // random - case 0x0c18: // mul - case 0x0c1a: // sqrt - case 0x0c1b: // dup - case 0x0c1c: // exch - case 0x0c1d: // index - case 0x0c1e: // roll - // TO DO: "Unimplemented Type 2 charstring op" - m_nOperatorsCount = 0; - break; - case 0x0c22: // hflex - if (m_nOperatorsCount != 7) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 hflex" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - seCharBuffer->Append((char)8); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[5].dNumber, m_arrOperators[5].bIsFloat, seCharBuffer); - ConvertNum(-m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[6].dNumber, m_arrOperators[6].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - seCharBuffer->Append((char)8); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0c23: // flex - if (m_nOperatorsCount != 13) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 flex" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[5].dNumber, m_arrOperators[5].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - ConvertNum(m_arrOperators[6].dNumber, m_arrOperators[6].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[7].dNumber, m_arrOperators[7].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[8].dNumber, m_arrOperators[8].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[9].dNumber, m_arrOperators[9].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[10].dNumber, m_arrOperators[10].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[11].dNumber, m_arrOperators[11].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0c24: // hflex1 - if (m_nOperatorsCount != 9) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 hflex1" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - seCharBuffer->Append((char)8); - ConvertNum(m_arrOperators[5].dNumber, m_arrOperators[5].bIsFloat, seCharBuffer); - ConvertNum(0, false, seCharBuffer); - ConvertNum(m_arrOperators[6].dNumber, m_arrOperators[6].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[7].dNumber, m_arrOperators[7].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[8].dNumber, m_arrOperators[8].bIsFloat, seCharBuffer); - ConvertNum(-(m_arrOperators[1].dNumber + m_arrOperators[3].dNumber + m_arrOperators[7].dNumber), m_arrOperators[1].bIsFloat | m_arrOperators[3].bIsFloat | m_arrOperators[7].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - case 0x0c25: // flex1 - if (m_nOperatorsCount != 11) - { - // TO DO: "Wrong number of args (m_nOperatorsCount) to Type 2 flex1" - } - ConvertNum(m_arrOperators[0].dNumber, m_arrOperators[0].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[1].dNumber, m_arrOperators[1].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[2].dNumber, m_arrOperators[2].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[3].dNumber, m_arrOperators[3].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[4].dNumber, m_arrOperators[4].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[5].dNumber, m_arrOperators[5].bIsFloat, seCharBuffer); - seCharBuffer->Append((char)8); - ConvertNum(m_arrOperators[6].dNumber, m_arrOperators[6].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[7].dNumber, m_arrOperators[7].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[8].dNumber, m_arrOperators[8].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[9].dNumber, m_arrOperators[9].bIsFloat, seCharBuffer); - dX = m_arrOperators[0].dNumber + m_arrOperators[2].dNumber + m_arrOperators[4].dNumber + m_arrOperators[6].dNumber + m_arrOperators[8].dNumber; - dY = m_arrOperators[1].dNumber + m_arrOperators[3].dNumber + m_arrOperators[5].dNumber + m_arrOperators[7].dNumber + m_arrOperators[9].dNumber; - if (fabs(dX) > fabs(dY)) - { - ConvertNum(m_arrOperators[10].dNumber, m_arrOperators[10].bIsFloat, seCharBuffer); - ConvertNum(-dY, m_arrOperators[1].bIsFloat | m_arrOperators[3].bIsFloat | m_arrOperators[5].bIsFloat | m_arrOperators[7].bIsFloat | m_arrOperators[9].bIsFloat, seCharBuffer); - } - else - { - ConvertNum(-dX, m_arrOperators[0].bIsFloat | m_arrOperators[2].bIsFloat | m_arrOperators[4].bIsFloat | m_arrOperators[6].bIsFloat | m_arrOperators[8].bIsFloat, seCharBuffer); - ConvertNum(m_arrOperators[10].dNumber, m_arrOperators[10].bIsFloat, seCharBuffer); - } - seCharBuffer->Append((char)8); - m_nOperatorsCount = 0; - m_bOpenPath = true; - break; - default: - // TO DO: "Illegal Type 2 charstring Operation" - m_nOperatorsCount = 0; - break; - } - } - } - - // CharString Encryption - if (bTop) - { - unsigned short nR2 = 4330; - for (int nIndex = nStart; nIndex < seCharBuffer->GetLength(); ++nIndex) - { - unByte = seCharBuffer->GetAt(nIndex) ^ (nR2 >> 8); - seCharBuffer->SetAt(nIndex, unByte); - nR2 = (unByte + nR2) * 52845 + 22719; - } - } - } - - void CFontFileType1C::ConvertGlyphWidth(bool bUseOperation, StringExt *seCharBuffer, Type1CPrivateDict *pDict) - { - double dWidth = 0; - bool bWidthDouble = false; - - if (bUseOperation) - { - dWidth = pDict->dNominalWidthX + m_arrOperators[0].dNumber; - bWidthDouble = pDict->bNominalWidthXFP | m_arrOperators[0].bIsFloat; - for (int nIndex = 1; nIndex < m_nOperatorsCount; ++nIndex) - { - m_arrOperators[nIndex - 1] = m_arrOperators[nIndex]; - } - --m_nOperatorsCount; - } - else - { - dWidth = pDict->dDefaultWidthX; - bWidthDouble = pDict->bDefaultWidthXFP; - } - ConvertNum(0, false, seCharBuffer); - ConvertNum(dWidth, bWidthDouble, seCharBuffer); - seCharBuffer->Append((char)13); - } - - void CFontFileType1C::ConvertNum(double dValue, bool bIsFloat, StringExt *seCharBuffer) - { - unsigned char sBuffer[12]; - - int nLen = 0; - int nTemp = 0; - if (bIsFloat) - { - - if (dValue >= -32768 && dValue < 32768) - { - nTemp = (int)(dValue * 256.0); - sBuffer[0] = 255; - sBuffer[1] = (unsigned char)(nTemp >> 24); - sBuffer[2] = (unsigned char)(nTemp >> 16); - sBuffer[3] = (unsigned char)(nTemp >> 8); - sBuffer[4] = (unsigned char)nTemp; - sBuffer[5] = 255; - sBuffer[6] = 0; - sBuffer[7] = 0; - sBuffer[8] = 1; - sBuffer[9] = 0; - sBuffer[10] = 12; - sBuffer[11] = 12; - nLen = 12; - } - else - { - // TO DO: "Type 2 fixed point constant out of range" - } - } - else - { - nTemp = (int)dValue; - if (nTemp >= -107 && nTemp <= 107) - { - sBuffer[0] = (unsigned char)(nTemp + 139); - nLen = 1; - } - else if (nTemp > 107 && nTemp <= 1131) - { - nTemp -= 108; - sBuffer[0] = (unsigned char)((nTemp >> 8) + 247); - sBuffer[1] = (unsigned char)(nTemp & 0xff); - nLen = 2; - } - else if (nTemp < -107 && nTemp >= -1131) - { - nTemp = -nTemp - 108; - sBuffer[0] = (unsigned char)((nTemp >> 8) + 251); - sBuffer[1] = (unsigned char)(nTemp & 0xff); - nLen = 2; - } - else - { - sBuffer[0] = 255; - sBuffer[1] = (unsigned char)(nTemp >> 24); - sBuffer[2] = (unsigned char)(nTemp >> 16); - sBuffer[3] = (unsigned char)(nTemp >> 8); - sBuffer[4] = (unsigned char)nTemp; - nLen = 5; - } - } - seCharBuffer->Append((char *)sBuffer, nLen); - } - - void CFontFileType1C::EexecWrite(Type1CEexecBuf *pEexecBuffer, char *sBuffer) - { - unsigned char *pCharPtr; - - for (pCharPtr = (unsigned char *)sBuffer; *pCharPtr; ++pCharPtr) - { - unsigned char nCurChar = *pCharPtr ^ (pEexecBuffer->unEncryptionKey >> 8); - pEexecBuffer->unEncryptionKey = (nCurChar + pEexecBuffer->unEncryptionKey) * 52845 + 22719; - if (pEexecBuffer->bASKII) - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, &c_sHexChars[nCurChar >> 4], 1); - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, &c_sHexChars[nCurChar & 0x0f], 1); - pEexecBuffer->nLine += 2; - if (pEexecBuffer->nLine == 64) - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, "\n", 1); - pEexecBuffer->nLine = 0; - } - } - else - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, (char *)&nCurChar, 1); - } - } - } - - void CFontFileType1C::EexecWriteCharString(Type1CEexecBuf *pEexecBuffer, unsigned char *sBuffer, int nLen) - { - // Eexec шифрование - for (int nIndex = 0; nIndex < nLen; ++nIndex) - { - unsigned nCurChar = sBuffer[nIndex] ^ (pEexecBuffer->unEncryptionKey >> 8); - pEexecBuffer->unEncryptionKey = (nCurChar + pEexecBuffer->unEncryptionKey) * 52845 + 22719; - if (pEexecBuffer->bASKII) - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, &c_sHexChars[nCurChar >> 4], 1); - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, &c_sHexChars[nCurChar & 0x0f], 1); - pEexecBuffer->nLine += 2; - if (pEexecBuffer->nLine == 64) - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, "\n", 1); - pEexecBuffer->nLine = 0; - } - } - else - { - (*pEexecBuffer->pOutputFunc)(pEexecBuffer->pOutputStream, (char *)&nCurChar, 1); - } - } - } - - bool CFontFileType1C::Parse() - { - Type1CIndex oFDIndex; - Type1CIndexVal oIndexVal; - - m_bSuccessParsed = true; - - // некоторые программы включают фонты Type 1C в пробелами в начале - if (m_nLen > 0 && m_sFile[0] != '\x01') - { - ++m_sFile; - --m_nLen; - } - - GetIndex(GetU8(2, &m_bSuccessParsed), &m_oNameIndex, &m_bSuccessParsed); - GetIndex(m_oNameIndex.nEndPos, &m_oTopDictIndex, &m_bSuccessParsed); - GetIndex(m_oTopDictIndex.nEndPos, &m_oStringIndex, &m_bSuccessParsed); - GetIndex(m_oStringIndex.nEndPos, &m_oGsubrIndex, &m_bSuccessParsed); - - if (!m_bSuccessParsed) - return false; - - m_nGsubrBias = (m_oGsubrIndex.nCount < 1240) ? 107 : (m_oGsubrIndex.nCount < 33900) ? 1131 : 32768; - - // считываем первое имя фонта - GetIndexVal(&m_oNameIndex, 0, &oIndexVal, &m_bSuccessParsed); - - if (!m_bSuccessParsed) - return false; - - m_seName = new StringExt((char *)&m_sFile[oIndexVal.nPos], oIndexVal.nLen); - - // Считываем самый верхний словарь для первого фонта - ReadTopDict(); - - if (m_oTopDict.nFirstOperator == 0x0c1e) - { - if (m_oTopDict.nFDArrayOffset == 0) - { - m_nFDsCount = 1; - m_pPrivateDicts = (Type1CPrivateDict *)MemUtilsMalloc(sizeof(Type1CPrivateDict)); - ReadPrivateDict(0, 0, &m_pPrivateDicts[0]); - } - else - { - GetIndex(m_oTopDict.nFDArrayOffset, &oFDIndex, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return false; - m_nFDsCount = oFDIndex.nCount; - m_pPrivateDicts = (Type1CPrivateDict *)MemUtilsMallocArray(m_nFDsCount, sizeof(Type1CPrivateDict)); - for (int nIndex = 0; nIndex < m_nFDsCount; ++nIndex) - { - GetIndexVal(&oFDIndex, nIndex, &oIndexVal, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return false; - ReadFD(oIndexVal.nPos, oIndexVal.nLen, &m_pPrivateDicts[nIndex]); - } - } - } - else - { - m_pPrivateDicts = (Type1CPrivateDict *)MemUtilsMalloc(sizeof(Type1CPrivateDict)); - ReadPrivateDict(m_oTopDict.nPrivateOffset, m_oTopDict.nPrivateSize, &m_pPrivateDicts[0]); - } - - if (!m_bSuccessParsed) - return false; - - // get the charstrings index - if (m_oTopDict.nCharStringsOffset <= 0) - { - m_bSuccessParsed = false; - return false; - } - - GetIndex(m_oTopDict.nCharStringsOffset, &m_oCharStringsIndex, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return false; - - m_nGlyphsCount = m_oCharStringsIndex.nCount; - - if (m_oTopDict.nFirstOperator == 0x0c1e) - { - ReadFDSelect(); - if (!m_bSuccessParsed) - return false; - } - - if (!ReadCharset()) - { - m_bSuccessParsed = false; - return false; - } - - if (m_oTopDict.nFirstOperator != 0x0c14 && m_oTopDict.nFirstOperator != 0x0c1e) - { - BuildEncoding(); - if (!m_bSuccessParsed) - return false; - } - - return m_bSuccessParsed; - } - - void CFontFileType1C::ReadTopDict() - { - Type1CIndexVal oTopDictPointer; - - m_oTopDict.nFirstOperator = -1; - m_oTopDict.nVersionSID = 0; - m_oTopDict.nNoticeSID = 0; - m_oTopDict.nCopyrightSID = 0; - m_oTopDict.nFullNameSID = 0; - m_oTopDict.nFamilyNameSID = 0; - m_oTopDict.nWeightSID = 0; - m_oTopDict.nIsFixedPitch = 0; - m_oTopDict.dItalicAngle = 0; - m_oTopDict.dUnderlinePosition = -100; - m_oTopDict.dUnderlineThickness = 50; - m_oTopDict.nPaintType = 0; - m_oTopDict.nCharStringType = 2; - m_oTopDict.arrdFontMatrix[0] = 0.001; - m_oTopDict.arrdFontMatrix[1] = 0; - m_oTopDict.arrdFontMatrix[2] = 0; - m_oTopDict.arrdFontMatrix[3] = 0.001; - m_oTopDict.arrdFontMatrix[4] = 0; - m_oTopDict.arrdFontMatrix[5] = 0; - m_oTopDict.bHasFontMatrix = false; - m_oTopDict.nUniqueID = 0; - m_oTopDict.arrdFontBBox[0] = 0; - m_oTopDict.arrdFontBBox[1] = 0; - m_oTopDict.arrdFontBBox[2] = 0; - m_oTopDict.arrdFontBBox[3] = 0; - m_oTopDict.dStrokeWidth = 0; - m_oTopDict.nCharsetOffset = 0; - m_oTopDict.nEncodingOffset = 0; - m_oTopDict.nCharStringsOffset = 0; - m_oTopDict.nPrivateSize = 0; - m_oTopDict.nPrivateOffset = 0; - m_oTopDict.nRegistrySID = 0; - m_oTopDict.nOrderingSID = 0; - m_oTopDict.nSupplement = 0; - m_oTopDict.nFDArrayOffset = 0; - m_oTopDict.nFDSelectOffset = 0; - - GetIndexVal(&m_oTopDictIndex, 0, &oTopDictPointer, &m_bSuccessParsed); - int nPos = oTopDictPointer.nPos; - m_nOperatorsCount = 0; - while (nPos < oTopDictPointer.nPos + oTopDictPointer.nLen) - { - nPos = GetOperator(nPos, false, &m_bSuccessParsed); - if (!m_bSuccessParsed) - { - break; - } - if (!m_arrOperators[m_nOperatorsCount - 1].bIsNumber) - { - --m_nOperatorsCount; - if (m_oTopDict.nFirstOperator < 0) - { - m_oTopDict.nFirstOperator = m_arrOperators[m_nOperatorsCount].nOperator; - } - switch (m_arrOperators[m_nOperatorsCount].nOperator) - { - case 0x0000: m_oTopDict.nVersionSID = (int)m_arrOperators[0].dNumber; break; - case 0x0001: m_oTopDict.nNoticeSID = (int)m_arrOperators[0].dNumber; break; - case 0x0c00: m_oTopDict.nCopyrightSID = (int)m_arrOperators[0].dNumber; break; - case 0x0002: m_oTopDict.nFullNameSID = (int)m_arrOperators[0].dNumber; break; - case 0x0003: m_oTopDict.nFamilyNameSID = (int)m_arrOperators[0].dNumber; break; - case 0x0004: m_oTopDict.nWeightSID = (int)m_arrOperators[0].dNumber; break; - case 0x0c01: m_oTopDict.nIsFixedPitch = (int)m_arrOperators[0].dNumber; break; - case 0x0c02: m_oTopDict.dItalicAngle = m_arrOperators[0].dNumber; break; - case 0x0c03: m_oTopDict.dUnderlinePosition = m_arrOperators[0].dNumber; break; - case 0x0c04: m_oTopDict.dUnderlineThickness = m_arrOperators[0].dNumber; break; - case 0x0c05: m_oTopDict.nPaintType = (int)m_arrOperators[0].dNumber; break; - case 0x0c06: m_oTopDict.nCharStringType = (int)m_arrOperators[0].dNumber; break; - case 0x0c07: m_oTopDict.arrdFontMatrix[0] = m_arrOperators[0].dNumber; - m_oTopDict.arrdFontMatrix[1] = m_arrOperators[1].dNumber; - m_oTopDict.arrdFontMatrix[2] = m_arrOperators[2].dNumber; - m_oTopDict.arrdFontMatrix[3] = m_arrOperators[3].dNumber; - m_oTopDict.arrdFontMatrix[4] = m_arrOperators[4].dNumber; - m_oTopDict.arrdFontMatrix[5] = m_arrOperators[5].dNumber; - m_oTopDict.bHasFontMatrix = true; break; - case 0x000d: m_oTopDict.nUniqueID = (int)m_arrOperators[0].dNumber; break; - case 0x0005: m_oTopDict.arrdFontBBox[0] = m_arrOperators[0].dNumber; - m_oTopDict.arrdFontBBox[1] = m_arrOperators[1].dNumber; - m_oTopDict.arrdFontBBox[2] = m_arrOperators[2].dNumber; - m_oTopDict.arrdFontBBox[3] = m_arrOperators[3].dNumber; break; - case 0x0c08: m_oTopDict.dStrokeWidth = m_arrOperators[0].dNumber; break; - case 0x000f: m_oTopDict.nCharsetOffset = (int)m_arrOperators[0].dNumber; break; - case 0x0010: m_oTopDict.nEncodingOffset = (int)m_arrOperators[0].dNumber; break; - case 0x0011: m_oTopDict.nCharStringsOffset = (int)m_arrOperators[0].dNumber; break; - case 0x0012: m_oTopDict.nPrivateSize = (int)m_arrOperators[0].dNumber; - m_oTopDict.nPrivateOffset = (int)m_arrOperators[1].dNumber; break; - case 0x0c1e: m_oTopDict.nRegistrySID = (int)m_arrOperators[0].dNumber; - m_oTopDict.nOrderingSID = (int)m_arrOperators[1].dNumber; - m_oTopDict.nSupplement = (int)m_arrOperators[2].dNumber; break; - case 0x0c24: m_oTopDict.nFDArrayOffset = (int)m_arrOperators[0].dNumber; break; - case 0x0c25: m_oTopDict.nFDSelectOffset = (int)m_arrOperators[0].dNumber; break; - } - m_nOperatorsCount = 0; - } - } - } - - // Читаем словарь шрифта (CID Font Dict (FD)). Отсюда вытаскиваем указатель на private dict, - // и читаем private dict. Также вытаксиваем FontMatrix. - void CFontFileType1C::ReadFD(int nOffset, int nLength, Type1CPrivateDict *pDict) - { - double arrdFontMatrix[6]; - bool bHasFontMatrix = false; - int nPrivateSize = 0, nPrivateOffset = 0; - int nPos = nOffset; - m_nOperatorsCount = 0; - while (nPos < nOffset + nLength) - { - nPos = GetOperator(nPos, false, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - if (!m_arrOperators[m_nOperatorsCount - 1].bIsNumber) - { - if (m_arrOperators[m_nOperatorsCount - 1].nOperator == 0x0012) - { - if (m_nOperatorsCount < 3) - { - m_bSuccessParsed = false; - return; - } - nPrivateSize = (int)m_arrOperators[0].dNumber; - nPrivateOffset = (int)m_arrOperators[1].dNumber; - break; - } - else if (m_arrOperators[m_nOperatorsCount - 1].nOperator == 0x0c07) - { - arrdFontMatrix[0] = m_arrOperators[0].dNumber; - arrdFontMatrix[1] = m_arrOperators[1].dNumber; - arrdFontMatrix[2] = m_arrOperators[2].dNumber; - arrdFontMatrix[3] = m_arrOperators[3].dNumber; - arrdFontMatrix[4] = m_arrOperators[4].dNumber; - arrdFontMatrix[5] = m_arrOperators[5].dNumber; - bHasFontMatrix = true; - } - m_nOperatorsCount = 0; - } - } - ReadPrivateDict(nPrivateOffset, nPrivateSize, pDict); - if (bHasFontMatrix) - { - pDict->arrdFontMatrix[0] = arrdFontMatrix[0]; - pDict->arrdFontMatrix[1] = arrdFontMatrix[1]; - pDict->arrdFontMatrix[2] = arrdFontMatrix[2]; - pDict->arrdFontMatrix[3] = arrdFontMatrix[3]; - pDict->arrdFontMatrix[4] = arrdFontMatrix[4]; - pDict->arrdFontMatrix[5] = arrdFontMatrix[5]; - pDict->bHasFontMatrix = true; - } - } - - void CFontFileType1C::ReadPrivateDict(int nOffset, int nLength, Type1CPrivateDict *pDict) - { - pDict->bHasFontMatrix = false; - pDict->nBlueValues = 0; - pDict->nOtherBlues = 0; - pDict->nFamilyBlues = 0; - pDict->nFamilyOtherBlues = 0; - pDict->dBlueScale = 0.039625; - pDict->nBlueShift = 7; - pDict->nBlueFuzz = 1; - pDict->bHasStdHW = false; - pDict->bHasStdVW = false; - pDict->nStemSnapH = 0; - pDict->nStemSnapV = 0; - pDict->bHasForceBold = false; - pDict->dForceBoldThreshold = 0; - pDict->nLanguageGroup = 0; - pDict->dExpansionFactor = 0.06; - pDict->nInitialRandomSeed = 0; - pDict->nSubrsOffset = 0; - pDict->dDefaultWidthX = 0; - pDict->bDefaultWidthXFP = false; - pDict->dNominalWidthX = 0; - pDict->bNominalWidthXFP = false; - - if (nOffset == 0 || nLength == 0) - return; - - int nPos = nOffset; - m_nOperatorsCount = 0; - - while (nPos < nOffset + nLength) - { - nPos = GetOperator(nPos, false, &m_bSuccessParsed); - if (!m_bSuccessParsed) - break; - - if (!m_arrOperators[m_nOperatorsCount - 1].bIsNumber) - { - --m_nOperatorsCount; - - switch (m_arrOperators[m_nOperatorsCount].nOperator) - { - case 0x0006: - pDict->nBlueValues = GetDeltaIntArray(pDict->arrnBlueValues, type1CMaxBlueValues); - break; - case 0x0007: - pDict->nOtherBlues = GetDeltaIntArray(pDict->arrnOtherBlues, type1CMaxOtherBlues); - break; - case 0x0008: - pDict->nFamilyBlues = GetDeltaIntArray(pDict->arrnFamilyBlues, type1CMaxBlueValues); - break; - case 0x0009: - pDict->nFamilyOtherBlues = GetDeltaIntArray(pDict->arrnFamilyOtherBlues, type1CMaxOtherBlues); - break; - case 0x0c09: - pDict->dBlueScale = m_arrOperators[0].dNumber; - break; - case 0x0c0a: - pDict->nBlueShift = (int)m_arrOperators[0].dNumber; - break; - case 0x0c0b: - pDict->nBlueFuzz = (int)m_arrOperators[0].dNumber; - break; - case 0x000a: - pDict->dStdHW = m_arrOperators[0].dNumber; - pDict->bHasStdHW = true; - break; - case 0x000b: - pDict->dStdVW = m_arrOperators[0].dNumber; - pDict->bHasStdVW = true; - break; - case 0x0c0c: - pDict->nStemSnapH = GetDeltaDoubleArray(pDict->arrdStemSnapH, type1CMaxStemSnap); - break; - case 0x0c0d: - pDict->nStemSnapV = GetDeltaDoubleArray(pDict->arrdStemSnapV, type1CMaxStemSnap); - break; - case 0x0c0e: - pDict->bForceBold = m_arrOperators[0].dNumber != 0; - pDict->bHasForceBold = true; - break; - case 0x0c0f: - pDict->dForceBoldThreshold = m_arrOperators[0].dNumber; - break; - case 0x0c11: - pDict->nLanguageGroup = (int)m_arrOperators[0].dNumber; - break; - case 0x0c12: - pDict->dExpansionFactor = m_arrOperators[0].dNumber; - break; - case 0x0c13: - pDict->nInitialRandomSeed = (int)m_arrOperators[0].dNumber; - break; - case 0x0013: - pDict->nSubrsOffset = nOffset + (int)m_arrOperators[0].dNumber; - break; - case 0x0014: - pDict->dDefaultWidthX = m_arrOperators[0].dNumber; - pDict->bDefaultWidthXFP = m_arrOperators[0].bIsFloat; - break; - case 0x0015: - pDict->dNominalWidthX = m_arrOperators[0].dNumber; - pDict->bNominalWidthXFP = m_arrOperators[0].bIsFloat; - break; - } - m_nOperatorsCount = 0; - } - } - } - - void CFontFileType1C::ReadFDSelect() - { - int nRanges = 0; - - m_pnFDSelect = (unsigned char *)MemUtilsMalloc(m_nGlyphsCount); - - if (m_oTopDict.nFDSelectOffset == 0) - { - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - m_pnFDSelect[nIndex] = 0; - } - } - else - { - int nPos = m_oTopDict.nFDSelectOffset; - int nFDSelectFormat = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - { - return; - } - if (nFDSelectFormat == 0) - { - if (!CheckRegion(nPos, m_nGlyphsCount)) - { - m_bSuccessParsed = false; - return; - } - memcpy(m_pnFDSelect, m_sFile + nPos, m_nGlyphsCount); - } - else if (nFDSelectFormat == 3) - { - nRanges = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - int nGID0 = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - for (int nIndex = 1; nIndex <= nRanges; ++nIndex) - { - int nCurFD = GetU8(nPos++, &m_bSuccessParsed); - int nGID1 = GetU16BE(nPos, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - nPos += 2; - if (nGID0 > nGID1 || nGID1 > m_nGlyphsCount) - { - // TO DO: error "Bad FDSelect table in CID font" - m_bSuccessParsed = false; - return; - } - for (int nJ = nGID0; nJ < nGID1; ++nJ) - { - m_pnFDSelect[nJ] = nCurFD; - } - nGID0 = nGID1; - } - } - else - { - // TO DO: error "Unknown FDSelect table format in CID font" - for (int nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - m_pnFDSelect[nIndex] = 0; - } - } - } - } - - void CFontFileType1C::BuildEncoding() - { - char sBuffer[256]; - int nCodes, nRanges; - int nChar = 0, nLeft, nSups; - - if (m_oTopDict.nEncodingOffset == 0) - { - m_arrEncoding = c_arrsFontFileType1StandardEncoding; - } - else if (m_oTopDict.nEncodingOffset == 1) - { - m_arrEncoding = c_arrsFontFileType1ExpertEncoding; - } - else - { - m_arrEncoding = (char **)MemUtilsMallocArray(256, sizeof(char *)); - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - m_arrEncoding[nIndex] = NULL; - } - int nPos = m_oTopDict.nEncodingOffset; - int nEncodingFormat = GetU8(nPos++, &m_bSuccessParsed); - - if (!m_bSuccessParsed) - return; - - if ((nEncodingFormat & 0x7f) == 0) - { - nCodes = 1 + GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - if (nCodes > m_nGlyphsCount) - { - nCodes = m_nGlyphsCount; - } - for (int nIndex = 1; nIndex < nCodes; ++nIndex) - { - nChar = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - if (m_arrEncoding[nChar]) - { - MemUtilsFree(m_arrEncoding[nChar]); - } - m_arrEncoding[nChar] = CopyString(GetString(m_pnCharset[nIndex], sBuffer, &m_bSuccessParsed)); - } - } - else if ((nEncodingFormat & 0x7f) == 1) - { - nRanges = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - nCodes = 1; - for (int nIndex = 0; nIndex < nRanges; ++nIndex) - { - nChar = GetU8(nPos++, &m_bSuccessParsed); - nLeft = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - for (int nJ = 0; nJ <= nLeft && nCodes < m_nGlyphsCount; ++nJ) - { - if (nChar < 256) - { - if (m_arrEncoding[nChar]) - { - MemUtilsFree(m_arrEncoding[nChar]); - } - m_arrEncoding[nChar] = CopyString(GetString(m_pnCharset[nCodes], sBuffer, &m_bSuccessParsed)); - } - ++nCodes; - ++nChar; - } - } - } - if (nEncodingFormat & 0x80) - { - nSups = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - for (int nIndex = 0; nIndex < nSups; ++nIndex) - { - nChar = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - return; - - int nSID = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - - if (!m_bSuccessParsed) - return; - - if (m_arrEncoding[nChar]) - { - MemUtilsFree(m_arrEncoding[nChar]); - } - m_arrEncoding[nChar] = CopyString(GetString(nSID, sBuffer, &m_bSuccessParsed)); - } - } - } - } - - bool CFontFileType1C::ReadCharset() - { - int nChar = 0; - int nLeft, nIndex = 0; - - if (m_oTopDict.nCharsetOffset == 0) - { - m_pnCharset = c_arrnFontFileType1CISOAdobeCharset; - } - else if (m_oTopDict.nCharsetOffset == 1) - { - m_pnCharset = c_arrnFontFileType1CExpertCharset; - } - else if (m_oTopDict.nCharsetOffset == 2) - { - m_pnCharset = c_arrnFontFileType1CExpertSubsetCharset; - } - else - { - m_pnCharset = (unsigned short *)MemUtilsMallocArray(m_nGlyphsCount, sizeof(unsigned short)); - for (nIndex = 0; nIndex < m_nGlyphsCount; ++nIndex) - { - m_pnCharset[nIndex] = 0; - } - int nPos = m_oTopDict.nCharsetOffset; - int nCharsetFormat = GetU8(nPos++, &m_bSuccessParsed); - - if (nCharsetFormat == 0) - { - for (nIndex = 1; nIndex < m_nGlyphsCount; ++nIndex) - { - m_pnCharset[nIndex] = (unsigned short)GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - if (!m_bSuccessParsed) - break; - } - } - else if (nCharsetFormat == 1) - { - nIndex = 1; - while (nIndex < m_nGlyphsCount) - { - nChar = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - nLeft = GetU8(nPos++, &m_bSuccessParsed); - if (!m_bSuccessParsed) - break; - for (int nJ = 0; nJ <= nLeft && nIndex < m_nGlyphsCount; ++nJ) - { - m_pnCharset[nIndex++] = (unsigned short)nChar++; - } - } - } - else if (nCharsetFormat == 2) - { - nIndex = 1; - while (nIndex < m_nGlyphsCount) - { - nChar = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - nLeft = GetU16BE(nPos, &m_bSuccessParsed); - nPos += 2; - if (!m_bSuccessParsed) - break; - - for (int nJ = 0; nJ <= nLeft && nIndex < m_nGlyphsCount; ++nJ) - { - m_pnCharset[nIndex++] = (unsigned short)nChar++; - } - } - } - if (!m_bSuccessParsed) - { - MemUtilsFree(m_pnCharset); - m_pnCharset = NULL; - return false; - } - } - return true; - } - - int CFontFileType1C::GetOperator(int nPos, bool bCharString, bool *pbSuccess) - { - static char c_sNumChars[16] = "0123456789.ee -"; - Type1COperator oOperator; - char sBuffer[65]; - int nFirstChar, nSecondChar, nFC, nSC, nTempValue = 0; - - nFirstChar = GetU8(nPos++, pbSuccess); - oOperator.bIsNumber = true; - oOperator.bIsFloat = false; - - if (nFirstChar == 28) - { - nTempValue = GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - if (nTempValue & 0x8000) - { - nTempValue |= ~0xffff; - } - oOperator.dNumber = nTempValue; - - } - else if (!bCharString && nFirstChar == 29) - { - nTempValue = GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - if (nTempValue & 0x80000000) - { - nTempValue |= ~0xffffffff; - } - oOperator.dNumber = nTempValue; - - } - else if (!bCharString && nFirstChar == 30) - { - int nIndex = 0; - do - { - nSecondChar = GetU8(nPos++, pbSuccess); - nFC = nSecondChar >> 4; - nSC = nSecondChar & 0x0f; - if (nFC == 0xf) - { - break; - } - sBuffer[nIndex++] = c_sNumChars[nFC]; - if (nIndex == 64) - { - break; - } - if (nFC == 0xc) - { - sBuffer[nIndex++] = '-'; - } - if (nIndex == 64) - { - break; - } - if (nSC == 0xf) - { - break; - } - sBuffer[nIndex++] = c_sNumChars[nSC]; - if (nIndex == 64) - { - break; - } - if (nSC == 0xc) - { - sBuffer[nIndex++] = '-'; - } - } while (nIndex < 64); - sBuffer[nIndex] = '\0'; - oOperator.dNumber = atof(sBuffer); - oOperator.bIsFloat = true; - - } - else if (nFirstChar >= 32 && nFirstChar <= 246) - { - oOperator.dNumber = nFirstChar - 139; - } - else if (nFirstChar >= 247 && nFirstChar <= 250) - { - oOperator.dNumber = ((nFirstChar - 247) << 8) + GetU8(nPos++, pbSuccess) + 108; - } - else if (nFirstChar >= 251 && nFirstChar <= 254) - { - oOperator.dNumber = -((nFirstChar - 251) << 8) - GetU8(nPos++, pbSuccess) - 108; - } - else if (bCharString && nFirstChar == 255) - { - nTempValue = GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - nTempValue = (nTempValue << 8) | GetU8(nPos++, pbSuccess); - if (nTempValue & 0x80000000) - { - nTempValue |= ~0xffffffff; - } - oOperator.dNumber = (double)nTempValue / 65536.0; - oOperator.bIsFloat = true; - - } - else if (nFirstChar == 12) - { - oOperator.bIsNumber = false; - oOperator.nOperator = 0x0c00 + GetU8(nPos++, pbSuccess); - } - else - { - oOperator.bIsNumber = false; - oOperator.nOperator = nFirstChar; - } - - if (m_nOperatorsCount < 49) - { - m_arrOperators[m_nOperatorsCount++] = oOperator; - } - - return nPos; - } - - // Конвертируем delta-encoded массив операторов в массив ints - int CFontFileType1C::GetDeltaIntArray(int *pArray, int nMaxLen) - { - int nCount = 0; - - if ((nCount = m_nOperatorsCount) > nMaxLen) - { - nCount = nMaxLen; - } - int nTemp = 0; - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - nTemp += (int)m_arrOperators[nIndex].dNumber; - pArray[nIndex] = nTemp; - } - return nCount; - } - - // Конвертируем delta-encoded массив операторов в массив doubles - int CFontFileType1C::GetDeltaDoubleArray(double *pArray, int nMaxLen) - { - int nCount = 0; - - if ((nCount = m_nOperatorsCount) > nMaxLen) - { - nCount = nMaxLen; - } - double dTemp = 0; - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - dTemp += m_arrOperators[nIndex].dNumber; - pArray[nIndex] = dTemp; - } - return nCount; - } - - void CFontFileType1C::GetIndex(int nPos, Type1CIndex *pIndex, bool *bSuccess) - { - pIndex->nPos = nPos; - pIndex->nCount = GetU16BE(nPos, bSuccess); - if (0 == pIndex->nCount) - { - // возможны пустые индексы, они содержат только поле length - pIndex->nOffsetSize = 0; - pIndex->nStartPos = pIndex->nEndPos = nPos + 2; - } - else - { - pIndex->nOffsetSize = GetU8(nPos + 2, bSuccess); - if (pIndex->nOffsetSize < 1 || pIndex->nOffsetSize > 4) - { - *bSuccess = false; - } - pIndex->nStartPos = nPos + 3 + (pIndex->nCount + 1) * pIndex->nOffsetSize - 1; - if (pIndex->nStartPos < 0 || pIndex->nStartPos >= m_nLen) - { - *bSuccess = false; - } - pIndex->nEndPos = pIndex->nStartPos + GetUVarBE(nPos + 3 + pIndex->nCount * pIndex->nOffsetSize, pIndex->nOffsetSize, bSuccess); - if (pIndex->nEndPos < pIndex->nStartPos || pIndex->nEndPos > m_nLen) - { - *bSuccess = false; - } - } - } - - void CFontFileType1C::GetIndexVal(Type1CIndex *pIndex, int nIndex, Type1CIndexVal *pIndexVal, bool *bSuccess) - { - if (nIndex < 0 || nIndex >= pIndex->nCount) - { - *bSuccess = false; - return; - } - int nPos0 = pIndex->nStartPos + GetUVarBE(pIndex->nPos + 3 + nIndex * pIndex->nOffsetSize, pIndex->nOffsetSize, bSuccess); - int nPos1 = pIndex->nStartPos + GetUVarBE(pIndex->nPos + 3 + (nIndex + 1) * pIndex->nOffsetSize, pIndex->nOffsetSize, bSuccess); - - if (nPos0 < pIndex->nStartPos || nPos0 > pIndex->nEndPos || nPos1 <= pIndex->nStartPos || nPos1 > pIndex->nEndPos || nPos1 < nPos0) - { - *bSuccess = false; - } - pIndexVal->nPos = nPos0; - pIndexVal->nLen = nPos1 - nPos0; - } - - char *CFontFileType1C::GetString(int nSID, char *sBuffer, bool *pbSuccess) - { - Type1CIndexVal oIndexVal; - int nCount = 0; - - if (nSID < 391) - { - strcpy(sBuffer, c_arrsFontFileType1CStandardStrings[nSID]); - } - else - { - nSID -= 391; - GetIndexVal(&m_oStringIndex, nSID, &oIndexVal, pbSuccess); - if (*pbSuccess) - { - if ((nCount = oIndexVal.nLen) > 255) - { - nCount = 255; - } - strncpy(sBuffer, (char *)&m_sFile[oIndexVal.nPos], nCount); - sBuffer[nCount] = '\0'; - } - else - { - sBuffer[0] = '\0'; - } - } - return sBuffer; - } -} \ No newline at end of file diff --git a/PdfReader/old/FontFileType1C.h b/PdfReader/old/FontFileType1C.h deleted file mode 100644 index 64d0b4306d..0000000000 --- a/PdfReader/old/FontFileType1C.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FONT_FILE_TYPE1C_H -#define _PDF_READER_FONT_FILE_TYPE1C_H - -#include "FontFileBase.h" - -namespace PdfReader -{ - class StringExt; - - //------------------------------------------------------------------------ - - struct Type1CIndex - { - int nPos; // Позиция в файле от начала файла - int nCount; // Количество вхождений - int nOffsetSize; // Offset size - int nStartPos; // Начальная позиция index data - 1 - int nEndPos; // Позиция следующего байта после Type1CIndex - }; - - struct Type1CIndexVal - { - int nPos; // Позиция в файле от начала файла - int nLen; // Длина в байтах - }; - - struct Type1CTopDict - { - int nFirstOperator; - - int nVersionSID; - int nNoticeSID; - int nCopyrightSID; - int nFullNameSID; - int nFamilyNameSID; - int nWeightSID; - - int nIsFixedPitch; - double dItalicAngle; - double dUnderlinePosition; - double dUnderlineThickness; - - int nPaintType; - int nCharStringType; - double arrdFontMatrix[6]; - bool bHasFontMatrix; // В CID фонтах возможно матрица фонта лежит в FD, а не в верхнем словаре - int nUniqueID; - double arrdFontBBox[4]; - double dStrokeWidth; - int nCharsetOffset; - int nEncodingOffset; - int nCharStringsOffset; - int nPrivateSize; - int nPrivateOffset; - - // CIDFont entries - int nRegistrySID; - int nOrderingSID; - int nSupplement; - int nFDArrayOffset; - int nFDSelectOffset; - }; - - - -#define type1CMaxBlueValues 14 -#define type1CMaxOtherBlues 10 -#define type1CMaxStemSnap 12 - - struct Type1CPrivateDict - { - double arrdFontMatrix[6]; - bool bHasFontMatrix; - int arrnBlueValues[type1CMaxBlueValues]; - int nBlueValues; - int arrnOtherBlues[type1CMaxOtherBlues]; - int nOtherBlues; - int arrnFamilyBlues[type1CMaxBlueValues]; - int nFamilyBlues; - int arrnFamilyOtherBlues[type1CMaxOtherBlues]; - int nFamilyOtherBlues; - double dBlueScale; - int nBlueShift; - int nBlueFuzz; - double dStdHW; - bool bHasStdHW; - double dStdVW; - bool bHasStdVW; - double arrdStemSnapH[type1CMaxStemSnap]; - int nStemSnapH; - double arrdStemSnapV[type1CMaxStemSnap]; - int nStemSnapV; - bool bForceBold; - bool bHasForceBold; - double dForceBoldThreshold; - int nLanguageGroup; - double dExpansionFactor; - int nInitialRandomSeed; - int nSubrsOffset; - double dDefaultWidthX; - bool bDefaultWidthXFP; - double dNominalWidthX; - bool bNominalWidthXFP; - }; - - struct Type1COperator - { - bool bIsNumber; // true -> number, false -> operator - bool bIsFloat; // true -> floating point number, false -> int - union - { - double dNumber; - int nOperator; - }; - }; - - struct Type1CEexecBuf - { - FontFileOutputFunc pOutputFunc; - void *pOutputStream; - bool bASKII; // ASCII кодировка? - unsigned short unEncryptionKey; // eexec encryption key - int nLine; // количество eexec-символов, оставшихся на текущей строке - }; - - //------------------------------------------------------------------------ - // CFontFileType1C - //------------------------------------------------------------------------ - - class CFontFileType1C : public CFontFileBase - { - - public: - - static CFontFileType1C *LoadFromBuffer(char *sBuffer, int nLen); - - static CFontFileType1C *LoadFromFile(wchar_t *wsFileName); - - virtual ~CFontFileType1C(); - - char *GetName(); - - // Возвращаем кодировку, как массив 256 имен (некоторые могут быть - // NULL). Используется только для 8-битных фонтов. - char **GetEncoding(); - - unsigned short *GetCIDToGIDMap(int *arrCIDs); - - // Convert to a Type 1 font, suitable for embedding in a PostScript - // file. This is only useful with 8-bit fonts. If is - // not NULL, it will be used in place of the encoding in the Type 1C - // font. If is true the eexec section will be hex-encoded, - // otherwise it will be left as binary data. If is non-NULL, - // it will be used as the PostScript font name. - void ToType1(char *sPSName, char **ppNewEncoding, bool bASKII, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 0 CIDFont, suitable for embedding in a - // PostScript file. will be used as the PostScript font - // name. - void ToCIDType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - // Convert to a Type 0 (but non-CID) composite font, suitable for - // embedding in a PostScript file. will be used as the - // PostScript font name. - void ToType0(char *sPSName, FontFileOutputFunc pOutputFunc, void *pOutputStream); - - private: - - CFontFileType1C(char *sBuffer, int nLen, bool bFreeData); - void EexecConvertGlyph(Type1CEexecBuf *pEexecBuf, char *sGlyphName, int nOffset, int nBytes, Type1CIndex *pSubrIndex, Type1CPrivateDict *pDict); - void ConvertGlyph(int nOffset, int nBytes, StringExt *seCharBuffer, Type1CIndex *pSubrIndex, Type1CPrivateDict *pDict, bool bTop); - void ConvertGlyphWidth(bool bUseOperation, StringExt *seCharBuffer, Type1CPrivateDict *pDict); - void ConvertNum(double dValue, bool bIsFloat, StringExt *seCharBuffer); - void EexecWrite(Type1CEexecBuf *pEexecBuf, char *sBuffer); - void EexecWriteCharString(Type1CEexecBuf *pEexecBuf, unsigned char *sBuffer, int nLen); - bool Parse(); - void ReadTopDict(); - void ReadFD(int nOffset, int nLength, Type1CPrivateDict *pDict); - void ReadPrivateDict(int nOffset, int nLength, Type1CPrivateDict *pDict); - void ReadFDSelect(); - void BuildEncoding(); - bool ReadCharset(); - int GetOperator(int nPos, bool bCharString, bool *pbSuccess); - int GetDeltaIntArray(int *pArray, int nMaxLen); - int GetDeltaDoubleArray(double *pArray, int nMaxLen); - void GetIndex(int nPos, Type1CIndex *pIndex, bool *pbSuccess); - void GetIndexVal(Type1CIndex *pIndex, int nIndex, Type1CIndexVal *pIndexVal, bool *bSuccess); - char *GetString(int nSID, char *sBuffer, bool *pbSuccess); - - private: - - StringExt *m_seName; - char **m_arrEncoding; - - Type1CIndex m_oNameIndex; - Type1CIndex m_oTopDictIndex; - Type1CIndex m_oStringIndex; - Type1CIndex m_oGsubrIndex; - Type1CIndex m_oCharStringsIndex; - - Type1CTopDict m_oTopDict; - Type1CPrivateDict *m_pPrivateDicts; - - int m_nGlyphsCount; - int m_nFDsCount; - unsigned char *m_pnFDSelect; - unsigned short *m_pnCharset; - int m_nGsubrBias; - - bool m_bSuccessParsed; - - Type1COperator m_arrOperators[49]; - int m_nOperatorsCount; - int m_nHints; // для текущего символа - bool m_bFirstOperator; - bool m_bOpenPath; // true, если есть незакрытый пат - }; -} - -#endif // _PDF_READER_FONT_FILE_TYPE1C_H diff --git a/PdfReader/old/Function.cpp b/PdfReader/old/Function.cpp deleted file mode 100644 index a03728cacd..0000000000 --- a/PdfReader/old/Function.cpp +++ /dev/null @@ -1,1898 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "Dict.h" -#include "Stream.h" -#include "Function.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Function - //------------------------------------------------------------------------ - - Function::Function() - { - } - - Function::~Function() - { - } - - Function *Function::Parse(Object *pFuncObject) - { - Dict *pDict; - - // Функция задается либо как словарь, либо поток, либо как тождественная функция - if (pFuncObject->IsStream()) - { - pDict = pFuncObject->StreamGetDict(); - } - else if (pFuncObject->IsDict()) - { - pDict = pFuncObject->GetDict(); - } - else if (pFuncObject->IsName("Identity")) - { - return new IdentityFunction(); - } - else - { - // TO DO: Error "Expected function dictionary or stream" - return NULL; - } - - Object oTemp; - if (!pDict->Search("FunctionType", &oTemp)->IsInt()) - { - // TO DO: Error "Function type is missing or wrong type" - oTemp.Free(); - return NULL; - } - int nFuncType = oTemp.GetInt(); - oTemp.Free(); - - Function *pFunc = NULL; - if (0 == nFuncType) // Sampled function - { - pFunc = new SampledFunction(pFuncObject, pDict); - } - else if (2 == nFuncType) // Exponential interpolation function - { - pFunc = new ExponentialFunction(pFuncObject, pDict); - } - else if (3 == nFuncType) // Stitching function - { - pFunc = new StitchingFunction(pFuncObject, pDict); - } - else if (4 == nFuncType) // PostScript calculator function - { - pFunc = new PostScriptFunction(pFuncObject, pDict); - } - else - { - // TO DO: Error "Unimplemented function type" - return NULL; - } - if (!pFunc->IsValid()) - { - delete pFunc; - return NULL; - } - - return pFunc; - } - - bool Function::Initialize(Dict *pDict) - { - Object oArray; - // Domain (Всегда должен присутствовать) - if (!pDict->Search("Domain", &oArray)->IsArray()) - { - // TO DO: Error "Function is missing domain" - oArray.Free(); - return false; - } - m_nInputDim = oArray.ArrayGetLength() / 2; - - if (m_nInputDim > funcMaxInputs) - { - // TO DO: Error "Functions with more than funcMaxInputs inputs are unsupported" - oArray.Free(); - return false; - } - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(2 * nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function domain array" - oTemp.Free(); - oArray.Free(); - return false; - } - m_arrDomain[nIndex][0] = oTemp.GetNum(); - oTemp.Free(); - oArray.ArrayGet(2 * nIndex + 1, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function domain array" - oTemp.Free(); - oArray.Free(); - return false; - } - m_arrDomain[nIndex][1] = oTemp.GetNum(); - oTemp.Free(); - } - oArray.Free(); - - // Range (Этого поля может и не быть) - m_bHasRange = false; - m_nOutputDim = 0; - if (pDict->Search("Range", &oArray)->IsArray()) - { - m_bHasRange = true; - m_nOutputDim = oArray.ArrayGetLength() / 2; - if (m_nOutputDim > funcMaxOutputs) - { - // TO DO: Error "Functions with more than funcMaxOutputs outputs are unsupported" - oArray.Free(); - return false; - } - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(2 * nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function range array" - oTemp.Free(); - oArray.Free(); - return false; - } - m_arrRange[nIndex][0] = oTemp.GetNum(); - oTemp.Free(); - oArray.ArrayGet(2 * nIndex + 1, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function range array" - oTemp.Free(); - oArray.Free(); - return false; - } - m_arrRange[nIndex][1] = oTemp.GetNum(); - oTemp.Free(); - } - } - oArray.Free(); - - return true; - } - - //------------------------------------------------------------------------ - // IdentityFunction - //------------------------------------------------------------------------ - - IdentityFunction::IdentityFunction() - { - // Заполняем произвольными значениями - m_nInputDim = funcMaxInputs; - m_nOutputDim = funcMaxOutputs; - - for (int nIndex = 0; nIndex < funcMaxInputs; ++nIndex) - { - m_arrDomain[nIndex][0] = 0; - m_arrDomain[nIndex][1] = 1; - } - m_bHasRange = false; - } - - IdentityFunction::~IdentityFunction() - { - } - - void IdentityFunction::Transform(double *pInput, double *pOutput) - { - for (int nIndex = 0; nIndex < funcMaxOutputs; ++nIndex) - { - pOutput[nIndex] = pInput[nIndex]; // тождественная же функция :) - } - } - - //------------------------------------------------------------------------ - // SampledFunction - //------------------------------------------------------------------------ - - SampledFunction::SampledFunction(Object *pFuncObject, Dict *pDict) - { - m_pSamples = NULL; - m_pBuffer = NULL; - m_bValid = false; - - if (!Initialize(pDict)) - { - return; - } - if (!m_bHasRange) - { - // TO DO: Error "Type 0 function is missing range" - return; - } - if (m_nInputDim > sampledFuncMaxInputs) - { - // TO DO: Error "Sampled functions with more than sampledFuncMaxInputs inputs are unsupported" - return; - } - - m_pBuffer = (double *)MemUtilsMallocArray(1 << m_nInputDim, sizeof(double)); - - if (!pFuncObject->IsStream()) - { - // TO DO: Error "Type 0 function isn't a stream" - return; - } - Stream *pStream = pFuncObject->GetStream(); - - // Size - Object oArray; - if (!pDict->Search("Size", &oArray)->IsArray() || oArray.ArrayGetLength() != m_nInputDim) - { - // TO DO: Error "Function has missing or invalid size array" - oArray.Free(); - return; - } - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(nIndex, &oTemp); - if (!oTemp.IsInt()) - { - // TO DO: Error "Illegal value in function size array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrSize[nIndex] = oTemp.GetInt(); - oTemp.Free(); - } - oArray.Free(); - - m_arrIndexMult[0] = m_nOutputDim; - for (int nIndex = 1; nIndex < m_nInputDim; ++nIndex) - { - m_arrIndexMult[nIndex] = m_arrIndexMult[nIndex - 1] * m_arrSize[nIndex - 1]; - } - - // BitsPerSample - if (!pDict->Search("BitsPerSample", &oArray)->IsInt()) - { - // TO DO: Error "Function has missing or invalid BitsPerSample" - oArray.Free(); - return; - } - int nSampleBits = oArray.GetInt(); - double dSampleMult = 1.0 / (pow(2.0, (double)nSampleBits) - 1); - oArray.Free(); - - // TO DO: Сделать чтение поля Order, и реализовать функцию Transform - - // Encode - if (pDict->Search("Encode", &oArray)->IsArray() && oArray.ArrayGetLength() == 2 * m_nInputDim) - { - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(2 * nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function encode array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrEncoder[nIndex][0] = oTemp.GetNum(); - oTemp.Free(); - - oArray.ArrayGet(2 * nIndex + 1, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function encode array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrEncoder[nIndex][1] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - m_arrEncoder[nIndex][0] = 0; - m_arrEncoder[nIndex][1] = m_arrSize[nIndex] - 1; - } - } - oArray.Free(); - - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - m_arrInputMult[nIndex] = (m_arrEncoder[nIndex][1] - m_arrEncoder[nIndex][0]) / (m_arrDomain[nIndex][1] - m_arrDomain[nIndex][0]); - } - - // Decode - if (pDict->Search("Decode", &oArray)->IsArray() && oArray.ArrayGetLength() == 2 * m_nOutputDim) - { - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(2 * nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function decode array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrDecoder[nIndex][0] = oTemp.GetNum(); - oTemp.Free(); - - oArray.ArrayGet(2 * nIndex + 1, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function decode array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrDecoder[nIndex][1] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - m_arrDecoder[nIndex][0] = m_arrRange[nIndex][0]; - m_arrDecoder[nIndex][1] = m_arrRange[nIndex][1]; - } - } - oArray.Free(); - - // Samples - m_nSamplesCount = m_nOutputDim; - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - m_nSamplesCount *= m_arrSize[nIndex]; - m_pSamples = (double *)MemUtilsMallocArray(m_nSamplesCount, sizeof(double)); - - unsigned int unBuf = 0; - int nBitsCount = 0; - unsigned int unBitMask = (1 << nSampleBits) - 1; - pStream->Reset(); - for (int nIndex = 0; nIndex < m_nSamplesCount; ++nIndex) - { - unsigned int unValue = 0; - if (nSampleBits == 8) - { - unValue = pStream->GetChar(); - } - else if (nSampleBits == 16) - { - unValue = pStream->GetChar(); - unValue = (unValue << 8) + pStream->GetChar(); - } - else if (nSampleBits == 32) - { - unValue = pStream->GetChar(); - unValue = (unValue << 8) + pStream->GetChar(); - unValue = (unValue << 8) + pStream->GetChar(); - unValue = (unValue << 8) + pStream->GetChar(); - } - else - { - while (nBitsCount < nSampleBits) - { - unBuf = (unBuf << 8) | (pStream->GetChar() & 0xff); - nBitsCount += 8; - } - unValue = (unBuf >> (nBitsCount - nSampleBits)) & unBitMask; - nBitsCount -= nSampleBits; - } - m_pSamples[nIndex] = (double)unValue * dSampleMult; - } - pStream->Close(); - - m_bValid = true; - return; - } - - SampledFunction::~SampledFunction() - { - MemUtilsFree(m_pSamples); - MemUtilsFree(m_pBuffer); - } - - SampledFunction::SampledFunction(SampledFunction *pFunc) - { - memcpy(this, pFunc, sizeof(SampledFunction)); - m_pSamples = (double *)MemUtilsMallocArray(m_nSamplesCount, sizeof(double)); - memcpy(m_pSamples, pFunc->m_pSamples, m_nSamplesCount * sizeof(double)); - m_pBuffer = (double *)MemUtilsMallocArray(1 << m_nInputDim, sizeof(double)); - } - - void SampledFunction::Transform(double *pInput, double *pOutput) - { - int arrE[funcMaxInputs][2]; - double arrEFrac0[funcMaxInputs]; - double arrEFrac1[funcMaxInputs]; - - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - double dValue = (pInput[nIndex] - m_arrDomain[nIndex][0]) * m_arrInputMult[nIndex] + m_arrEncoder[nIndex][0]; - if (dValue < 0) - { - dValue = 0; - } - else if (dValue > m_arrSize[nIndex] - 1) - { - dValue = m_arrSize[nIndex] - 1; - } - arrE[nIndex][0] = (int)dValue; - if ((arrE[nIndex][1] = arrE[nIndex][0] + 1) >= m_arrSize[nIndex]) - { - arrE[nIndex][1] = arrE[nIndex][0]; - } - arrEFrac1[nIndex] = dValue - arrE[nIndex][0]; - arrEFrac0[nIndex] = 1 - arrEFrac1[nIndex]; - } - - for (int nI = 0; nI < m_nOutputDim; ++nI) - { - for (int nJ = 0; nJ < (1 << m_nInputDim); ++nJ) - { - int nIdx = nI; - for (int nK = 0, t = nJ; nK < m_nInputDim; ++nK, t >>= 1) - { - nIdx += m_arrIndexMult[nK] * (arrE[nK][t & 1]); - } - m_pBuffer[nJ] = m_pSamples[nIdx]; - } - - int nT = 0; - for (int nJ = 0, nT = (1 << m_nInputDim); nJ < m_nInputDim; ++nJ, nT >>= 1) - { - for (int nK = 0; nK < nT; nK += 2) - { - m_pBuffer[nK >> 1] = arrEFrac0[nJ] * m_pBuffer[nK] + arrEFrac1[nJ] * m_pBuffer[nK + 1]; - } - } - - pOutput[nI] = m_pBuffer[0] * (m_arrDecoder[nI][1] - m_arrDecoder[nI][0]) + m_arrDecoder[nI][0]; - if (pOutput[nI] < m_arrRange[nI][0]) - { - pOutput[nI] = m_arrRange[nI][0]; - } - else if (pOutput[nI] > m_arrRange[nI][1]) - { - pOutput[nI] = m_arrRange[nI][1]; - } - } - } - - //------------------------------------------------------------------------ - // ExponentialFunction - //------------------------------------------------------------------------ - - ExponentialFunction::ExponentialFunction(Object *pFuncObject, Dict *pDict) - { - m_bValid = false; - - if (!Initialize(pDict)) - { - return; - } - if (m_nInputDim != 1) - { - // TO DO: Error "Exponential function with more than one input" - return; - } - - // C0 - Object oArray; - if (pDict->Search("C0", &oArray)->IsArray()) - { - if (m_bHasRange && oArray.ArrayGetLength() != m_nOutputDim) - { - // TO DO: Error "Function's C0 array is wrong length" - oArray.Free(); - return; - } - m_nOutputDim = oArray.ArrayGetLength(); - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function C0 array" - oArray.Free(); - oTemp.Free(); - return; - } - m_arrC0[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - if (m_bHasRange && m_nOutputDim != 1) - { - // TO DO: Error "Function's C0 array is wrong length" - oArray.Free(); - return; - } - m_nOutputDim = 1; - m_arrC0[0] = 0; - } - oArray.Free(); - - // C1 - if (pDict->Search("C1", &oArray)->IsArray()) - { - if (oArray.ArrayGetLength() != m_nOutputDim) - { - // TO DO: Error "Function's C1 array is wrong length" - oArray.Free(); - return; - } - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - Object oTemp; - oArray.ArrayGet(nIndex, &oTemp); - if (!oTemp.IsNum()) - { - // TO DO: Error "Illegal value in function C1 array" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrC1[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - if (m_nOutputDim != 1) - { - // TO DO: Error "Function's C1 array is wrong length" - oArray.Free(); - return; - } - m_arrC1[0] = 1; - } - oArray.Free(); - - // N (exponent) - if (!pDict->Search("N", &oArray)->IsNum()) - { - // TO DO: Error "Function has missing or invalid N" - oArray.Free(); - return; - } - m_dN = oArray.GetNum(); - oArray.Free(); - - m_bValid = true; - return; - } - - ExponentialFunction::~ExponentialFunction() - { - } - - ExponentialFunction::ExponentialFunction(ExponentialFunction *pFunc) - { - memcpy(this, pFunc, sizeof(ExponentialFunction)); - } - - void ExponentialFunction::Transform(double *pInput, double *pOutput) - { - double dX = 0; - - if (pInput[0] < m_arrDomain[0][0]) - { - dX = m_arrDomain[0][0]; - } - else if (pInput[0] > m_arrDomain[0][1]) - { - dX = m_arrDomain[0][1]; - } - else - { - dX = pInput[0]; - } - for (int nIndex = 0; nIndex < m_nOutputDim; ++nIndex) - { - pOutput[nIndex] = m_arrC0[nIndex] + pow(dX, m_dN) * (m_arrC1[nIndex] - m_arrC0[nIndex]); - if (m_bHasRange) - { - if (pOutput[nIndex] < m_arrRange[nIndex][0]) - { - pOutput[nIndex] = m_arrRange[nIndex][0]; - } - else if (pOutput[nIndex] > m_arrRange[nIndex][1]) - { - pOutput[nIndex] = m_arrRange[nIndex][1]; - } - } - } - return; - } - - //------------------------------------------------------------------------ - // StitchingFunction - //------------------------------------------------------------------------ - - StitchingFunction::StitchingFunction(Object *pFuncObject, Dict *pDict) - { - m_bValid = false; - m_ppFuncs = NULL; - m_arrBounds = NULL; - m_arrEncode = NULL; - m_arrScale = NULL; - - if (!Initialize(pDict)) - { - return; - } - - if (m_nInputDim != 1) - { - // TO DO: Error "Stitching function with more than one input" - return; - } - - // Functions - Object oArray; - if (!pDict->Search("Functions", &oArray)->IsArray()) - { - // TO DO: Error "Missing 'Functions' entry in stitching function" - oArray.Free(); - return; - } - - m_nCount = oArray.ArrayGetLength(); - m_ppFuncs = (Function**)MemUtilsMallocArray(m_nCount, sizeof(Function *)); - m_arrBounds = (double *)MemUtilsMallocArray(m_nCount + 1, sizeof(double)); - m_arrEncode = (double *)MemUtilsMallocArray(2 * m_nCount, sizeof(double)); - m_arrScale = (double *)MemUtilsMallocArray(m_nCount, sizeof(double)); - - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - { - m_ppFuncs[nIndex] = NULL; - } - - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - { - Object oTemp; - if (!(m_ppFuncs[nIndex] = Function::Parse(oArray.ArrayGet(nIndex, &oTemp)))) - { - oTemp.Free(); - oArray.Free(); - return; - } - - if (nIndex > 0 && (m_ppFuncs[nIndex]->GetInputSize() != 1 || m_ppFuncs[nIndex]->GetOutputSize() != m_ppFuncs[0]->GetOutputSize())) - { - // TO DO: Error "Incompatible subfunctions in stitching function" - oTemp.Free(); - oArray.Free(); - return; - } - oTemp.Free(); - } - oArray.Free(); - - // Bounds - if (!pDict->Search("Bounds", &oArray)->IsArray() || oArray.ArrayGetLength() != m_nCount - 1) - { - // TO DO: Error "Missing or invalid 'Bounds' entry in stitching function" - oArray.Free(); - return; - } - m_arrBounds[0] = m_arrDomain[0][0]; - for (int nIndex = 1; nIndex < m_nCount; ++nIndex) - { - Object oTemp; - if (!oArray.ArrayGet(nIndex - 1, &oTemp)->IsNum()) - { - // TO DO: Error "Invalid type in 'Bounds' array in stitching function" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrBounds[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - m_arrBounds[m_nCount] = m_arrDomain[0][1]; - oArray.Free(); - - // Encode - if (!pDict->Search("Encode", &oArray)->IsArray() || oArray.ArrayGetLength() != 2 * m_nCount) - { - // TO DO: Error "Missing or invalid 'Encode' entry in stitching function" - oArray.Free(); - return; - } - - for (int nIndex = 0; nIndex < 2 * m_nCount; ++nIndex) - { - Object oTemp; - if (!oArray.ArrayGet(nIndex, &oTemp)->IsNum()) - { - // TO DO: Error "Invalid type in 'Encode' array in stitching function" - oTemp.Free(); - oArray.Free(); - return; - } - m_arrEncode[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - oArray.Free(); - - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - { - if (m_arrBounds[nIndex] == m_arrBounds[nIndex + 1]) - { - // Чтобы избежать деление на 0, в данном случае функция с номером nIndex не будет использоваться - m_arrScale[nIndex] = 0; - } - else - { - m_arrScale[nIndex] = (m_arrEncode[2 * nIndex + 1] - m_arrEncode[2 * nIndex]) / (m_arrBounds[nIndex + 1] - m_arrBounds[nIndex]); - } - } - - m_bValid = true; - return; - } - - StitchingFunction::StitchingFunction(StitchingFunction *pFunc) - { - m_nCount = pFunc->m_nCount; - m_ppFuncs = (Function **)MemUtilsMallocArray(m_nCount, sizeof(Function *)); - - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - { - m_ppFuncs[nIndex] = pFunc->m_ppFuncs[nIndex]->Copy(); - } - - m_arrBounds = (double *)MemUtilsMallocArray(m_nCount + 1, sizeof(double)); - memcpy(m_arrBounds, pFunc->m_arrBounds, (m_nCount + 1) * sizeof(double)); - - m_arrEncode = (double *)MemUtilsMallocArray(2 * m_nCount, sizeof(double)); - memcpy(m_arrEncode, pFunc->m_arrEncode, 2 * m_nCount * sizeof(double)); - - m_arrScale = (double *)MemUtilsMallocArray(m_nCount, sizeof(double)); - memcpy(m_arrScale, pFunc->m_arrScale, m_nCount * sizeof(double)); - - m_bValid = true; - } - - StitchingFunction::~StitchingFunction() - { - if (m_ppFuncs) - { - for (int nIndex = 0; nIndex < m_nCount; ++nIndex) - { - delete m_ppFuncs[nIndex]; - } - } - MemUtilsFree(m_ppFuncs); - MemUtilsFree(m_arrBounds); - MemUtilsFree(m_arrEncode); - MemUtilsFree(m_arrScale); - } - - void StitchingFunction::Transform(double *pInput, double *pOutput) - { - double dX; - - if (pInput[0] < m_arrDomain[0][0]) - { - dX = m_arrDomain[0][0]; - } - else if (pInput[0] > m_arrDomain[0][1]) - { - dX = m_arrDomain[0][1]; - } - else - { - dX = pInput[0]; - } - - int nIndex = 0; - for (nIndex = 0; nIndex < m_nCount - 1; ++nIndex) - { - if (dX < m_arrBounds[nIndex + 1]) - { - break; - } - } - dX = m_arrEncode[2 * nIndex] + (dX - m_arrBounds[nIndex]) * m_arrScale[nIndex]; - m_ppFuncs[nIndex]->Transform(&dX, pOutput); - } - - //------------------------------------------------------------------------ - // PostScriptFunction - //------------------------------------------------------------------------ - - enum PSOperations - { - psOperationAbs, - psOperationAdd, - psOperationAnd, - psOperationAtan, - psOperationBitshift, - psOperationCeiling, - psOperationCopy, - psOperationCos, - psOperationCvi, - psOperationCvr, - psOperationDiv, - psOperationDup, - psOperationEq, - psOperationExch, - psOperationExp, - psOperationFalse, - psOperationFloor, - psOperationGe, - psOperationGt, - psOperationIdiv, - psOperationIndex, - psOperationLe, - psOperationLn, - psOperationLog, - psOperationLt, - psOperationMod, - psOperationMul, - psOperationNe, - psOperationNeg, - psOperationNot, - psOperationOr, - psOperationPop, - psOperationRoll, - psOperationRound, - psOperationSin, - psOperationSqrt, - psOperationSub, - psOperationTrue, - psOperationTruncate, - psOperationXor, - psOperationIf, - psOperationIfelse, - psOperationReturn - }; - - // Список идет в алфавитном порядке. Номер элемента здесь, соответствует - // операции в перечисляемом типе PSOperations - char *c_sPSOperationNames[] = - { - "abs", - "add", - "and", - "atan", - "bitshift", - "ceiling", - "copy", - "cos", - "cvi", - "cvr", - "div", - "dup", - "eq", - "exch", - "exp", - "false", - "floor", - "ge", - "gt", - "idiv", - "index", - "le", - "ln", - "log", - "lt", - "mod", - "mul", - "ne", - "neg", - "not", - "or", - "pop", - "roll", - "round", - "sin", - "sqrt", - "sub", - "true", - "truncate", - "xor" - }; - -#define PSOperationsCount (sizeof(c_sPSOperationNames) / sizeof(char *)) - - enum PSObjectType - { - psBool, - psInt, - psReal, - psOperator, - psBlock - }; - - // В потоке, операторы 'if'/'ifelse' занимают три слота. - // - // +---------------------------------+ - // | psOperator: If / Ifelse | - // +---------------------------------+ - // | psBlock: указатель = | - // +---------------------------------+ - // | psBlock: указатель = | - // +---------------------------------+ - // | if | - // | ... | - // | psOperator: Return | - // +---------------------------------+ - // | else | - // | ... | - // | psOperator: Return | - // +---------------------------------+ - // | ... | - // - // Если оператор = 'if', указатель все задан, но не используется - - struct PSObject - { - PSObjectType eType; - union - { - bool uBool; // boolean (stack only) - int uInt; // integer (stack and code) - double uReal; // real (stack and code) - PSOperations uOperation; // operator (code only) - int uBlock; // if/ifelse block pointer (code only) - }; - }; - -#define psStackSize 100 - - class PSStack - { - public: - - PSStack() - { - m_nStackSize = psStackSize; - } - void PushBool(bool bBool) - { - if (CheckOverflow()) - { - m_arrStack[--m_nStackSize].eType = psBool; - m_arrStack[m_nStackSize].uBool = bBool; - } - } - - void PushInt(int nInteger) - { - if (CheckOverflow()) - { - m_arrStack[--m_nStackSize].eType = psInt; - m_arrStack[m_nStackSize].uInt = nInteger; - } - } - - void PushReal(double dReal) - { - if (CheckOverflow()) - { - m_arrStack[--m_nStackSize].eType = psReal; - m_arrStack[m_nStackSize].uReal = dReal; - } - } - - bool PopBool() - { - if (CheckUnderflow() && CheckType(psBool, psBool)) - { - return m_arrStack[m_nStackSize++].uBool; - } - return false; - } - - int PopInt() - { - if (CheckUnderflow() && CheckType(psInt, psInt)) - { - return m_arrStack[m_nStackSize++].uInt; - } - return 0; - } - - double PopNum() - { - if (CheckUnderflow() && CheckType(psInt, psReal)) - { - double dReturn = (m_arrStack[m_nStackSize].eType == psInt) ? (double)m_arrStack[m_nStackSize].uInt : m_arrStack[m_nStackSize].uReal; - ++m_nStackSize; - return dReturn; - } - return 0; - } - - bool Empty() - { - return m_nStackSize == psStackSize; - } - bool TopIsInt() - { - return m_nStackSize < psStackSize && m_arrStack[m_nStackSize].eType == psInt; - } - bool TopTwoAreInts() - { - return m_nStackSize < psStackSize - 1 && m_arrStack[m_nStackSize].eType == psInt && m_arrStack[m_nStackSize + 1].eType == psInt; - } - bool TopIsReal() - { - return m_nStackSize < psStackSize && m_arrStack[m_nStackSize].eType == psReal; - } - bool TopTwoAreNums() - { - return m_nStackSize < psStackSize - 1 && (m_arrStack[m_nStackSize].eType == psInt || m_arrStack[m_nStackSize].eType == psReal) && (m_arrStack[m_nStackSize + 1].eType == psInt || m_arrStack[m_nStackSize + 1].eType == psReal); - } - - void Copy(int nCount) - { - if (m_nStackSize + nCount > psStackSize) - { - // TO DO: Error "Stack underflow in PostScript function" - return; - } - if (!CheckOverflow(nCount)) - { - return; - } - for (int nIndex = m_nStackSize + nCount - 1; nIndex >= m_nStackSize; --nIndex) - { - m_arrStack[nIndex - nCount] = m_arrStack[nIndex]; - } - m_nStackSize -= nCount; - } - - void Roll(int n, int j) - { - int i, k; - - if (j >= 0) - { - j %= n; - } - else - { - j = -j % n; - if (j != 0) - { - j = n - j; - } - } - if (n <= 0 || j == 0) - { - return; - } - for (i = 0; i < j; ++i) - { - PSObject oPSObject = m_arrStack[m_nStackSize]; - for (k = m_nStackSize; k < m_nStackSize + n - 1; ++k) - { - m_arrStack[k] = m_arrStack[k + 1]; - } - m_arrStack[m_nStackSize + n - 1] = oPSObject; - } - } - - void Index(int nIndex) - { - if (!CheckOverflow()) - { - return; - } - --m_nStackSize; - m_arrStack[m_nStackSize] = m_arrStack[m_nStackSize + 1 + nIndex]; - } - - void Pop() - { - if (!CheckUnderflow()) - { - return; - } - ++m_nStackSize; - } - - - private: - - bool CheckOverflow(int nCount = 1) - { - if (m_nStackSize - nCount < 0) - { - // TO DO: Error "Stack overflow in PostScript function" - return false; - } - return true; - } - - bool CheckUnderflow() - { - if (m_nStackSize == psStackSize) - { - // TO DO: Error "Stack underflow in PostScript function" - return false; - } - return true; - } - - bool CheckType(PSObjectType eType1, PSObjectType eType2) - { - if (m_arrStack[m_nStackSize].eType != eType1 && m_arrStack[m_nStackSize].eType != eType2) - { - // TO DO: Error "Type mismatch in PostScript function" - return false; - } - return true; - } - - private: - - PSObject m_arrStack[psStackSize]; - int m_nStackSize; - }; - - PostScriptFunction::PostScriptFunction(Object *pFuncObject, Dict *pDict) - { - m_pCode = NULL; - m_nCodeSize = 0; - m_bValid = false; - - if (!Initialize(pDict)) - { - return; - } - if (!m_bHasRange) - { - // TO DO: Error "Type 4 function is missing range" - return; - } - - if (!pFuncObject->IsStream()) - { - // TO DO: Error "Type 4 function isn't a stream" - return; - } - Stream *pStream = pFuncObject->GetStream(); - - //----- parse the function - m_seCodeString = new StringExt(); - pStream->Reset(); - - StringExt *seToken; - if (!(seToken = GetToken(pStream)) || seToken->Compare("{")) - { - // TO DO: Error "Expected '{' at start of PostScript function" - MemUtilsFree(seToken); - pStream->Close(); - return; - } - if (seToken) - delete seToken; - int nCodePos = 0; - if (!ParseCode(pStream, &nCodePos)) - { - pStream->Close(); - return; - } - pStream->Close(); - - m_bValid = true; - } - - PostScriptFunction::PostScriptFunction(PostScriptFunction *pFunc) - { - memcpy(this, pFunc, sizeof(PostScriptFunction)); - m_pCode = (PSObject *)MemUtilsMallocArray(m_nCodeSize, sizeof(PSObject)); - memcpy(m_pCode, pFunc->m_pCode, m_nCodeSize * sizeof(PSObject)); - m_seCodeString = pFunc->m_seCodeString->Copy(); - } - - PostScriptFunction::~PostScriptFunction() - { - MemUtilsFree(m_pCode); - if (m_seCodeString) - delete m_seCodeString; - } - - void PostScriptFunction::Transform(double *pInput, double *pOutput) - { - PSStack *pStack = new PSStack(); - if (!pStack) - return; - - for (int nIndex = 0; nIndex < m_nInputDim; ++nIndex) - { - pStack->PushReal(pInput[nIndex]); - } - Exec(pStack, 0); - - for (int nIndex = m_nOutputDim - 1; nIndex >= 0; --nIndex) - { - pOutput[nIndex] = pStack->PopNum(); - if (pOutput[nIndex] < m_arrRange[nIndex][0]) - { - pOutput[nIndex] = m_arrRange[nIndex][0]; - } - else if (pOutput[nIndex] > m_arrRange[nIndex][1]) - { - pOutput[nIndex] = m_arrRange[nIndex][1]; - } - } - delete pStack; - } - - bool PostScriptFunction::ParseCode(Stream *pStream, int *pnCodePos) - { - StringExt *seToken; - - while (1) - { - if (!(seToken = GetToken(pStream))) - { - // TO DO: Error "Unexpected end of PostScript function stream" - return false; - } - if (!seToken) - return false; - - char *pCurChar = seToken->GetBuffer(); - - if (isdigit(*pCurChar) || *pCurChar == '.' || *pCurChar == '-') - { - bool bReal = false; - for (++pCurChar; *pCurChar; ++pCurChar) - { - if (*pCurChar == '.') - { - bReal = true; - break; - } - } - ResizeCode(*pnCodePos); - if (bReal) - { - m_pCode[*pnCodePos].eType = psReal; - m_pCode[*pnCodePos].uReal = atof(seToken->GetBuffer()); - } - else - { - m_pCode[*pnCodePos].eType = psInt; - m_pCode[*pnCodePos].uInt = atoi(seToken->GetBuffer()); - } - ++*pnCodePos; - delete seToken; - } - else if (!seToken->Compare("{")) - { - delete seToken; - int nOperatorPos = *pnCodePos; - int nElsePos = 0; - *pnCodePos += 3; - ResizeCode(nOperatorPos + 2); - if (!ParseCode(pStream, pnCodePos)) - { - return false; - } - if (!(seToken = GetToken(pStream))) - { - // TO DO: Error "Unexpected end of PostScript function stream" - return false; - } - if (!seToken->Compare("{")) - { - nElsePos = *pnCodePos; - if (!ParseCode(pStream, pnCodePos)) - { - return false; - } - delete seToken; - if (!(seToken = GetToken(pStream))) - { - // TO DO: Error "Unexpected end of PostScript function stream" - return false; - } - } - else - { - nElsePos = -1; - } - if (!seToken->Compare("if")) - { - if (nElsePos >= 0) - { - // TO DO: Error "Got 'if' operator with two blocks in PostScript function" - return false; - } - m_pCode[nOperatorPos].eType = psOperator; - m_pCode[nOperatorPos].uOperation = psOperationIf; - m_pCode[nOperatorPos + 2].eType = psBlock; - m_pCode[nOperatorPos + 2].uBlock = *pnCodePos; - } - else if (!seToken->Compare("ifelse")) - { - if (nElsePos < 0) - { - // TO DO: Error "Got 'ifelse' operator with one blocks in PostScript function" - return false; - } - m_pCode[nOperatorPos].eType = psOperator; - m_pCode[nOperatorPos].uOperation = psOperationIfelse; - m_pCode[nOperatorPos + 1].eType = psBlock; - m_pCode[nOperatorPos + 1].uBlock = nElsePos; - m_pCode[nOperatorPos + 2].eType = psBlock; - m_pCode[nOperatorPos + 2].uBlock = *pnCodePos; - } - else - { - // TO DO: Error "Expected if/ifelse operator in PostScript function" - delete seToken; - return false; - } - delete seToken; - } - else if (!seToken->Compare("}")) - { - delete seToken; - ResizeCode(*pnCodePos); - m_pCode[*pnCodePos].eType = psOperator; - m_pCode[*pnCodePos].uOperation = psOperationReturn; - ++*pnCodePos; - break; - } - else - { - int nFirst = -1; - int nSecond = PSOperationsCount; - // invariant: psOpNames[a] < tok < psOpNames[b] - int nCompareRes = 0; - while (nSecond - nFirst > 1) - { - int nMiddle = (nFirst + nSecond) / 2; - nCompareRes = seToken->Compare(c_sPSOperationNames[nMiddle]); - if (nCompareRes > 0) - { - nFirst = nMiddle; - } - else if (nCompareRes < 0) - { - nSecond = nMiddle; - } - else - { - nFirst = nSecond = nMiddle; - } - } - if (nCompareRes != 0) - { - // TO DO: Error "Unknown operator in PostScript function" - delete seToken; - return false; - } - delete seToken; - ResizeCode(*pnCodePos); - m_pCode[*pnCodePos].eType = psOperator; - m_pCode[*pnCodePos].uOperation = (PSOperations)nFirst; - ++*pnCodePos; - } - } - return true; - } - - StringExt *PostScriptFunction::GetToken(Stream *pStream) - { - int nChar = 0; - - StringExt *seResult = new StringExt(); - bool bComment = false; - - while (1) - { - if ((nChar = pStream->GetChar()) == EOF) - { - break; - } - m_seCodeString->Append(nChar); - if (bComment) - { - if (nChar == '\x0a' || nChar == '\x0d') - { - bComment = false; - } - } - else if (nChar == '%') - { - bComment = true; - } - else if (!isspace(nChar)) - { - break; - } - } - if (nChar == '{' || nChar == '}') - { - seResult->Append((char)nChar); - } - else if (isdigit(nChar) || nChar == '.' || nChar == '-') - { - while (1) - { - seResult->Append((char)nChar); - nChar = pStream->LookChar(); - if (nChar == EOF || !(isdigit(nChar) || nChar == '.' || nChar == '-')) - { - break; - } - pStream->GetChar(); - m_seCodeString->Append(nChar); - } - } - else - { - while (1) - { - seResult->Append((char)nChar); - nChar = pStream->LookChar(); - if (nChar == EOF || !isalnum(nChar)) - { - break; - } - pStream->GetChar(); - m_seCodeString->Append(nChar); - } - } - return seResult; - } - - void PostScriptFunction::ResizeCode(int nNewSize) - { - if (nNewSize >= m_nCodeSize) - { - m_nCodeSize += 64; - m_pCode = (PSObject *)MemUtilsReallocArray(m_pCode, m_nCodeSize, sizeof(PSObject)); - } - } - - void PostScriptFunction::Exec(PSStack *pStack, int codePtr) - { - int nInteger1 = 0, nInteger2 = 0; - double dReal1 = 0, dReal2 = 0; - bool bBool1 = false, bBool2 = false; - - while (1) - { - switch (m_pCode[codePtr].eType) - { - case psInt: - pStack->PushInt(m_pCode[codePtr++].uInt); - break; - case psReal: - pStack->PushReal(m_pCode[codePtr++].uReal); - break; - case psOperator: - switch (m_pCode[codePtr++].uOperation) - { - case psOperationAbs: - if (pStack->TopIsInt()) - { - pStack->PushInt(abs(pStack->PopInt())); - } - else - { - pStack->PushReal(fabs(pStack->PopNum())); - } - break; - case psOperationAdd: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 + nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(dReal1 + dReal2); - } - break; - case psOperationAnd: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 & nInteger2); - } - else - { - bBool2 = pStack->PopBool(); - bBool1 = pStack->PopBool(); - pStack->PushBool(bBool1 && bBool2); - } - break; - case psOperationAtan: - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(atan2(dReal1, dReal2)); - break; - case psOperationBitshift: - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - if (nInteger2 > 0) - { - pStack->PushInt(nInteger1 << nInteger2); - } - else if (nInteger2 < 0) - { - pStack->PushInt((int)((unsigned int)nInteger1 >> nInteger2)); - } - else - { - pStack->PushInt(nInteger1); - } - break; - case psOperationCeiling: - if (!pStack->TopIsInt()) - { - pStack->PushReal(ceil(pStack->PopNum())); - } - break; - case psOperationCopy: - pStack->Copy(pStack->PopInt()); - break; - case psOperationCos: - pStack->PushReal(cos(pStack->PopNum())); - break; - case psOperationCvi: - if (!pStack->TopIsInt()) - { - pStack->PushInt((int)pStack->PopNum()); - } - break; - case psOperationCvr: - if (!pStack->TopIsReal()) - { - pStack->PushReal(pStack->PopNum()); - } - break; - case psOperationDiv: - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(dReal1 / dReal2); - break; - case psOperationDup: - pStack->Copy(1); - break; - case psOperationEq: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 == nInteger2); - } - else if (pStack->TopTwoAreNums()) - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 == dReal2); - } - else - { - bBool2 = pStack->PopBool(); - bBool1 = pStack->PopBool(); - pStack->PushBool(bBool1 == bBool2); - } - break; - case psOperationExch: - pStack->Roll(2, 1); - break; - case psOperationExp: - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(pow(dReal1, dReal2)); - break; - case psOperationFalse: - pStack->PushBool(false); - break; - case psOperationFloor: - if (!pStack->TopIsInt()) - { - pStack->PushReal(floor(pStack->PopNum())); - } - break; - case psOperationGe: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 >= nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 >= dReal2); - } - break; - case psOperationGt: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 > nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 > dReal2); - } - break; - case psOperationIdiv: - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 / nInteger2); - break; - case psOperationIndex: - pStack->Index(pStack->PopInt()); - break; - case psOperationLe: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 <= nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 <= dReal2); - } - break; - case psOperationLn: - pStack->PushReal(log(pStack->PopNum())); - break; - case psOperationLog: - pStack->PushReal(log10(pStack->PopNum())); - break; - case psOperationLt: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 < nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 < dReal2); - } - break; - case psOperationMod: - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 % nInteger2); - break; - case psOperationMul: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - //~ should check for out-of-range, and push a real instead - pStack->PushInt(nInteger1 * nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(dReal1 * dReal2); - } - break; - case psOperationNe: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushBool(nInteger1 != nInteger2); - } - else if (pStack->TopTwoAreNums()) - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushBool(dReal1 != dReal2); - } - else - { - bBool2 = pStack->PopBool(); - bBool1 = pStack->PopBool(); - pStack->PushBool(bBool1 != bBool2); - } - break; - case psOperationNeg: - if (pStack->TopIsInt()) - { - pStack->PushInt(-pStack->PopInt()); - } - else - { - pStack->PushReal(-pStack->PopNum()); - } - break; - case psOperationNot: - if (pStack->TopIsInt()) - { - pStack->PushInt(~pStack->PopInt()); - } - else - { - pStack->PushBool(!pStack->PopBool()); - } - break; - case psOperationOr: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 | nInteger2); - } - else - { - bBool2 = pStack->PopBool(); - bBool1 = pStack->PopBool(); - pStack->PushBool(bBool1 || bBool2); - } - break; - case psOperationPop: - pStack->Pop(); - break; - case psOperationRoll: - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->Roll(nInteger1, nInteger2); - break; - case psOperationRound: - if (!pStack->TopIsInt()) - { - dReal1 = pStack->PopNum(); - pStack->PushReal((dReal1 >= 0) ? floor(dReal1 + 0.5) : ceil(dReal1 - 0.5)); - } - break; - case psOperationSin: - pStack->PushReal(sin(pStack->PopNum())); - break; - case psOperationSqrt: - pStack->PushReal(sqrt(pStack->PopNum())); - break; - case psOperationSub: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 - nInteger2); - } - else - { - dReal2 = pStack->PopNum(); - dReal1 = pStack->PopNum(); - pStack->PushReal(dReal1 - dReal2); - } - break; - case psOperationTrue: - pStack->PushBool(true); - break; - case psOperationTruncate: - if (!pStack->TopIsInt()) - { - dReal1 = pStack->PopNum(); - pStack->PushReal((dReal1 >= 0) ? floor(dReal1) : ceil(dReal1)); - } - break; - case psOperationXor: - if (pStack->TopTwoAreInts()) - { - nInteger2 = pStack->PopInt(); - nInteger1 = pStack->PopInt(); - pStack->PushInt(nInteger1 ^ nInteger2); - } - else - { - bBool2 = pStack->PopBool(); - bBool1 = pStack->PopBool(); - pStack->PushBool(bBool1 ^ bBool2); - } - break; - case psOperationIf: - bBool1 = pStack->PopBool(); - if (bBool1) - { - Exec(pStack, codePtr + 2); - } - codePtr = m_pCode[codePtr + 1].uBlock; - break; - case psOperationIfelse: - bBool1 = pStack->PopBool(); - if (bBool1) - { - Exec(pStack, codePtr + 2); - } - else - { - Exec(pStack, m_pCode[codePtr].uBlock); - } - codePtr = m_pCode[codePtr + 1].uBlock; - break; - case psOperationReturn: - return; - } - break; - default: - // TO DO: Error "Internal: bad object in PostScript function code" - break; - } - } - } -} \ No newline at end of file diff --git a/PdfReader/old/Function.h b/PdfReader/old/Function.h deleted file mode 100644 index f92a04f4f3..0000000000 --- a/PdfReader/old/Function.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_FUNCTION_H -#define _PDF_READER_FUNCTION_H - -#include "Object.h" - -namespace PdfReader -{ - class Dict; - class Stream; - struct PSObject; - class PSStack; - - //------------------------------------------------------------------------ - // Function - //------------------------------------------------------------------------ - -#define funcMaxInputs 32 -#define funcMaxOutputs 32 -#define sampledFuncMaxInputs 16 - - class Function - { - public: - - Function(); - - virtual ~Function(); - - static Function *Parse(Object *pFuncObject); - - // Заполняем Domain и Range - bool Initialize(Dict *pDict); - - virtual Function *Copy() = 0; - - // Типы функций - // -1 : identity - // 0 : sampled - // 2 : exponential - // 3 : stitching - // 4 : PostScript - virtual int GetType() = 0; - - int GetInputSize() - { - return m_nInputDim; - } - int GetOutputSize() - { - return m_nOutputDim; - } - - double GetDomainMin(int nIndex) - { - return m_arrDomain[nIndex][0]; - } - double GetDomainMax(int nIndex) - { - return m_arrDomain[nIndex][1]; - } - double GetRangeMin(int nIndex) - { - return m_arrRange[nIndex][0]; - } - double GetRangeMax(int nIndex) - { - return m_arrRange[nIndex][1]; - } - bool HasRange() - { - return m_bHasRange; - } - - // Собственно, работа самой функции. pInput - набор входящих параметров, pOutput - выходящие значения. - virtual void Transform(double *pInput, double *pOutput) = 0; - - virtual bool IsValid() = 0; - - protected: - - - int m_nInputDim; // Function: R^(InputDim) -> R^(OutputDim) - int m_nOutputDim; // - double m_arrDomain[funcMaxInputs][2]; // Минимум и максимум для каждой входящей переменной - double m_arrRange[funcMaxOutputs][2]; // Минимум и максимум для каждого выходящего параметра - bool m_bHasRange; // Domain должен быть задан всегда, а Range может отсутствовать - }; - - //------------------------------------------------------------------------ - // IdentityFunction - //------------------------------------------------------------------------ - - class IdentityFunction : public Function - { - public: - - IdentityFunction(); - virtual ~IdentityFunction(); - virtual Function *Copy() - { - return new IdentityFunction(); - } - virtual int GetType() - { - return -1; - } - virtual void Transform(double *pInput, double *pOutput); - virtual bool IsValid() - { - return true; - } - - private: - }; - - //------------------------------------------------------------------------ - // SampledFunction (Type0 Function) - //------------------------------------------------------------------------ - - // На самом деле это аппроксимационная функция. Здесь должны быть заданы - // точки и значения функции в данных точках, и тогда данная функция - // воспринимается как аппромаксионная функция по заданным значениям, причем - // аппрокимация зависит от поля Order, 1 - линейная интерполяция, - // 3 - интерполяция. - - // Пока реализована только линейная интерполяция. - class SampledFunction : public Function - { - public: - - SampledFunction(Object *pFuncObject, Dict *pDict); - virtual ~SampledFunction(); - virtual Function *Copy() - { - return new SampledFunction(this); - } - virtual int GetType() - { - return 0; - } - virtual void Transform(double *pInput, double *pOutput); - virtual bool IsValid() - { - return m_bValid; - } - - - int GetSampleSize(int nIndex) - { - return m_arrSize[nIndex]; - } - double GetEncodeMin(int nIndex) - { - return m_arrEncoder[nIndex][0]; - } - double GetEncodeMax(int nIndex) - { - return m_arrEncoder[nIndex][1]; - } - double GetDecodeMin(int nIndex) - { - return m_arrDecoder[nIndex][0]; - } - double GetDecodeMax(int nIndex) - { - return m_arrDecoder[nIndex][1]; - } - double *GetSamples() - { - return m_pSamples; - } - - private: - - SampledFunction(SampledFunction *pFunc); - - private: - - int m_arrSize[funcMaxInputs]; // Количество различных значений, которые может принимать данный параметр - double m_arrEncoder[funcMaxInputs][2]; // Минимум и максимум для Domain encoder - double m_arrDecoder[funcMaxOutputs][2]; // Минимум и максимум для Range decoder - double m_arrInputMult[funcMaxInputs]; // - int m_arrIndexMult[funcMaxInputs]; // - double *m_pSamples; // Собственно сами значения - int m_nSamplesCount; // Количество заданных значений - double *m_pBuffer; // Буфер для функции преобразования - - bool m_bValid; - }; - - //------------------------------------------------------------------------ - // ExponentialFunction - //------------------------------------------------------------------------ - - class ExponentialFunction : public Function - { - public: - - ExponentialFunction(Object *pFuncObject, Dict *pDict); - virtual ~ExponentialFunction(); - virtual Function *Copy() - { - return new ExponentialFunction(this); - } - virtual int GetType() - { - return 2; - } - virtual void Transform(double *pInput, double *pOutput); - virtual bool IsValid() - { - return m_bValid; - } - - double *GetC0() - { - return m_arrC0; - } - double *GetC1() - { - return m_arrC1; - } - double GetN() - { - return m_dN; - } - - private: - - ExponentialFunction(ExponentialFunction *pFunc); - - private: - - double m_arrC0[funcMaxOutputs]; - double m_arrC1[funcMaxOutputs]; - double m_dN; - - bool m_bValid; - }; - - //------------------------------------------------------------------------ - // StitchingFunction - //------------------------------------------------------------------------ - - // Кусочная функция. В массиве m_arrBounds задаются точки деления исходного - // отрезка. Domain0 < Bounds0 < Bounds1 < ... < Bounds(K - 2) < Domain1. - // i-ая функция задана на полуинтервале [ Bounds(i - 1), Bounds(i) ), - // где Bounds(-1) = Domain0, Bound(k-1) = Domain1 (услованая запись, в массиве - // m_arrBounds эти значения не входят). - class StitchingFunction : public Function - { - public: - - StitchingFunction(Object *pFuncObject, Dict *pDict); - virtual ~StitchingFunction(); - virtual Function *Copy() - { - return new StitchingFunction(this); - } - virtual int GetType() - { - return 3; - } - virtual void Transform(double *pInput, double *pOutput); - virtual bool IsValid() - { - return m_bValid; - } - - int GetFunctionsCount() - { - return m_nCount; - } - Function *GetFunction(int nIndex) - { - return m_ppFuncs[nIndex]; - } - double *GetBounds() - { - return m_arrBounds; - } - double *GetEncode() - { - return m_arrEncode; - } - double *GetScale() - { - return m_arrScale; - } - - private: - - StitchingFunction(StitchingFunction *pFunc); - - private: - - int m_nCount; // количество функций - Function **m_ppFuncs; // сами функции - double *m_arrBounds; // Границы областей определения функций - double *m_arrEncode; // Границы множств значений функций - double *m_arrScale; - - bool m_bValid; - }; - - //------------------------------------------------------------------------ - // PostScriptFunction - //------------------------------------------------------------------------ - - class PostScriptFunction : public Function - { - public: - - PostScriptFunction(Object *pFuncObject, Dict *pDict); - virtual ~PostScriptFunction(); - virtual Function *Copy() - { - return new PostScriptFunction(this); - } - virtual int GetType() - { - return 4; - } - virtual void Transform(double *pInput, double *pOutput); - virtual bool IsValid() - { - return m_bValid; - } - StringExt *GetCodeString() - { - return m_seCodeString; - } - - private: - - PostScriptFunction(PostScriptFunction *pFunc); - bool ParseCode(Stream *pStream, int *pnCodePos); - StringExt *GetToken(Stream *pStream); - void ResizeCode(int nNewSize); - void Exec(PSStack *pStack, int nCodePos); - - private: - - StringExt *m_seCodeString; - PSObject *m_pCode; - int m_nCodeSize; - - bool m_bValid; - }; -} - -#endif // _PDF_READER_FUNCTION_H diff --git a/PdfReader/old/GFont.cpp b/PdfReader/old/GFont.cpp deleted file mode 100644 index 9423be5464..0000000000 --- a/PdfReader/old/GFont.cpp +++ /dev/null @@ -1,2002 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "Dict.h" -#include "GlobalParams.h" -#include "CMap.h" -#include "CharCodeToUnicode.h" -#include "EncodingTables.h" -#include "BuiltinFontTables.h" -#include "FontFileType1.h" -#include "FontFileType1C.h" -#include "FontFileTrueType.h" -#include "GFont.h" -#include "File.h" -#include "Stream.h" -#include "XRef.h" - -namespace PdfReader -{ - struct StandardFontMapEntry - { - char *sAlternativeName; - char *sProperName; - }; - - // PDF поддерживает 14 стандартных фонтов(Type1) без указаниях ширин и FontDescriptor, - // поэтому мы состовляем карту отображающую стандартные фонты в 14 основных фонтов PDF. - // Эта таблица составлена на основе "implementation note 44 in the PDF 1.4 spec", с - // небольшими добавками. - static StandardFontMapEntry c_sStandardFontMap[] = - { - { "Arial", "Helvetica" }, - { "Arial,Bold", "Helvetica-Bold" }, - { "Arial,BoldItalic", "Helvetica-BoldOblique" }, - { "Arial,Italic", "Helvetica-Oblique" }, - { "Arial-Bold", "Helvetica-Bold" }, - { "Arial-BoldItalic", "Helvetica-BoldOblique" }, - { "Arial-BoldItalicMT", "Helvetica-BoldOblique" }, - { "Arial-BoldMT", "Helvetica-Bold" }, - { "Arial-Italic", "Helvetica-Oblique" }, - { "Arial-ItalicMT", "Helvetica-Oblique" }, - { "ArialMT", "Helvetica" }, - { "Courier,Bold", "Courier-Bold" }, - { "Courier,BoldItalic", "Courier-BoldOblique" }, - { "Courier,Italic", "Courier-Oblique" }, - { "CourierNew", "Courier" }, - { "CourierNew,Bold", "Courier-Bold" }, - { "CourierNew,BoldItalic", "Courier-BoldOblique" }, - { "CourierNew,Italic", "Courier-Oblique" }, - { "CourierNew-Bold", "Courier-Bold" }, - { "CourierNew-BoldItalic", "Courier-BoldOblique" }, - { "CourierNew-Italic", "Courier-Oblique" }, - { "CourierNewPS-BoldItalicMT", "Courier-BoldOblique" }, - { "CourierNewPS-BoldMT", "Courier-Bold" }, - { "CourierNewPS-ItalicMT", "Courier-Oblique" }, - { "CourierNewPSMT", "Courier" }, - { "Helvetica,Bold", "Helvetica-Bold" }, - { "Helvetica,BoldItalic", "Helvetica-BoldOblique" }, - { "Helvetica,Italic", "Helvetica-Oblique" }, - { "Helvetica-BoldItalic", "Helvetica-BoldOblique" }, - { "Helvetica-Italic", "Helvetica-Oblique" }, - { "Symbol,Bold", "Symbol" }, - { "Symbol,BoldItalic", "Symbol" }, - { "Symbol,Italic", "Symbol" }, - { "TimesNewRoman", "Times-Roman" }, - { "TimesNewRoman,Bold", "Times-Bold" }, - { "TimesNewRoman,BoldItalic", "Times-BoldItalic" }, - { "TimesNewRoman,Italic", "Times-Italic" }, - { "TimesNewRoman-Bold", "Times-Bold" }, - { "TimesNewRoman-BoldItalic", "Times-BoldItalic" }, - { "TimesNewRoman-Italic", "Times-Italic" }, - { "TimesNewRomanPS", "Times-Roman" }, - { "TimesNewRomanPS-Bold", "Times-Bold" }, - { "TimesNewRomanPS-BoldItalic", "Times-BoldItalic" }, - { "TimesNewRomanPS-BoldItalicMT", "Times-BoldItalic" }, - { "TimesNewRomanPS-BoldMT", "Times-Bold" }, - { "TimesNewRomanPS-Italic", "Times-Italic" }, - { "TimesNewRomanPS-ItalicMT", "Times-Italic" }, - { "TimesNewRomanPSMT", "Times-Roman" }, - { "TimesNewRomanPSMT,Bold", "Times-Bold" }, - { "TimesNewRomanPSMT,BoldItalic", "Times-BoldItalic" }, - { "TimesNewRomanPSMT,Italic", "Times-Italic" } - }; - - //------------------------------------------------------------------------ - // GrFont - //------------------------------------------------------------------------ - - GrFont *GrFont::MakeFont(XRef *pXref, char *sTag, Ref oID, Dict *pFontDict, GlobalParams *pGlobalParams) - { - // Считываем название шрифта - StringExt *seName = NULL; - - Object oTemp; - pFontDict->Search("BaseFont", &oTemp); - if (oTemp.IsName()) - { - seName = new StringExt(oTemp.GetName()); - } - oTemp.Free(); - - // Тип шрифта - GrFont *pFont = NULL; - pFontDict->Search("Subtype", &oTemp); - if (oTemp.IsName("Type1") || oTemp.IsName("MMType1")) - { - pFont = new Gr8BitFont(pXref, sTag, oID, seName, fontType1, pFontDict, pGlobalParams); - } - else if (oTemp.IsName("Type1C")) - { - pFont = new Gr8BitFont(pXref, sTag, oID, seName, fontType1C, pFontDict, pGlobalParams); - } - else if (oTemp.IsName("Type3")) - { - pFont = new Gr8BitFont(pXref, sTag, oID, seName, fontType3, pFontDict, pGlobalParams); - } - else if (oTemp.IsName("TrueType")) - { - pFont = new Gr8BitFont(pXref, sTag, oID, seName, fontTrueTypeLN, pFontDict, pGlobalParams); - } - else if (oTemp.IsName("Type0")) - { - pFont = new GrCIDFont(pXref, sTag, oID, seName, pFontDict, pGlobalParams); - } - else - { - if (!seName) - seName = new StringExt(""); - // TO DO: Error "Unknown font type" - pFont = new Gr8BitFont(pXref, sTag, oID, seName, fontUnknownType, pFontDict, pGlobalParams); - } - oTemp.Free(); - - return pFont; - } - - GrFont::GrFont(char *sTag, Ref oID, StringExt *seName, GlobalParams *pGlobalParams) - { - m_pGlobalParams = pGlobalParams; - - m_bValid = false; - m_seTag = new StringExt(sTag); - m_oID = oID; - m_seName = seName; - m_seOriginalName = seName; - m_seEmbeddedFontName = NULL; - m_wsExternalFontFilePath = L""; - } - - GrFont::~GrFont() - { - if (m_seTag) - { - delete m_seTag; - } - if (m_seOriginalName && m_seOriginalName != m_seName) - { - delete m_seOriginalName; - } - if (m_seName) - { - delete m_seName; - } - if (m_seEmbeddedFontName) - { - delete m_seEmbeddedFontName; - } - } - - void GrFont::ReadFontDescriptor(XRef *pXref, Dict *pFontDict) - { - m_nFlags = fontSerif; - - m_oEmbFontFileRef.nNum = -1; - m_oEmbFontFileRef.nGen = -1; - m_dMissingWidth = 0; - - Object oFontDescriptor; - if (pFontDict->Search("FontDescriptor", &oFontDescriptor)->IsDict()) - { - // Flags - Object oDictItem; - if (oFontDescriptor.DictLookup("Flags", &oDictItem)->IsInt()) - { - m_nFlags = oDictItem.GetInt(); - } - oDictItem.Free(); - - // FontName - oFontDescriptor.DictLookup("FontName", &oDictItem); - if (oDictItem.IsName()) - { - m_seEmbeddedFontName = new StringExt(oDictItem.GetName()); - } - oDictItem.Free(); - - // Ищем внедренный FontFile - if (oFontDescriptor.DictLookupAndCopy("FontFile", &oDictItem)->IsRef()) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontType1) - { - // TO DO: Error "Mismatch between font type and embedded font file" - m_eType = fontType1; - } - } - oDictItem.Free(); - - if (m_oEmbFontFileRef.nNum == -1 && oFontDescriptor.DictLookupAndCopy("FontFile2", &oDictItem)->IsRef()) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontTrueTypeLN && m_eType != fontCIDType2) - { - // TO DO: Error "Mismatch between font type and embedded font file" - m_eType = (m_eType == fontCIDType0 ? fontCIDType2 : fontTrueTypeLN); - } - } - oDictItem.Free(); - - if (m_oEmbFontFileRef.nNum == -1 && oFontDescriptor.DictLookupAndCopy("FontFile3", &oDictItem)->IsRef()) - { - Object oStream; - if (oDictItem.Fetch(pXref, &oStream)->IsStream()) - { - Object oTemp; - oStream.StreamGetDict()->Search("Subtype", &oTemp); - if (oTemp.IsName("Type1")) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontType1) - { - // TO DO: Error "Mismatch between font type and embedded font file" - m_eType = fontType1; - } - } - else if (oTemp.IsName("Type1C")) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontType1 && m_eType != fontType1C) - { - // TO DO: Error "Mismatch between font type and embedded font file" - } - m_eType = fontType1C; - } - else if (oTemp.IsName("TrueType")) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontTrueTypeLN) - { - // TO DO: Error "Mismatch between font type and embedded font file" - m_eType = fontTrueTypeLN; - } - } - else if (oTemp.IsName("CIDFontType0C")) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType != fontCIDType0) - { - // TO DO: Error "Mismatch between font type and embedded font file" - } - m_eType = fontCIDType0C; - } - else if (oTemp.IsName("OpenType")) - { - m_oEmbFontFileRef = oDictItem.GetRef(); - if (m_eType == fontTrueTypeLN) - { - m_eType = fontTrueTypeLNOT; - } - else if (m_eType == fontType1) - { - m_eType = fontType1COT; - } - else if (m_eType == fontCIDType0) - { - m_eType = fontCIDType0COT; - } - else if (m_eType == fontCIDType2) - { - m_eType = fontCIDType2OT; - } - else - { - // TO DO: Error "Mismatch between font type and embedded font file" - } - } - else - { - // TO DO: Error "Unknown embedded font type" - } - oTemp.Free(); - } - oStream.Free(); - } - oDictItem.Free(); - - // MissingWidth - oFontDescriptor.DictLookup("MissingWidth", &oDictItem); - if (oDictItem.IsNum()) - { - m_dMissingWidth = oDictItem.GetNum(); - } - oDictItem.Free(); - - double dTemp = 0; - // Ascent - oFontDescriptor.DictLookup("Ascent", &oDictItem); - if (oDictItem.IsNum()) - { - dTemp = 0.001 * oDictItem.GetNum(); - // Некоторые неправильнае шрифты устанавливают Ascent и Descent равными 0 - if (dTemp != 0) - { - m_dAscent = dTemp; - } - } - oDictItem.Free(); - - // Descent - oFontDescriptor.DictLookup("Descent", &oDictItem); - if (oDictItem.IsNum()) - { - dTemp = 0.001 * oDictItem.GetNum(); - // Некоторые неправильнае шрифты устанавливают Ascent и Descent равными 0 - if (dTemp != 0) - { - m_dDescent = dTemp; - } - // Descent должно быть отрицательным значением - if (m_dDescent > 0) - { - m_dDescent = -m_dDescent; - } - } - oDictItem.Free(); - - // FontBBox - if (oFontDescriptor.DictLookup("FontBBox", &oDictItem)->IsArray()) - { - for (int nIndex = 0; nIndex < 4 && nIndex < oDictItem.ArrayGetLength(); ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - m_arrFontBBox[nIndex] = 0.001 * oTemp.GetNum(); - } - oTemp.Free(); - } - } - oDictItem.Free(); - - } - oFontDescriptor.Free(); - } - - CharCodeToUnicode *GrFont::ReadToUnicodeCMap(Dict *pFontDict, int nBitsCount, CharCodeToUnicode *pCharToUnicode) - { - Object oTemp; - if (!pFontDict->Search("ToUnicode", &oTemp)->IsStream()) - { - oTemp.Free(); - return NULL; - } - StringExt *seBuffer = new StringExt(); - oTemp.StreamReset(); - int nChar = 0; - while ((nChar = oTemp.StreamGetChar()) != EOF) - { - seBuffer->Append(nChar); - } - oTemp.StreamClose(); - oTemp.Free(); - if (pCharToUnicode) - { - pCharToUnicode->MergeCMap(seBuffer, nBitsCount, m_pGlobalParams); - } - else - { - pCharToUnicode = CharCodeToUnicode::ParseCMap(seBuffer, nBitsCount, m_pGlobalParams); - } - delete seBuffer; - return pCharToUnicode; - } - - void GrFont::FindExternalFontFile(bool bBuiltin) - { - static wchar_t *c_wsType1Ext[] ={ L".pfa", L".pfb", L".ps", L"", NULL }; - static wchar_t *c_wsTTFExts[] ={ L".ttf", NULL }; - - if (m_pGlobalParams && m_seName) - { - if (bBuiltin) - { - if (!GetEmbeddedFontFileRef(&m_oEmbFontFileRef)) - { - m_wsExternalFontFilePath = m_pGlobalParams->GetBuiltinFontPath(m_seName); - m_eType = fontType1; - } - } - else - { - if (m_eType == fontType1) - { - m_wsExternalFontFilePath = m_pGlobalParams->FindFontFile(m_seName, c_wsType1Ext); - } - else if (m_eType == fontTrueTypeLN) - { - m_wsExternalFontFilePath = m_pGlobalParams->FindFontFile(m_seName, c_wsTTFExts); - } - } - } - } - - char *GrFont::ReadExternalFontFile(int *pnLen) - { - FILE* pFile = NSFile::CFileBinary::OpenFileNative(m_wsExternalFontFilePath, L"rb"); - if (!pFile) - { - // TO DO: Error "External font file vanished" - return NULL; - } - - fseek(pFile, 0, SEEK_END); - *pnLen = (int)ftell(pFile); - fseek(pFile, 0, SEEK_SET); - - char *sBuffer = (char *)MemUtilsMalloc(*pnLen); - if ((int)fread(sBuffer, 1, *pnLen, pFile) != *pnLen) - { - // TO DO: Error "Error reading external font file" - } - fclose(pFile); - return sBuffer; - } - - char *GrFont::ReadEmbeddedFontFile(XRef *pXref, int *pnLen) - { - Object oFontFile; - oFontFile.InitRef(m_oEmbFontFileRef.nNum, m_oEmbFontFileRef.nGen); - Object oStream; - oFontFile.Fetch(pXref, &oStream); - if (!oStream.IsStream()) - { - // TO DO: Error "Embedded font file is not a stream" - oStream.Free(); - oFontFile.Free(); - m_oEmbFontFileRef.nNum = -1; - return NULL; - } - Stream *pStream = oStream.GetStream(); - char *sBuffer = NULL; - int nSize = 0; - int nIndex = 0; - pStream->Reset(); - int nChar = 0; - while ((nChar = pStream->GetChar()) != EOF) - { - if (nIndex == nSize) - { - nSize += 4096; - sBuffer = (char *)MemUtilsRealloc(sBuffer, nSize); - } - sBuffer[nIndex++] = nChar; - } - *pnLen = nIndex; - pStream->Close(); - - oStream.Free(); - oFontFile.Free(); - - return sBuffer; - } - - //------------------------------------------------------------------------ - // Gr8BitFont - //------------------------------------------------------------------------ - - Gr8BitFont::Gr8BitFont(XRef *pXref, char *sTag, Ref oID, StringExt *seName, GrFontType eType, Dict *pFontDict, GlobalParams *pGlobalParams) : - GrFont(sTag, oID, seName, pGlobalParams) - { - m_eType = eType; - m_pCharToUnicode = NULL; - - if (m_seName) - { - StringExt *seName2 = m_seName->Copy(); - int nIndex = 0; - while (nIndex < seName2->GetLength()) - { - if (seName2->GetAt(nIndex) == ' ') - { - seName2->Delete(nIndex); - } - else - { - ++nIndex; - } - } - int nFirst = 0; - int nLast = sizeof(c_sStandardFontMap) / sizeof(StandardFontMapEntry); - - // Поиск методом деления отрезка пополам - while (nLast - nFirst > 1) - { - int nMiddle = (nFirst + nLast) / 2; - if (seName2->Compare(c_sStandardFontMap[nMiddle].sAlternativeName) >= 0) - { - nFirst = nMiddle; - } - else - { - nLast = nMiddle; - } - } - if (!seName2->Compare(c_sStandardFontMap[nFirst].sAlternativeName)) - { - m_seName = new StringExt(c_sStandardFontMap[nFirst].sProperName); - } - delete seName2; - } - - // Смотрим является ли наш фонт одним из 14 стандартных - BuiltinFont *pBuiltinFont = NULL; - if (m_seName) - { - for (int nIndex = 0; nIndex < BuiltinFontsCount; ++nIndex) - { - if (!m_seName->Compare(c_arrBuiltinFonts[nIndex].sName)) - { - pBuiltinFont = &c_arrBuiltinFonts[nIndex]; - break; - } - } - } - - // Выставляем стандартные значения для Ascent/Descent/BBox - if (pBuiltinFont) - { - m_dAscent = 0.001 * pBuiltinFont->nAscent; - m_dDescent = 0.001 * pBuiltinFont->nDescent; - m_arrFontBBox[0] = 0.001 * pBuiltinFont->arrBBox[0]; - m_arrFontBBox[1] = 0.001 * pBuiltinFont->arrBBox[1]; - m_arrFontBBox[2] = 0.001 * pBuiltinFont->arrBBox[2]; - m_arrFontBBox[3] = 0.001 * pBuiltinFont->arrBBox[3]; - } - else - { - m_dAscent = 0.95; - m_dDescent = -0.35; - m_arrFontBBox[0] = m_arrFontBBox[1] = m_arrFontBBox[2] = m_arrFontBBox[3] = 0; - } - - // Считываем данные из FontDescriptor - ReadFontDescriptor(pXref, pFontDict); - - // Для стандартных фонтов выставляем стандартные значения Ascent/Descent/BBox - if (pBuiltinFont && m_oEmbFontFileRef.nNum < 0) - { - m_dAscent = 0.001 * pBuiltinFont->nAscent; - m_dDescent = 0.001 * pBuiltinFont->nDescent; - m_arrFontBBox[0] = 0.001 * pBuiltinFont->arrBBox[0]; - m_arrFontBBox[1] = 0.001 * pBuiltinFont->arrBBox[1]; - m_arrFontBBox[2] = 0.001 * pBuiltinFont->arrBBox[2]; - m_arrFontBBox[3] = 0.001 * pBuiltinFont->arrBBox[3]; - } - - // Ищем внешний FontFile - FindExternalFontFile(pBuiltinFont ? true : false); - - // FontMatrix - m_arrFontMatrix[0] = m_arrFontMatrix[3] = 1; - m_arrFontMatrix[1] = m_arrFontMatrix[2] = m_arrFontMatrix[4] = m_arrFontMatrix[5] = 0; - - Object oDictItem; - if (pFontDict->Search("FontMatrix", &oDictItem)->IsArray()) - { - for (int nIndex = 0; nIndex < 6 && nIndex < oDictItem.ArrayGetLength(); ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - m_arrFontMatrix[nIndex] = oTemp.GetNum(); - } - oTemp.Free(); - } - } - oDictItem.Free(); - - // Считываем данные, характерные для шрифта Type 3 - if (m_eType == fontType3) - { - if (pFontDict->Search("FontBBox", &oDictItem)->IsArray()) - { - for (int nIndex = 0; nIndex < 4 && nIndex < oDictItem.ArrayGetLength(); ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - m_arrFontBBox[nIndex] = oTemp.GetNum(); - } - oTemp.Free(); - } - } - oDictItem.Free(); - - if (!pFontDict->Search("CharProcs", &m_oCharProcs)->IsDict()) - { - // TO DO: Error "Missing or invalid CharProcs dictionary in Type 3 font" - m_oCharProcs.Free(); - } - - if (!pFontDict->Search("Resources", &m_oResources)->IsDict()) - { - m_oResources.Free(); - } - } - - //----- Строим Encoding ----- - - // Encodings начинается с BaseEncoding, которую мы можем найти в - // (в порядке приоритета): - // 1. pFontDict.Encoding or pFontDict.Encoding.BaseEncoding - // - MacRoman / MacExpert / WinAnsi / Standard - // 2. Во внедренном или внешнем FontFile - // 3. Стандартные значения(если до этого не нашли): - // - Builtin --> Builtin encoding - // - TrueType --> WinAnsiEncoding - // - Остальные --> StandardEncoding - - // Ищем BaseEncoding в pFontDict - m_bHasEncoding = false; - m_bUsesMacRomanEncoding = false; - char **ppBaseEncoding = NULL; - bool bBaseEncodingFromFontFile = false; - - pFontDict->Search("Encoding", &oDictItem); - if (oDictItem.IsDict()) - { - Object oTemp; - oDictItem.DictLookup("BaseEncoding", &oTemp); - if (oTemp.IsName("MacRomanEncoding")) - { - m_bHasEncoding = true; - m_bUsesMacRomanEncoding = true; - ppBaseEncoding = c_arrMacRomanEncoding; - } - else if (oTemp.IsName("MacExpertEncoding")) - { - m_bHasEncoding = true; - ppBaseEncoding = c_arrMacExpertEncoding; - } - else if (oTemp.IsName("WinAnsiEncoding")) - { - m_bHasEncoding = true; - ppBaseEncoding = c_arrWinAnsiEncoding; - } - oTemp.Free(); - } - else if (oDictItem.IsName("MacRomanEncoding")) - { - m_bHasEncoding = true; - m_bUsesMacRomanEncoding = true; - ppBaseEncoding = c_arrMacRomanEncoding; - } - else if (oDictItem.IsName("MacExpertEncoding")) - { - m_bHasEncoding = true; - ppBaseEncoding = c_arrMacExpertEncoding; - } - else if (oDictItem.IsName("WinAnsiEncoding")) - { - m_bHasEncoding = true; - ppBaseEncoding = c_arrWinAnsiEncoding; - } - - // Ищем BaseEncoding в FontFile(только для Type1) - CFontFileType1 *pFFT1 = NULL; - CFontFileType1C *pFFT1C = NULL; - char *sBuffer = NULL; - int nLen = 0; - - if (m_eType == fontType1 && (L"" != m_wsExternalFontFilePath || m_oEmbFontFileRef.nNum >= 0)) - { - if (L"" != m_wsExternalFontFilePath) - { - pFFT1 = CFontFileType1::LoadFromFile((wchar_t*)m_wsExternalFontFilePath.c_str()); - } - else - { - sBuffer = ReadEmbeddedFontFile(pXref, &nLen); - pFFT1 = CFontFileType1::LoadFromBuffer(sBuffer, nLen); - } - if (pFFT1) - { - if (pFFT1->GetName()) - { - if (m_seEmbeddedFontName) - { - delete m_seEmbeddedFontName; - } - m_seEmbeddedFontName = new StringExt(pFFT1->GetName()); - } - if (!ppBaseEncoding) - { - ppBaseEncoding = pFFT1->GetEncoding(); - bBaseEncodingFromFontFile = true; - } - } - } - else if (m_eType == fontType1C && (L"" != m_wsExternalFontFilePath || m_oEmbFontFileRef.nNum >= 0)) - { - if (L"" != m_wsExternalFontFilePath) - { - pFFT1C = CFontFileType1C::LoadFromFile((wchar_t*)m_wsExternalFontFilePath.c_str()); - } - else - { - sBuffer = ReadEmbeddedFontFile(pXref, &nLen); - pFFT1C = CFontFileType1C::LoadFromBuffer(sBuffer, nLen); - } - if (pFFT1C) - { - if (pFFT1C->GetName()) - { - if (m_seEmbeddedFontName) - { - delete m_seEmbeddedFontName; - } - m_seEmbeddedFontName = new StringExt(pFFT1C->GetName()); - } - if (!ppBaseEncoding) - { - ppBaseEncoding = pFFT1C->GetEncoding(); - bBaseEncodingFromFontFile = true; - } - } - } - if (sBuffer) - { - MemUtilsFree(sBuffer); - } - - // Стандартные значения BaseEncoding - if (!ppBaseEncoding) - { - if (pBuiltinFont && m_oEmbFontFileRef.nNum < 0) - { - ppBaseEncoding = pBuiltinFont->ppDefaultBaseEncoding; - m_bHasEncoding = true; - } - else if (m_eType == fontTrueTypeLN) - { - ppBaseEncoding = c_arrWinAnsiEncoding; - } - else - { - ppBaseEncoding = c_arrStandardEncoding; - } - } - - // copy the base encoding - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - m_ppEncoding[nIndex] = ppBaseEncoding[nIndex]; - if ((m_arrEncFree[nIndex] = bBaseEncodingFromFontFile) && m_ppEncoding[nIndex]) - { - m_ppEncoding[nIndex] = CopyString(ppBaseEncoding[nIndex]); - } - } - - // Некоторые Type 1C Font Files имею пустые кодировки, что может навредить конвертации T1C->T1, - // поэтому мы заполняем все пустые места из StandardEncoding - if (m_eType == fontType1C && (L"" != m_wsExternalFontFilePath || m_oEmbFontFileRef.nNum >= 0) && bBaseEncodingFromFontFile) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (!m_ppEncoding[nIndex] && c_arrStandardEncoding[nIndex]) - { - m_ppEncoding[nIndex] = c_arrStandardEncoding[nIndex]; - m_arrEncFree[nIndex] = false; - } - } - } - - // Differences - if (oDictItem.IsDict()) - { - Object oDifferences; - oDictItem.DictLookup("Differences", &oDifferences); - if (oDifferences.IsArray()) - { - m_bHasEncoding = true; - int nCode = 0; - for (int nIndex = 0; nIndex < oDifferences.ArrayGetLength(); ++nIndex) - { - Object oTemp; - oDifferences.ArrayGet(nIndex, &oTemp); - if (oTemp.IsInt()) - { - nCode = oTemp.GetInt(); - } - else if (oTemp.IsName()) - { - if (nCode >= 0 && nCode < 256) - { - if (m_arrEncFree[nCode]) - { - MemUtilsFree(m_ppEncoding[nCode]); - } - m_ppEncoding[nCode] = CopyString(oTemp.GetName()); - m_arrEncFree[nCode] = true; - } - ++nCode; - } - else - { - // TO DO: Error "Wrong type in font encoding resource differences" - } - oTemp.Free(); - } - } - oDifferences.Free(); - } - oDictItem.Free(); - - if (pFFT1) - { - delete pFFT1; - } - if (pFFT1C) - { - delete pFFT1C; - } - - //----- build the mapping to Unicode ----- - - // Шаг 1: Используем соответствие Name-to-Unicode - bool bMissing = false, bHex = false; - char *sCharName; - Unicode arrToUnicode[256]; - for (int nCode = 0; nCode < 256; ++nCode) - { - if ((sCharName = m_ppEncoding[nCode])) - { - if (m_pGlobalParams && !(arrToUnicode[nCode] = m_pGlobalParams->MapNameToUnicode(sCharName)) && strcmp(sCharName, ".notdef")) - { - // Если данного символа не было в таблице Name-to-Unicode table, проверяем - // как выглядит Name. ( либо 'Axx', либо 'xx', где 'A' - произвольная буква - // и 'xx' - два шестнадцатиричных числа - if ((strlen(sCharName) == 3 && isalpha(sCharName[0]) && - isxdigit(sCharName[1]) && isxdigit(sCharName[2]) && - ((sCharName[1] >= 'a' && sCharName[1] <= 'f') || - (sCharName[1] >= 'A' && sCharName[1] <= 'F') || - (sCharName[2] >= 'a' && sCharName[2] <= 'f') || - (sCharName[2] >= 'A' && sCharName[2] <= 'F')) - ) || - (strlen(sCharName) == 2 && - isxdigit(sCharName[0]) && isxdigit(sCharName[1]) && - ((sCharName[0] >= 'a' && sCharName[0] <= 'f') || - (sCharName[0] >= 'A' && sCharName[0] <= 'F') || - (sCharName[1] >= 'a' && sCharName[1] <= 'f') || - (sCharName[1] >= 'A' && sCharName[1] <= 'F')) - )) - { - bHex = true; - } - bMissing = true; - } - } - else - { - arrToUnicode[nCode] = 0; - } - } - - // Шаг 2: Заполняем пропущенные символы, ищем имена одного из видов - // 'Axx', 'xx', 'Ann', 'ABnn' или 'nn', где 'A' и 'B' - любые буквы, - // 'xx' - два шестнадцатиричных числа, и 'nn' - 2-4 десятичных числа - if (bMissing && m_pGlobalParams && m_pGlobalParams->GetMapNumericCharNames()) - { - for (int nCode = 0; nCode < 256; ++nCode) - { - if ((sCharName = m_ppEncoding[nCode]) && !arrToUnicode[nCode] && strcmp(sCharName, ".notdef")) - { - int nCount = strlen(sCharName); - int nCode2 = -1; - if (bHex && nCount == 3 && isalpha(sCharName[0]) && isxdigit(sCharName[1]) && isxdigit(sCharName[2])) - { - sscanf(sCharName + 1, "%x", &nCode2); - } - else if (bHex && nCount == 2 && isxdigit(sCharName[0]) && isxdigit(sCharName[1])) - { - sscanf(sCharName, "%x", &nCode2); - } - else if (!bHex && nCount >= 2 && nCount <= 4 && isdigit(sCharName[0]) && isdigit(sCharName[1])) - { - nCode2 = atoi(sCharName); - } - else if (nCount >= 3 && nCount <= 5 && isdigit(sCharName[1]) && isdigit(sCharName[2])) - { - nCode2 = atoi(sCharName + 1); - } - else if (nCount >= 4 && nCount <= 6 && isdigit(sCharName[2]) && isdigit(sCharName[3])) - { - nCode2 = atoi(sCharName + 2); - } - if (nCode2 >= 0 && nCode2 <= 0xff) - { - arrToUnicode[nCode] = (Unicode)nCode2; - } - } - } - } - else if (bMissing && m_pGlobalParams && m_pGlobalParams->GetMapUnknownCharNames()) // Если установлен флаг 'mapUnknownCharNames' - { - for (int nCode = 0; nCode < 256; ++nCode) - { - if (!arrToUnicode[nCode]) - { - arrToUnicode[nCode] = nCode; - } - } - } - - m_pCharToUnicode = CharCodeToUnicode::Make8BitToUnicode(arrToUnicode); - - // ToUnicode CMap - ReadToUnicodeCMap(pFontDict, 8, m_pCharToUnicode); - - // Ищем Unicode-to-Unicode - CharCodeToUnicode *pUnicodeToUnicode, *pCharToUnicode; - if (m_seName && m_pGlobalParams && (pUnicodeToUnicode = m_pGlobalParams->GetUnicodeToUnicode(m_seName))) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - arrToUnicode[nIndex] = 0; - } - pCharToUnicode = CharCodeToUnicode::Make8BitToUnicode(arrToUnicode); - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - Unicode arrUnicodeBuf[8]; - int nCount = m_pCharToUnicode->MapToUnicode((CharCode)nIndex, arrUnicodeBuf, 8); - if (nCount >= 1) - { - nCount = pUnicodeToUnicode->MapToUnicode((CharCode)arrUnicodeBuf[0], arrUnicodeBuf, 8); - if (nCount >= 1) - { - pCharToUnicode->SetMapping((CharCode)nIndex, arrUnicodeBuf, nCount); - } - } - } - pUnicodeToUnicode->Release(); - if (m_pCharToUnicode) - delete m_pCharToUnicode; - m_pCharToUnicode = pCharToUnicode; - } - - // Widths - - for (int nCode = 0; nCode < 256; ++nCode) - { - m_arrWidths[nCode] = m_dMissingWidth * 0.001; - } - - // Используем шириные из pFontDict, если они там заданы - pFontDict->Search("FirstChar", &oDictItem); - int nFirstChar = oDictItem.IsInt() ? oDictItem.GetInt() : 0; - oDictItem.Free(); - - if (nFirstChar < 0 || nFirstChar > 255) - { - nFirstChar = 0; - } - pFontDict->Search("LastChar", &oDictItem); - int nLastChar = oDictItem.IsInt() ? oDictItem.GetInt() : 255; - oDictItem.Free(); - - if (nLastChar < 0 || nLastChar > 255) - { - nLastChar = 255; - } - double dMult = (m_eType == fontType3) ? m_arrFontMatrix[0] : 0.001; - - pFontDict->Search("Widths", &oDictItem); - if (oDictItem.IsArray()) - { - m_nFlags |= fontFixedWidth; - if (oDictItem.ArrayGetLength() < nLastChar - nFirstChar + 1) - { - nLastChar = nFirstChar + oDictItem.ArrayGetLength() - 1; - } - for (int nCode = nFirstChar; nCode <= nLastChar; ++nCode) - { - Object oTemp; - oDictItem.ArrayGet(nCode - nFirstChar, &oTemp); - if (oTemp.IsNum()) - { - m_arrWidths[nCode] = oTemp.GetNum() * dMult; - if (m_arrWidths[nCode] != m_arrWidths[nFirstChar]) - { - m_nFlags &= ~fontFixedWidth; - } - } - oTemp.Free(); - } - } - else if (pBuiltinFont) // Используем ширины из Built-in шрифта - { - // Некорректные PDF-файлы кодируют символ с номером 32 как .notdef(хотя это пробел) - unsigned short unWidth = 0; - if (BuiltinFontGetWidth(pBuiltinFont, "space", &unWidth)) - { - m_arrWidths[32] = 0.001 * unWidth; - } - for (int nCode = 0; nCode < 256; ++nCode) - { - if (m_ppEncoding[nCode] && BuiltinFontGetWidth(pBuiltinFont, m_ppEncoding[nCode], &unWidth)) - { - m_arrWidths[nCode] = 0.001 * unWidth; - } - } - } - else // Ширины не заданы - заполняем стандартными значениями - { - int nIndex = 0; - if (IsFixedWidth()) - { - nIndex = 0; - } - else if (IsSerif()) - { - nIndex = 8; - } - else - { - nIndex = 4; - } - if (IsBold()) - { - nIndex += 2; - } - if (IsItalic()) - { - nIndex += 1; - } - pBuiltinFont = c_arrBuiltinFontSubset[nIndex]; - - // Некорректные PDF-файлы кодируют символ с номером 32 как .notdef(хотя это пробел) - unsigned short unWidth = 0; - if (BuiltinFontGetWidth(pBuiltinFont, "space", &unWidth)) - { - m_arrWidths[32] = 0.001 * unWidth; - } - for (int nCode = 0; nCode < 256; ++nCode) - { - if (m_ppEncoding[nCode] && BuiltinFontGetWidth(pBuiltinFont, m_ppEncoding[nCode], &unWidth)) - { - m_arrWidths[nCode] = 0.001 * unWidth; - } - } - } - oDictItem.Free(); - - m_bValid = true; - } - - Gr8BitFont::~Gr8BitFont() - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (m_arrEncFree[nIndex] && m_ppEncoding[nIndex]) - { - MemUtilsFree(m_ppEncoding[nIndex]); - } - } - m_pCharToUnicode->Release(); - if (m_oCharProcs.IsDict()) - { - m_oCharProcs.Free(); - } - if (m_oResources.IsDict()) - { - m_oResources.Free(); - } - } - - int Gr8BitFont::GetNextChar(char *sText, int nLen, CharCode *punCode, Unicode *punUnicode, int uSize, int *uLen, double *pdDx, double *pdDy, double *pdVx, double *pdVy) - { - CharCode nCharCode; - - *punCode = nCharCode = (CharCode)(*sText & 0xff); - *uLen = m_pCharToUnicode->MapToUnicode(nCharCode, punUnicode, uSize); - *pdDx = m_arrWidths[nCharCode]; - *pdDy = *pdVx = *pdVy = 0; - return 1; - } - - CharCodeToUnicode *Gr8BitFont::GetToUnicode() - { - m_pCharToUnicode->AddRef(); - return m_pCharToUnicode; - } - - unsigned short *Gr8BitFont::GetCodeToGIDMap(CFontFileTrueType *pTTF) - { - unsigned short *pMap = (unsigned short *)MemUtilsMallocArray(256, sizeof(unsigned short)); - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - pMap[nIndex] = 0; - } - - // 1. Если в PDF задана кодировка: - // 1a. Если в PDF шрифте определна кодировка MacRomanEncoding и - // TrueType-шрифт имеет Macintosh Roman CMap, используем его, - // и получем обатно по именам коды символов. - // 1b. Если TrueType-шрифт имеет Microsoft Unicode CMap или - // non-Microsoft Unicode CMap, используем его, и используем - // юникодные номера, а не коды символов. - // 1c. Если PDF-шрифт - Symbolic и TrueType-шрифт имеет - // Microsoft Symbol CMap, используем его, и используем сами - // коды символов (возможно со сдвигом 0xf000). - // 1d. Если TrueType-шрифт имеет Macintosh Roman CMap, используем - // его как и в случае 1a. - // 2. Если PDF-шрифт не имеет кодировки или PDF-шрифт - Symbolic: - // 2a. Если TrueType-шрифт имеет Macintosh Roman CMap, используем - // его, и используем сами коды символов (возможно со сдвигом - // 0xf000). - // 2b. Если TrueType-шрифт имеет Microsoft Symbol CMap, используем - // его, и используем сами коды символов (возможно со сдвигом - // 0xf000). - // 3. Если не один из этих случаев не применим, тогда используем первый - // CMap. (но такого не должно происходить) - - - // TO DO: Возможна ситуация, когда одинаковых кодировок несколько, и в они содерржат - // разные символы. В таких случаях надо бы делать общую кодировку, а не считывать - // одну конкретную. - - int nUnicodeCmap = -1, nMacRomanCmap = -1, nMSSymbolCmap = -1; - int nCmapPlatform = 0, nCmapEncoding = 0; - for (int nIndex = 0; nIndex < pTTF->GetCmapsCount(); ++nIndex) - { - nCmapPlatform = pTTF->GetCmapPlatform(nIndex); - nCmapEncoding = pTTF->GetCmapEncoding(nIndex); - - if ((nCmapPlatform == 3 && nCmapEncoding == 1) || nCmapPlatform == 0) - { - nUnicodeCmap = nIndex; - } - else if (nCmapPlatform == 1 && nCmapEncoding == 0) - { - nMacRomanCmap = nIndex; - } - else if (nCmapPlatform == 3 && nCmapEncoding == 0) - { - nMSSymbolCmap = nIndex; - } - } - int nCmap = 0; - bool bUseMacRoman = false; - bool bUseUnicode = false; - if (m_bHasEncoding) - { - if (m_bUsesMacRomanEncoding && nMacRomanCmap >= 0) - { - nCmap = nMacRomanCmap; - bUseMacRoman = true; - } - else if (nUnicodeCmap >= 0) - { - nCmap = nUnicodeCmap; - bUseUnicode = true; - } - else if ((m_nFlags & fontSymbolic) && nMSSymbolCmap >= 0) - { - nCmap = nMSSymbolCmap; - } - else if ((m_nFlags & fontSymbolic) && nMacRomanCmap >= 0) - { - nCmap = nMacRomanCmap; - } - else if (nMacRomanCmap >= 0) - { - nCmap = nMacRomanCmap; - bUseMacRoman = true; - } - } - else - { - if (nMSSymbolCmap >= 0) - { - nCmap = nMSSymbolCmap; - } - else if (nMacRomanCmap >= 0) - { - nCmap = nMacRomanCmap; - } - } - - char *sCharName; - int nCode = 0; - - if (bUseMacRoman) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if ((sCharName = m_ppEncoding[nIndex])) - { - if (m_pGlobalParams && (nCode = m_pGlobalParams->GetMacRomanCharCode(sCharName))) - { - pMap[nIndex] = pTTF->MapCodeToGID(nCmap, nCode); - } - } - } - } - else if (bUseUnicode) - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - int nLen = 0; - Unicode nUnicode = 0; - if (((sCharName = m_ppEncoding[nIndex]) && (m_pGlobalParams) && (nUnicode = m_pGlobalParams->MapNameToUnicode(sCharName))) || (nLen = m_pCharToUnicode->MapToUnicode((CharCode)nIndex, &nUnicode, 1))) - { - pMap[nIndex] = pTTF->MapCodeToGID(nCmap, nUnicode); - } - } - } - else - { - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (!(pMap[nIndex] = pTTF->MapCodeToGID(nCmap, nIndex))) - { - pMap[nIndex] = pTTF->MapCodeToGID(nCmap, 0xf000 + nIndex); - } - } - } - - for (int nIndex = 0; nIndex < 256; ++nIndex) - { - if (!pMap[nIndex] && (sCharName = m_ppEncoding[nIndex])) - { - pMap[nIndex] = (unsigned short)(int)pTTF->MapNameToGID(sCharName); - } - } - - return pMap; - } - - Dict *Gr8BitFont::GetCharProcs() - { - return m_oCharProcs.IsDict() ? m_oCharProcs.GetDict() : (Dict *)NULL; - } - - Object *Gr8BitFont::GetCharProc(int nCode, Object *pProc) - { - if (m_ppEncoding[nCode] && m_oCharProcs.IsDict()) - { - m_oCharProcs.DictLookup(m_ppEncoding[nCode], pProc); - } - else - { - pProc->InitNull(); - } - return pProc; - } - - Dict *Gr8BitFont::GetResources() - { - return m_oResources.IsDict() ? m_oResources.GetDict() : (Dict *)NULL; - } - - //------------------------------------------------------------------------ - // GrCIDFont - //------------------------------------------------------------------------ - - static int CompareWidthExceptions(const void *pWidth1, const void *pWidth2) - { - return ((GrFontCIDWidthException *)pWidth1)->nFirst - ((GrFontCIDWidthException *)pWidth2)->nFirst; - } - - static int CompareWidthExceptionsV(const void *pWidth1, const void *pWidth2) - { - return ((GrFontCIDWidthExceptionV *)pWidth1)->nFirst - ((GrFontCIDWidthExceptionV *)pWidth2)->nFirst; - } - - GrCIDFont::GrCIDFont(XRef *pXref, char *sTag, Ref oID, StringExt *seName, Dict *pFontDict, GlobalParams *pGlobalParams) : - GrFont(sTag, oID, seName, pGlobalParams) - { - m_dAscent = 0.95; - m_dDescent = -0.35; - m_arrFontBBox[0] = m_arrFontBBox[1] = m_arrFontBBox[2] = m_arrFontBBox[3] = 0; - m_pCMap = NULL; - m_pCharToUnicode = NULL; - m_oWidths.dDefaultWidth = 1.0; - m_oWidths.dDefaultHeight = -1.0; - m_oWidths.dDefaultV = 0.880; - m_oWidths.pExceptions = NULL; - m_oWidths.nExceptionsCount = 0; - m_oWidths.pExceptionsV = NULL; - m_oWidths.nExceptionsVCount = 0; - m_pCidToGID = NULL; - m_nCidToGIDLen = 0; - - // Descendant font - Object oDictItem; - if (!pFontDict->Search("DescendantFonts", &oDictItem)->IsArray()) - { - // TO DO: Error "Missing DescendantFonts entry in Type 0 font" - oDictItem.Free(); - return; - } - Object oDescendantObject; - if (!oDictItem.ArrayGet(0, &oDescendantObject)->IsDict()) - { - // TO DO: Error "Bad descendant font in Type 0 font" - oDescendantObject.Free(); - oDictItem.Free(); - return; - } - oDictItem.Free(); - - Dict *pDescendantDict = oDescendantObject.GetDict(); - - // Subtype - - if (!pDescendantDict->Search("Subtype", &oDictItem)) - { - // TO DO: Error "Missing Subtype entry in Type 0 descendant font" - oDescendantObject.Free(); - oDictItem.Free(); - return; - } - if (oDictItem.IsName("CIDFontType0")) - { - m_eType = fontCIDType0; - } - else if (oDictItem.IsName("CIDFontType2")) - { - m_eType = fontCIDType2; - } - else - { - // TO DO: Error "Unknown Type 0 descendant font type" - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - oDictItem.Free(); - - ReadFontDescriptor(pXref, pDescendantDict); - - // Ищем внешний FontFile - FindExternalFontFile(false); - - // Кодировка - - // Char collection - if (!pDescendantDict->Search("CIDSystemInfo", &oDictItem)->IsDict()) - { - // TO DO: Error "Missing CIDSystemInfo dictionary in Type 0 descendant font" - oDescendantObject.Free(); - oDictItem.Free(); - return; - } - Object oRegistry; - oDictItem.DictLookup("Registry", &oRegistry); - Object oOrdering; - oDictItem.DictLookup("Ordering", &oOrdering); - - if (!oRegistry.IsString() || !oOrdering.IsString()) - { - // TO DO: Error "Invalid CIDSystemInfo dictionary in Type 0 descendant font" - oRegistry.Free(); - oOrdering.Free(); - oDescendantObject.Free(); - oDictItem.Free(); - return; - } - - StringExt *seCollection = oRegistry.GetString()->Copy()->Append('-')->Append(oOrdering.GetString()); - oOrdering.Free(); - oRegistry.Free(); - oDictItem.Free(); - - // ToUnicode CMap - if (!(m_pCharToUnicode = ReadToUnicodeCMap(pFontDict, 16, NULL))) - { - - // "Adobe-Identity" и "Adobe-UCS" collections не имеют файлов СidToUnicode - if (seCollection->Compare("Adobe-Identity") && seCollection->Compare("Adobe-UCS")) - { - // Ищем файлы cidToUnicode, данные извне - if (m_pGlobalParams && !(m_pCharToUnicode = m_pGlobalParams->GetCIDToUnicode(seCollection))) - { - // TO DO: Error "Unknown character collection" - } - } - } - - // Ищем Unicode-to-Unicode - CharCodeToUnicode *pUnicodeToUnicode = NULL; - if (m_seName && m_pGlobalParams && (pUnicodeToUnicode = m_pGlobalParams->GetUnicodeToUnicode(m_seName))) - { - if (m_pCharToUnicode) - { - for (CharCode nCharCode = 0; nCharCode < m_pCharToUnicode->GetLength(); ++nCharCode) - { - Unicode arrUnicodeBuffer[8]; - int nCount = m_pCharToUnicode->MapToUnicode(nCharCode, arrUnicodeBuffer, 8); - if (nCount >= 1) - { - nCount = pUnicodeToUnicode->MapToUnicode((CharCode)arrUnicodeBuffer[0], arrUnicodeBuffer, 8); - if (nCount >= 1) - { - m_pCharToUnicode->SetMapping(nCharCode, arrUnicodeBuffer, nCount); - } - } - } - pUnicodeToUnicode->Release(); - } - else - { - m_pCharToUnicode = pUnicodeToUnicode; - } - } - - // Кодировка (т.е. CMap) - pFontDict->Search("Encoding", &oDictItem); - - if (oDictItem.IsName()) - { - StringExt *seCMapName = new StringExt(oDictItem.GetName()); - - if (m_pGlobalParams && !(m_pCMap = m_pGlobalParams->GetCMap(seCollection, seCMapName))) - { - // TO DO: Error "Unknown CMap for character collection" - if (seCollection) - delete seCollection; - if (seCMapName) - delete seCMapName; - - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - if (seCMapName) - delete seCMapName; - } - else if (oDictItem.IsStream()) - { - Stream *pStream = oDictItem.GetStream(); - Dict *pEncDict = pStream->GetDict(); - - Object oEncItem; - - pEncDict->Search("CMapName", &oEncItem); - if (!oEncItem.IsName()) - { - if (seCollection) - delete seCollection; - oEncItem.Free(); - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - - StringExt *seCMapName = new StringExt(oEncItem.GetName()); - oEncItem.Free(); - - std::wstring wsTempFile; - FILE *pFile = NULL; - if (!OpenTempFile(&wsTempFile, &pFile, L"wb", L".cmap", (wchar_t*)m_pGlobalParams->GetTempFolder().c_str())) - { - if (seCollection) - delete seCollection; - - if (seCMapName) - delete seCMapName; - - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - pStream->Reset(); - int nChar = 0; - while (EOF != (nChar = pStream->GetChar())) - { - ::fputc(nChar, pFile); - } - - fclose(pFile); - - if (!(m_pCMap = pGlobalParams->GetCMap(seCollection, seCMapName, (wchar_t*)wsTempFile.c_str()))) - { - NSFile::CFileBinary::Remove(wsTempFile.c_str()); - - if (seCollection) - delete seCollection; - - if (seCMapName) - delete seCMapName; - - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - - NSFile::CFileBinary::Remove(wsTempFile.c_str()); - - if (seCMapName) - delete seCMapName; - - } - else - { - // TO DO: Error "Missing or invalid Encoding entry in Type 0 font" - if (seCollection) - delete seCollection; - oDictItem.Free(); - oDescendantObject.Free(); - return; - } - oDictItem.Free(); - - if (seCollection) - delete seCollection; - - // CIDToGIDMap (для внедренных шрифтов-TrueType) - if (m_eType == fontCIDType2) - { - pDescendantDict->Search("CIDToGIDMap", &oDictItem); - if (oDictItem.IsStream()) - { - int nChar1 = 0, nChar2 = 0; - m_nCidToGIDLen = 0; - int nLen = 64; - m_pCidToGID = (unsigned short *)MemUtilsMallocArray(nLen, sizeof(unsigned short)); - oDictItem.StreamReset(); - while ((nChar1 = oDictItem.StreamGetChar()) != EOF && (nChar2 = oDictItem.StreamGetChar()) != EOF) - { - if (m_nCidToGIDLen == nLen) - { - nLen *= 2; - m_pCidToGID = (unsigned short *)MemUtilsReallocArray(m_pCidToGID, nLen, sizeof(unsigned short)); - } - m_pCidToGID[m_nCidToGIDLen++] = (unsigned short)((nChar1 << 8) + nChar2); - } - } - else if (!oDictItem.IsName("Identity") && !oDictItem.IsNull()) - { - // TO DO: Error "Invalid CIDToGIDMap entry in CID font" - } - oDictItem.Free(); - } - - // Метрики - - // Стандартное значение ширин - if (pDescendantDict->Search("DW", &oDictItem)->IsInt()) - { - m_oWidths.dDefaultWidth = oDictItem.GetInt() * 0.001; - } - oDictItem.Free(); - - // Исключения - if (pDescendantDict->Search("W", &oDictItem)->IsArray()) - { - int nExceptionsSize = 0; - int nCounter = 0; - while (nCounter + 1 < oDictItem.ArrayGetLength()) - { - Object oFirst, oSecond; - oDictItem.ArrayGet(nCounter, &oFirst); - oDictItem.ArrayGet(nCounter + 1, &oSecond); - if (oFirst.IsInt() && oSecond.IsInt() && nCounter + 2 < oDictItem.ArrayGetLength()) - { - // формат: C_first C_last W - Object oWidth; - if (oDictItem.ArrayGet(nCounter + 2, &oWidth)->IsNum()) - { - if (m_oWidths.nExceptionsCount == nExceptionsSize) - { - nExceptionsSize += 16; - m_oWidths.pExceptions = (GrFontCIDWidthException *)MemUtilsReallocArray(m_oWidths.pExceptions, nExceptionsSize, sizeof(GrFontCIDWidthException)); - } - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].nFirst = oFirst.GetInt(); - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].nLast = oSecond.GetInt(); - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].dWidth = oWidth.GetNum() * 0.001; - ++m_oWidths.nExceptionsCount; - } - else - { - // TO DO: Error "Bad widths array in Type 0 font" - } - oWidth.Free(); - nCounter += 3; - } - else if (oFirst.IsInt() && oSecond.IsArray()) - { - // Формат: c [ w1 w2 … wn ] - if (m_oWidths.nExceptionsCount + oSecond.ArrayGetLength() > nExceptionsSize) - { - nExceptionsSize = (m_oWidths.nExceptionsCount + oSecond.ArrayGetLength() + 15) & ~15; - m_oWidths.pExceptions = (GrFontCIDWidthException *)MemUtilsReallocArray(m_oWidths.pExceptions, nExceptionsSize, sizeof(GrFontCIDWidthException)); - } - int nCurFirst = oFirst.GetInt(); - for (int nArrayIndex = 0; nArrayIndex < oSecond.ArrayGetLength(); ++nArrayIndex) - { - Object oTemp; - if (oSecond.ArrayGet(nArrayIndex, &oTemp)->IsNum()) - { - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].nFirst = nCurFirst; - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].nLast = nCurFirst; - m_oWidths.pExceptions[m_oWidths.nExceptionsCount].dWidth = oTemp.GetNum() * 0.001; - ++nCurFirst; - ++m_oWidths.nExceptionsCount; - } - else - { - // TO DO: Error "Bad widths array in Type 0 font" - } - oTemp.Free(); - } - nCounter += 2; - } - else - { - // TO DO: Error "Bad widths array in Type 0 font"); - ++nCounter; - } - oSecond.Free(); - oFirst.Free(); - } - qsort(m_oWidths.pExceptions, m_oWidths.nExceptionsCount, sizeof(GrFontCIDWidthException), &CompareWidthExceptions); - } - oDictItem.Free(); - - // Стандартные метрики по вертикали - if (pDescendantDict->Search("DW2", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2) - { - Object oTemp; - if (oDictItem.ArrayGet(0, &oTemp)->IsNum()) - { - m_oWidths.dDefaultV = oTemp.GetNum() * 0.001; - } - oTemp.Free(); - - if (oDictItem.ArrayGet(1, &oTemp)->IsNum()) - { - m_oWidths.dDefaultHeight = oTemp.GetNum() * 0.001; - } - oTemp.Free(); - } - oDictItem.Free(); - - // Исключения - if (pDescendantDict->Search("W2", &oDictItem)->IsArray()) - { - int nExceptionsSize = 0; - int nCounter = 0; - while (nCounter + 1 < oDictItem.ArrayGetLength()) - { - Object oFirst, oSecond; - oDictItem.ArrayGet(nCounter, &oFirst); - oDictItem.ArrayGet(nCounter + 1, &oSecond); - if (oFirst.IsInt() && oSecond.IsInt() && nCounter + 4 < oDictItem.ArrayGetLength()) - { - // Формат: С_first С_last W11y V1x V1y - Object oHeight, oVx, oVy; - if (oDictItem.ArrayGet(nCounter + 2, &oHeight)->IsNum() && oDictItem.ArrayGet(nCounter + 3, &oVx)->IsNum() && oDictItem.ArrayGet(nCounter + 4, &oVy)->IsNum()) - { - if (m_oWidths.nExceptionsVCount == nExceptionsSize) - { - nExceptionsSize += 16; - m_oWidths.pExceptionsV = (GrFontCIDWidthExceptionV *)MemUtilsReallocArray(m_oWidths.pExceptionsV, nExceptionsSize, sizeof(GrFontCIDWidthExceptionV)); - } - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].nFirst = oFirst.GetInt(); - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].nLast = oSecond.GetInt(); - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dHeight = oHeight.GetNum() * 0.001; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dVx = oVx.GetNum() * 0.001; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dVy = oVy.GetNum() * 0.001; - ++m_oWidths.nExceptionsVCount; - } - else - { - // TO DO: Error "Bad widths (W2) array in Type 0 font" - } - oVy.Free(); - oVx.Free(); - oHeight.Free(); - nCounter += 5; - } - else if (oFirst.IsInt() && oSecond.IsArray()) - { - if (m_oWidths.nExceptionsVCount + oSecond.ArrayGetLength() / 3 > nExceptionsSize) - { - nExceptionsSize = (m_oWidths.nExceptionsVCount + oSecond.ArrayGetLength() / 3 + 15) & ~15; - m_oWidths.pExceptionsV = (GrFontCIDWidthExceptionV *)MemUtilsReallocArray(m_oWidths.pExceptionsV, nExceptionsSize, sizeof(GrFontCIDWidthExceptionV)); - } - int nCurFirst = oFirst.GetInt(); - for (int nArrayIndex = 0; nArrayIndex < oSecond.ArrayGetLength(); nArrayIndex += 3) - { - Object oHeight, oVx, oVy; - if (oSecond.ArrayGet(nArrayIndex, &oHeight)->IsNum() && oSecond.ArrayGet(nArrayIndex + 1, &oVx)->IsNum() && oSecond.ArrayGet(nArrayIndex + 2, &oVy)->IsNum()) - { - // TO DO: Здесь было исправлено!!! неправильные индексы передавались -> вместо nExceptionsVCount передавались nExceptionsCount - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].nFirst = nCurFirst; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].nLast = nCurFirst; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dHeight = oHeight.GetNum() * 0.001; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dVx = oVx.GetNum() * 0.001; - m_oWidths.pExceptionsV[m_oWidths.nExceptionsVCount].dVy = oVy.GetNum() * 0.001; - ++nCurFirst; - ++m_oWidths.nExceptionsVCount; - } - else - { - // TO DO: Error "Bad widths (W2) array in Type 0 font" - } - oVy.Free(); - oVx.Free(); - oHeight.Free(); - } - nCounter += 2; - } - else - { - // TO DO: Error "Bad widths (W2) array in Type 0 font" - ++nCounter; - } - oSecond.Free(); - oFirst.Free(); - } - qsort(m_oWidths.pExceptionsV, m_oWidths.nExceptionsVCount, sizeof(GrFontCIDWidthExceptionV), &CompareWidthExceptionsV); - } - oDictItem.Free(); - - oDescendantObject.Free(); - m_bValid = true; - return; - } - - GrCIDFont::~GrCIDFont() - { - if (m_pCMap) - { - m_pCMap->Release(); - } - if (m_pCharToUnicode) - { - m_pCharToUnicode->Release(); - } - - MemUtilsFree(m_oWidths.pExceptions); - MemUtilsFree(m_oWidths.pExceptionsV); - - if (m_pCidToGID) - { - MemUtilsFree(m_pCidToGID); - } - } - - int GrCIDFont::GetNextChar(char *sText, int nLen, CharCode *punCode, Unicode *punUnicode, int uSize, int *uLen, double *pdDx, double *pdDy, double *pdVx, double *pdVy) - { - CID nCID = 0; - int nCount = 0; - - if (!m_pCMap) - { - *punCode = 0; - *uLen = 0; - *pdDx = *pdDy = 0; - return 1; - } - - *punCode = (CharCode)(nCID = m_pCMap->GetCID(sText, nLen, &nCount)); - // Временно - - *uLen = nCount; - if (1 == nCount) - *punUnicode = sText[0]; - else if (2 == nCount) - { - *punUnicode = 0; - *punUnicode |= sText[0] & 0xFF; - *punUnicode <<= 8; - *punUnicode |= sText[1] & 0xFF; - } - else - { - *uLen = 0; - *punUnicode = 0; - } - - //if ( m_pCharToUnicode ) - //{ - // *uLen = m_pCharToUnicode->MapToUnicode( nCID, punUnicode, uSize); - //} - //else - //{ - // *uLen = 0; - //} - - double dWidth = 0, dHeight = 0, dVx = 0, dVy = 0; - // Horizontal - if (m_pCMap->GetWMode() == 0) - { - dWidth = m_oWidths.dDefaultWidth; - dHeight = dVx = dVy = 0; - if (m_oWidths.nExceptionsCount > 0 && nCID >= m_oWidths.pExceptions[0].nFirst) - { - int nFirst = 0; - int nLast = m_oWidths.nExceptionsCount; - - while (nLast - nFirst > 1) - { - int nMiddle = (nFirst + nLast) / 2; - if (m_oWidths.pExceptions[nMiddle].nFirst <= nCID) - { - nFirst = nMiddle; - } - else - { - nLast = nMiddle; - } - } - if (nCID <= m_oWidths.pExceptions[nFirst].nLast) - { - dWidth = m_oWidths.pExceptions[nFirst].dWidth; - } - } - } - else // Vertical - { - dWidth = 0; - dHeight = m_oWidths.dDefaultHeight; - dVx = m_oWidths.dDefaultWidth / 2; - dVy = m_oWidths.dDefaultV; - if (m_oWidths.nExceptionsVCount > 0 && nCID >= m_oWidths.pExceptionsV[0].nFirst) - { - int nFirst = 0; - int nLast = m_oWidths.nExceptionsVCount; - - while (nLast - nFirst > 1) - { - int nMiddle = (nFirst + nLast) / 2; - if (m_oWidths.pExceptionsV[nMiddle].nLast <= nCID) - { - nFirst = nMiddle; - } - else - { - nLast = nMiddle; - } - } - if (nCID <= m_oWidths.pExceptionsV[nFirst].nLast) - { - dHeight = m_oWidths.pExceptionsV[nFirst].dHeight; - dVx = m_oWidths.pExceptionsV[nFirst].dVx; - dVy = m_oWidths.pExceptionsV[nFirst].dVy; - } - } - } - - *pdDx = dWidth; - *pdDy = dHeight; - *pdVx = dVx; - *pdVy = dVy; - - return nCount; - } - - int GrCIDFont::GetWMode() - { - return m_pCMap ? m_pCMap->GetWMode() : 0; - } - - CharCodeToUnicode *GrCIDFont::GetToUnicode() - { - if (m_pCharToUnicode) - { - m_pCharToUnicode->AddRef(); - } - return m_pCharToUnicode; - } - - StringExt *GrCIDFont::GetCollection() - { - return m_pCMap ? m_pCMap->GetCollection() : (StringExt *)NULL; - } - - //------------------------------------------------------------------------ - // GrFontDict - //------------------------------------------------------------------------ - - GrFontDict::GrFontDict(XRef *pXref, Ref *pFontDictRef, Dict *pFontDict, GlobalParams *pGlobalParams) - { - m_pGlobalParams = pGlobalParams; - - Ref oRef; - - m_nFontsCount = pFontDict->GetEntryCount(); - m_ppFonts = (GrFont **)MemUtilsMallocArray(m_nFontsCount, sizeof(GrFont *)); - for (int nIndex = 0; nIndex < m_nFontsCount; ++nIndex) - { - Object oFontRef, oFont; - pFontDict->GetValueCopy(nIndex, &oFontRef); - oFontRef.Fetch(pXref, &oFont); - if (oFont.IsDict()) - { - if (oFontRef.IsRef()) - { - oRef = oFontRef.GetRef(); - } - else - { - oRef.nNum = nIndex; - if (pXref) - { - oRef.nGen = pXref->GenerateUniqueRefGen(); - } - else - { - oRef.nGen = 999999; - } - } - m_ppFonts[nIndex] = GrFont::MakeFont(pXref, pFontDict->GetKey(nIndex), oRef, oFont.GetDict(), pGlobalParams); - if (m_ppFonts[nIndex] && !m_ppFonts[nIndex]->CheckValidate()) - { - if (m_ppFonts[nIndex]) - delete m_ppFonts[nIndex]; - m_ppFonts[nIndex] = NULL; - } - } - else - { - // TO DO: Error "font resource is not a dictionary" - m_ppFonts[nIndex] = NULL; - } - oFontRef.Free(); - oFont.Free(); - } - } - - GrFontDict::~GrFontDict() - { - for (int nIndex = 0; nIndex < m_nFontsCount; ++nIndex) - { - if (m_ppFonts[nIndex]) - { - delete m_ppFonts[nIndex]; - } - } - MemUtilsFree(m_ppFonts); - } - - GrFont *GrFontDict::Search(char *sTag) - { - for (int nIndex = 0; nIndex < m_nFontsCount; ++nIndex) - { - if (m_ppFonts[nIndex] && m_ppFonts[nIndex]->CheckTag(sTag)) - { - return m_ppFonts[nIndex]; - } - } - return NULL; - } -} diff --git a/PdfReader/old/GFont.h b/PdfReader/old/GFont.h deleted file mode 100644 index bf8e7f1b86..0000000000 --- a/PdfReader/old/GFont.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDFREADER_GFONT_H -#define _PDFREADER_GFONT_H - -#include "StringExt.h" -#include "Object.h" -#include "CharTypes.h" -#include "GlobalParams.h" - -namespace PdfReader -{ - class Dict; - class CMap; - class CharCodeToUnicode; - class CFontFileTrueType; - struct GrFontCIDWidths; - - //------------------------------------------------------------------------ - // GrFontType - //------------------------------------------------------------------------ - - enum GrFontType - { - //----- Gr8BitFont - fontUnknownType, - fontType1, - fontType1C, - fontType1COT, - fontType3, - fontTrueTypeLN, - fontTrueTypeLNOT, - //----- GrCIDFont - fontCIDType0, - fontCIDType0C, - fontCIDType0COT, - fontCIDType2, - fontCIDType2OT - }; - - //------------------------------------------------------------------------ - // GrFontCIDWidths - //------------------------------------------------------------------------ - - struct GrFontCIDWidthException - { - CID nFirst; // Данная запись применяется к - CID nLast; // CID: ... - double dWidth; // Новая ширина символов - }; - - struct GrFontCIDWidthExceptionV - { - CID nFirst; // Данная запись применяется к - CID nLast; // CID: ... - double dHeight; // Новая высота символов - double dVx; // Координаты вектора V: origin0->origin1 - double dVy; // См. фигуру 40 в спецификации PDF 1.7 - }; - - struct GrFontCIDWidths - { - double dDefaultWidth; // Стандартное значение ширины символа - double dDefaultHeight; // Стандартное значение высоты символа - double dDefaultV; // Стандартное значение вектора V - GrFontCIDWidthException *pExceptions; // Исключения для горизонтальных метрик - int nExceptionsCount; // Число исключений - GrFontCIDWidthExceptionV*pExceptionsV; // Исключения для вертикальных метрик - int nExceptionsVCount; // Число исключений - }; - - //------------------------------------------------------------------------ - // GrFont - //------------------------------------------------------------------------ - -#define fontFixedWidth (1 << 0) -#define fontSerif (1 << 1) -#define fontSymbolic (1 << 2) -#define fontItalic (1 << 6) -#define fontBold (1 << 18) - - class GrFont - { - public: - - static GrFont *MakeFont(XRef *pXref, char *sTag, Ref oID, Dict *pFontDict, GlobalParams *pGlobalParams); - - GrFont(char *sTag, Ref oID, StringExt *seName, GlobalParams *pGlobalParams); - - virtual ~GrFont(); - - bool CheckValidate() - { - return m_bValid; - } - - StringExt *GetTag() - { - return m_seTag; - } - - Ref *GetID() - { - return &m_oID; - } - - bool CheckTag(char *sTag) - { - return !m_seTag->Compare(sTag); - } - - StringExt *GetBaseName() - { - return m_seName; - } - - StringExt *GetOriginalName() - { - return m_seOriginalName; - } - - GrFontType GetType() - { - return m_eType; - } - virtual bool IsCIDFont() - { - return false; - } - - // Внедренные фонты. - bool GetEmbeddedFontFileRef(Ref *pEmbRef) - { - *pEmbRef = m_oEmbFontFileRef; - return m_oEmbFontFileRef.nNum >= 0; - } - - StringExt *GetEmbeddedFontName() - { - return m_seEmbeddedFontName; - } - - std::wstring GetExternalFontFilePath() - { - return m_wsExternalFontFilePath; - } - - // - int GetFlags() - { - return m_nFlags; - } - bool IsFixedWidth() - { - return (m_nFlags & fontFixedWidth ? true : false); - } - bool IsSerif() - { - return (m_nFlags & fontSerif ? true : false); - } - bool IsSymbolic() - { - return (m_nFlags & fontSymbolic ? true : false); - } - bool IsItalic() - { - return (m_nFlags & fontItalic ? true : false); - } - bool IsBold() - { - return (m_nFlags & fontBold ? true : false); - } - - double *GetFontMatrix() - { - return m_arrFontMatrix; - } - - double *GetFontBBox() - { - return m_arrFontBBox; - } - - double GetAscent() - { - return m_dAscent; - } - double GetDescent() - { - return m_dDescent; - } - - // 0 = пишем по горизонтали, 1 = по вертикали - virtual int GetWMode() - { - return 0; - } - - // Считываем внешний или включенный FontFile в буфер. - char *ReadExternalFontFile(int *pnLength); - char *ReadEmbeddedFontFile(XRef *pXref, int *pnLegth); - - // Считываем следующий символ из строки длины байт, возвращем - // код символа , его юникодное значение , вектор замещения - // (w0 или w1, см. спецификацию PDF 1.7 фигура 40) (, ), и вектор V - // (см. фигуру 40) (, ). Возвращаем количество байт необходимых для punCode. - virtual int GetNextChar(char *sText, int nLen, CharCode *punCode, Unicode *punUnicode, int uSize, int *uLen, double *pdDx, double *pdDy, double *pdVx, double *pdVy) = 0; - - protected: - - void ReadFontDescriptor(XRef *pXref, Dict *pFontDict); - CharCodeToUnicode *ReadToUnicodeCMap(Dict *pFontDict, int nBitsCount, CharCodeToUnicode *pCharToUnicode); - void FindExternalFontFile(bool bBuiltin = false); - - protected: - - StringExt* m_seTag; // Тэг pdf-шрифта - Ref m_oID; // Ссылка на объект-шрифт (используем в качестве уникального идентефикатора) - StringExt* m_seName; // Название шрифта - StringExt* m_seOriginalName; // Первоначальное название шрифта - GrFontType m_eType; // Тип шрифта - int m_nFlags; // Флаги в FontDescriptor - StringExt* m_seEmbeddedFontName; // Название включенного в PDF шрифта(т.е. шрифт идет вместе с FontFile) - Ref m_oEmbFontFileRef; // Ссылка(pdf-ссылка) на FontFile для включенного шрифта - std::wstring m_wsExternalFontFilePath; // Путь в FontFile(т.е. font file не в самом PDF) - - double m_arrFontMatrix[6]; // Матрица преобразования координат символа в координаты текста (только для Type 3) - double m_arrFontBBox[4]; // Наименьший прямоугольник задающий границы всех символов (только для Type 3) - double m_dMissingWidth; // Стандартное значение ширины для пропущенных символов - double m_dAscent; // Ascent - double m_dDescent; // Descent - - bool m_bValid; - - GlobalParams* m_pGlobalParams; - }; - - //------------------------------------------------------------------------ - // Gr8BitFont - //------------------------------------------------------------------------ - - class Gr8BitFont : public GrFont - { - public: - - Gr8BitFont(XRef *pXref, char *sTag, Ref oID, StringExt *seName, GrFontType eType, Dict *pFontDict, GlobalParams *pGlobalParams); - - virtual ~Gr8BitFont(); - - virtual int GetNextChar(char *sText, int nLen, CharCode *punCode, Unicode *punUnicode, int uSize, int *uLen, double *pdDx, double *pdDy, double *pdVx, double *pdVy); - - char **GetEncoding() - { - return m_ppEncoding; - } - - CharCodeToUnicode *GetToUnicode(); - - char *GetCharName(int nCode) - { - return m_ppEncoding[nCode]; - } - - bool GetHasEncoding() - { - return m_bHasEncoding; - } - - bool GetUsesMacRomanEncoding() - { - return m_bUsesMacRomanEncoding; - } - - double GetWidth(unsigned char unChar) - { - return m_arrWidths[unChar]; - } - // Только для TrueType - unsigned short *GetCodeToGIDMap(CFontFileTrueType *pTTF); - - // Следующие три функции используются только для Type 3 - Dict *GetCharProcs(); - Object *GetCharProc(int nCode, Object *pProc); - Dict *GetResources(); - - private: - - char *m_ppEncoding[256]; // Кодировка( Сhar code --> Сhar name) - bool m_arrEncFree[256]; // Булевские значения для имени каждого символа: true, если под строку выделяли память - CharCodeToUnicode *m_pCharToUnicode; // Сhar code --> Unicode - bool m_bHasEncoding; // Имеется ли кодировка вообще? - bool m_bUsesMacRomanEncoding; // Кодировка MacRomanEncoding? - double m_arrWidths[256]; // Ширины символов - Object m_oCharProcs; // Специфично только для Type 3, словарь CharProcs - Object m_oResources; // Специфично только для Type 3, словарь Resources - }; - - //------------------------------------------------------------------------ - // GrCIDFont - //------------------------------------------------------------------------ - - class GrCIDFont : public GrFont - { - public: - - GrCIDFont(XRef *pXref, char *sTag, Ref oID, StringExt *seName, Dict *pFontDict, GlobalParams *pGlobalParams); - - virtual ~GrCIDFont(); - - virtual bool IsCIDFont() - { - return true; - } - - virtual int GetNextChar(char *sText, int nLen, CharCode *punCode, Unicode *punUnicode, int uSize, int *uLen, double *pdDx, double *pdDy, double *pdVx, double *pdVy); - - virtual int GetWMode(); - - CharCodeToUnicode *GetToUnicode(); - - // Сollection name (-). - StringExt *GetCollection(); - - // CID-to-GID. Используется только если тип = fontCIDType2. - unsigned short *GetCIDToGID() - { - return m_pCidToGID; - } - int GetCIDToGIDLen() - { - return m_nCidToGIDLen; - } - - CMap *GetCMap() - { - return m_pCMap; - } - - private: - - CMap *m_pCMap; // char code --> CID - CharCodeToUnicode *m_pCharToUnicode; // CID --> Unicode - GrFontCIDWidths m_oWidths; // character widths - unsigned short *m_pCidToGID; // CID --> GID mapping (for embedded TrueType fonts) - int m_nCidToGIDLen; - }; - - //------------------------------------------------------------------------ - // GrFontDict - //------------------------------------------------------------------------ - - class GrFontDict - { - public: - - GrFontDict(XRef *pXref, Ref *pFontDictRef, Dict *pFontDict, GlobalParams *pGlobalParams); - - ~GrFontDict(); - - GrFont *Search(char *sTag); - - int GetFontsCount() - { - return m_nFontsCount; - } - GrFont *GetFont(int nIndex) - { - return m_ppFonts[nIndex]; - } - - private: - - GrFont **m_ppFonts; // Список шрифтов - int m_nFontsCount; // Количество шрифтов - GlobalParams *m_pGlobalParams; - }; -} - -#endif // _PDFREADER_GFONT_H diff --git a/PdfReader/old/GState.cpp b/PdfReader/old/GState.cpp deleted file mode 100644 index 80c76dd384..0000000000 --- a/PdfReader/old/GState.cpp +++ /dev/null @@ -1,4881 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "Array.h" -#include "Page.h" -#include "GState.h" -#include "Dict.h" -#include "Stream.h" - -namespace PdfReader -{ - static inline GrColorComp ClipToBounds(GrColorComp nColor) - { - return (nColor < 0) ? 0 : (nColor > GrColorComp1) ? GrColorComp1 : nColor; - } - - static inline double ClipToBounds(double dValue) - { - return (dValue < 0) ? 0 : (dValue > 1) ? 1 : dValue; - } - - //------------------------------------------------------------------------------------------------------------------------------- - - struct GrBlendModeInfo - { - char *sName; - GraphicsBlendMode eMode; - }; - - static GrBlendModeInfo c_arrsGrBlendModeNames[] = - { - { "Normal", grBlendNormal }, - { "Compatible", grBlendNormal }, - { "Multiply", grBlendMultiply }, - { "Screen", grBlendScreen }, - { "Overlay", grBlendOverlay }, - { "Darken", grBlendDarken }, - { "Lighten", grBlendLighten }, - { "ColorDodge", grBlendColorDodge }, - { "ColorBurn", grBlendColorBurn }, - { "HardLight", grBlendHardLight }, - { "SoftLight", grBlendSoftLight }, - { "Difference", grBlendDifference }, - { "Exclusion", grBlendExclusion }, - { "Hue", grBlendHue }, - { "Saturation", grBlendSaturation }, - { "Color", grBlendColor }, - { "Luminosity", grBlendLuminosity } - }; - -#define GrBlendModeNamesCount ((int)((sizeof(c_arrsGrBlendModeNames) / sizeof(GrBlendModeInfo)))) - - //------------------------------------------------------------------------------------------------------------------------------- - - static char *c_arrsGrColorSpaceModeNames[] = - { - "DeviceGray", - "CalGray", - "DeviceRGB", - "CalRGB", - "DeviceCMYK", - "Lab", - "ICCBased", - "Indexed", - "Separation", - "DeviceN", - "Pattern" - }; - -#define GrColorSpaceModesCount ((sizeof(c_arrsGrColorSpaceModeNames) / sizeof(char *))) - - //------------------------------------------------------------------------------------------------------------------------------- - // GrColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrColorSpace::GrColorSpace() - { - } - - GrColorSpace::~GrColorSpace() - { - } - - GrColorSpace *GrColorSpace::Parse(Object *pColorSpaceObject) - { - GrColorSpace *pColorSpace = NULL; - - if (pColorSpaceObject->IsName()) - { - if (pColorSpaceObject->IsName("DeviceGray") || pColorSpaceObject->IsName("G")) - { - pColorSpace = new GrDeviceGrayColorSpace(); - } - else if (pColorSpaceObject->IsName("DeviceRGB") || pColorSpaceObject->IsName("RGB")) - { - pColorSpace = new GrDeviceRGBColorSpace(); - } - else if (pColorSpaceObject->IsName("DeviceCMYK") || pColorSpaceObject->IsName("CMYK")) - { - pColorSpace = new GrDeviceCMYKColorSpace(); - } - else if (pColorSpaceObject->IsName("Pattern")) - { - pColorSpace = new GrPatternColorSpace(NULL); - } - else - { - // TO DO: Error "Bad color space" - } - } - else if (pColorSpaceObject->IsArray()) - { - Object oTemp; - pColorSpaceObject->ArrayGet(0, &oTemp); - if (oTemp.IsName("DeviceGray") || oTemp.IsName("G")) - { - pColorSpace = new GrDeviceGrayColorSpace(); - } - else if (oTemp.IsName("DeviceRGB") || oTemp.IsName("RGB")) - { - pColorSpace = new GrDeviceRGBColorSpace(); - } - else if (oTemp.IsName("DeviceCMYK") || oTemp.IsName("CMYK")) - { - pColorSpace = new GrDeviceCMYKColorSpace(); - } - else if (oTemp.IsName("CalGray")) - { - pColorSpace = GrCalGrayColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("CalRGB")) - { - pColorSpace = GrCalRGBColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("Lab")) - { - pColorSpace = GrLabColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("ICCBased")) - { - pColorSpace = GrICCBasedColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("Indexed") || oTemp.IsName("I")) - { - pColorSpace = GrIndexedColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("Separation")) - { - pColorSpace = GrSeparationColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("DeviceN")) - { - pColorSpace = GrDeviceNColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else if (oTemp.IsName("Pattern")) - { - pColorSpace = GrPatternColorSpace::Parse(pColorSpaceObject->GetArray()); - } - else - { - // TO DO: Error "Bad color space" - } - oTemp.Free(); - } - else - { - // TO DO: Error "Bad color space - expected name or array" - } - return pColorSpace; - } - - void GrColorSpace::GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue) - { - for (int nIndex = 0; nIndex < GetComponentsCount(); ++nIndex) - { - pDecodeLow[nIndex] = 0; - pDecodeRange[nIndex] = 1; - } - } - - int GrColorSpace::GetColorSpaceModesCount() - { - return GrColorSpaceModesCount; - } - - char *GrColorSpace::GetColorSpaceModeName(int nIndex) - { - return c_arrsGrColorSpaceModeNames[nIndex]; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceGrayColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrDeviceGrayColorSpace::GrDeviceGrayColorSpace() - { - } - - GrDeviceGrayColorSpace::~GrDeviceGrayColorSpace() - { - } - - GrColorSpace *GrDeviceGrayColorSpace::Copy() - { - return new GrDeviceGrayColorSpace(); - } - - void GrDeviceGrayColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = ClipToBounds(pColor->arrComp[0]); - } - - void GrDeviceGrayColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - pRGB->r = pRGB->g = pRGB->b = ClipToBounds(pColor->arrComp[0]); - } - - void GrDeviceGrayColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - pCMYK->c = pCMYK->m = pCMYK->y = 0; - pCMYK->k = ClipToBounds(GrColorComp1 - pColor->arrComp[0]); - } - - void GrDeviceGrayColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrCalGrayColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrCalGrayColorSpace::GrCalGrayColorSpace() - { - m_dWhiteX = m_dWhiteY = m_dWhiteZ = 1; - m_dBlackX = m_dBlackY = m_dBlackZ = 0; - m_dGamma = 1; - } - - GrCalGrayColorSpace::~GrCalGrayColorSpace() - { - } - - GrColorSpace *GrCalGrayColorSpace::Copy() - { - GrCalGrayColorSpace *pColorSpace = new GrCalGrayColorSpace(); - pColorSpace->m_dWhiteX = m_dWhiteX; - pColorSpace->m_dWhiteY = m_dWhiteY; - pColorSpace->m_dWhiteZ = m_dWhiteZ; - pColorSpace->m_dBlackX = m_dBlackX; - pColorSpace->m_dBlackY = m_dBlackY; - pColorSpace->m_dBlackZ = m_dBlackZ; - pColorSpace->m_dGamma = m_dGamma; - return pColorSpace; - } - - GrColorSpace *GrCalGrayColorSpace::Parse(Array *pArray) - { - Object oDict; - pArray->Get(1, &oDict); - - if (!oDict.IsDict()) - { - // TO DO: Error "Bad CalGray color space" - oDict.Free(); - return NULL; - } - - GrCalGrayColorSpace *pColorSpace = new GrCalGrayColorSpace(); - Object oDictValue; - if (oDict.DictLookup("WhitePoint", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 3) - { - Object oTemp; - oDictValue.ArrayGet(0, &oTemp); - pColorSpace->m_dWhiteX = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(1, &oTemp); - pColorSpace->m_dWhiteY = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(2, &oTemp); - pColorSpace->m_dWhiteZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictValue.Free(); - - if (oDict.DictLookup("BlackPoint", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 3) - { - Object oTemp; - oDictValue.ArrayGet(0, &oTemp); - pColorSpace->m_dBlackX = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(1, &oTemp); - pColorSpace->m_dBlackY = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(2, &oTemp); - pColorSpace->m_dBlackZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictValue.Free(); - - if (oDict.DictLookup("Gamma", &oDictValue)->IsNum()) - { - pColorSpace->m_dGamma = oDictValue.GetNum(); - } - oDictValue.Free(); - - oDict.Free(); - return pColorSpace; - } - - void GrCalGrayColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = ClipToBounds(pColor->arrComp[0]); - } - - void GrCalGrayColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - pRGB->r = pRGB->g = pRGB->b = ClipToBounds(pColor->arrComp[0]); - } - - void GrCalGrayColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - pCMYK->c = pCMYK->m = pCMYK->y = 0; - pCMYK->k = ClipToBounds(GrColorComp1 - pColor->arrComp[0]); - } - - void GrCalGrayColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceRGBColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrDeviceRGBColorSpace::GrDeviceRGBColorSpace() - { - } - - GrDeviceRGBColorSpace::~GrDeviceRGBColorSpace() - { - } - - GrColorSpace *GrDeviceRGBColorSpace::Copy() - { - return new GrDeviceRGBColorSpace(); - } - - void GrDeviceRGBColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = ClipToBounds((GrColorComp)(0.3 * pColor->arrComp[0] + 0.59 * pColor->arrComp[1] + 0.11 * pColor->arrComp[2] + 0.5)); - } - - void GrDeviceRGBColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - pRGB->r = ClipToBounds(pColor->arrComp[0]); - pRGB->g = ClipToBounds(pColor->arrComp[1]); - pRGB->b = ClipToBounds(pColor->arrComp[2]); - } - - void GrDeviceRGBColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - GrColorComp nC = ClipToBounds(GrColorComp1 - pColor->arrComp[0]); - GrColorComp nM = ClipToBounds(GrColorComp1 - pColor->arrComp[1]); - GrColorComp nY = ClipToBounds(GrColorComp1 - pColor->arrComp[2]); - GrColorComp nK = nC; - - if (nM < nK) - { - nK = nM; - } - if (nY < nK) - { - nK = nY; - } - pCMYK->c = nC - nK; - pCMYK->m = nM - nK; - pCMYK->y = nY - nK; - pCMYK->k = nK; - } - - void GrDeviceRGBColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - pColor->arrComp[1] = 0; - pColor->arrComp[2] = 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrCalRGBColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrCalRGBColorSpace::GrCalRGBColorSpace() - { - m_dWhiteX = m_dWhiteY = m_dWhiteZ = 1; - m_dBlackX = m_dBlackY = m_dBlackZ = 0; - m_dGammaR = m_dGammaG = m_dGammaB = 1; - m_arrdMatrix[0] = 1; m_arrdMatrix[1] = 0; m_arrdMatrix[2] = 0; - m_arrdMatrix[3] = 0; m_arrdMatrix[4] = 1; m_arrdMatrix[5] = 0; - m_arrdMatrix[6] = 0; m_arrdMatrix[7] = 0; m_arrdMatrix[8] = 1; - } - - GrCalRGBColorSpace::~GrCalRGBColorSpace() - { - } - - GrColorSpace *GrCalRGBColorSpace::Copy() - { - GrCalRGBColorSpace *pColorSpace = new GrCalRGBColorSpace(); - pColorSpace->m_dWhiteX = m_dWhiteX; - pColorSpace->m_dWhiteY = m_dWhiteY; - pColorSpace->m_dWhiteZ = m_dWhiteZ; - pColorSpace->m_dBlackX = m_dBlackX; - pColorSpace->m_dBlackY = m_dBlackY; - pColorSpace->m_dBlackZ = m_dBlackZ; - pColorSpace->m_dGammaR = m_dGammaR; - pColorSpace->m_dGammaG = m_dGammaG; - pColorSpace->m_dGammaB = m_dGammaB; - for (int nIndex = 0; nIndex < 9; ++nIndex) - { - pColorSpace->m_arrdMatrix[nIndex] = m_arrdMatrix[nIndex]; - } - return pColorSpace; - } - - GrColorSpace *GrCalRGBColorSpace::Parse(Array *pArray) - { - Object oDict; - pArray->Get(1, &oDict); - if (!oDict.IsDict()) - { - // TO DO: Error "Bad CalRGB color space" - oDict.Free(); - return NULL; - } - - GrCalRGBColorSpace *pColorSpace = new GrCalRGBColorSpace(); - Object oDictValue; - if (oDict.DictLookup("WhitePoint", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 3) - { - Object oTemp; - oDictValue.ArrayGet(0, &oTemp); - pColorSpace->m_dWhiteX = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(1, &oTemp); - pColorSpace->m_dWhiteY = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(2, &oTemp); - pColorSpace->m_dWhiteZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictValue.Free(); - - if (oDict.DictLookup("BlackPoint", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 3) - { - Object oTemp; - oDictValue.ArrayGet(0, &oTemp); - pColorSpace->m_dBlackX = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(1, &oTemp); - pColorSpace->m_dBlackY = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(2, &oTemp); - pColorSpace->m_dBlackZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictValue.Free(); - - if (oDict.DictLookup("Gamma", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 3) - { - Object oTemp; - oDictValue.ArrayGet(0, &oTemp); - pColorSpace->m_dGammaR = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(1, &oTemp); - pColorSpace->m_dGammaG = oTemp.GetNum(); - oTemp.Free(); - - oDictValue.ArrayGet(2, &oTemp); - pColorSpace->m_dGammaB = oTemp.GetNum(); - oTemp.Free(); - } - oDictValue.Free(); - - if (oDict.DictLookup("Matrix", &oDictValue)->IsArray() && oDictValue.ArrayGetLength() == 9) - { - for (int nIndex = 0; nIndex < 9; ++nIndex) - { - Object oTemp; - oDictValue.ArrayGet(nIndex, &oTemp); - pColorSpace->m_arrdMatrix[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - oDictValue.Free(); - oDict.Free(); - return pColorSpace; - } - - void GrCalRGBColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = ClipToBounds((GrColorComp)(0.299 * pColor->arrComp[0] + 0.587 * pColor->arrComp[1] + 0.114 * pColor->arrComp[2] + 0.5)); - } - - void GrCalRGBColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - pRGB->r = ClipToBounds(pColor->arrComp[0]); - pRGB->g = ClipToBounds(pColor->arrComp[1]); - pRGB->b = ClipToBounds(pColor->arrComp[2]); - } - - void GrCalRGBColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - GrColorComp nC = ClipToBounds(GrColorComp1 - pColor->arrComp[0]); - GrColorComp nM = ClipToBounds(GrColorComp1 - pColor->arrComp[1]); - GrColorComp nY = ClipToBounds(GrColorComp1 - pColor->arrComp[2]); - GrColorComp nK = nC; - - if (nM < nK) - { - nK = nM; - } - if (nY < nK) - { - nK = nY; - } - pCMYK->c = nC - nK; - pCMYK->m = nM - nK; - pCMYK->y = nY - nK; - pCMYK->k = nK; - } - - void GrCalRGBColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - pColor->arrComp[1] = 0; - pColor->arrComp[2] = 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceCMYKColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrDeviceCMYKColorSpace::GrDeviceCMYKColorSpace() - { - } - - GrDeviceCMYKColorSpace::~GrDeviceCMYKColorSpace() - { - } - - GrColorSpace *GrDeviceCMYKColorSpace::Copy() - { - return new GrDeviceCMYKColorSpace(); - } - - void GrDeviceCMYKColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = ClipToBounds((GrColorComp)(GrColorComp1 - pColor->arrComp[3] - 0.3 * pColor->arrComp[0] - 0.59 * pColor->arrComp[1] - 0.11 * pColor->arrComp[2] + 0.5)); - } - - void GrDeviceCMYKColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - double dR = 0, dG = 0, dB = 0, dX = 0; - - double dC = ColorToDouble(pColor->arrComp[0]); - double dM = ColorToDouble(pColor->arrComp[1]); - double dY = ColorToDouble(pColor->arrComp[2]); - double dK = ColorToDouble(pColor->arrComp[3]); - - double dRevC = 1 - dC; - double dRevM = 1 - dM; - double dRevY = 1 - dY; - double dRevK = 1 - dK; - - // C M Y K - dX = dRevC * dRevM * dRevY * dRevK; // 0 0 0 0 - dR = dG = dB = dX; - - dX = dRevC * dRevM * dRevY * dK; // 0 0 0 1 - dR += 0.1373 * dX; - dG += 0.1216 * dX; - dB += 0.1255 * dX; - - dX = dRevC * dRevM * dY * dRevK; // 0 0 1 0 - dR += dX; - dG += 0.9490 * dX; - - dX = dRevC * dRevM * dY * dK; // 0 0 1 1 - dR += 0.1098 * dX; - dG += 0.1020 * dX; - - dX = dRevC * dM * dRevY * dRevK; // 0 1 0 0 - dR += 0.9255 * dX; - dB += 0.5490 * dX; - - dX = dRevC * dM * dRevY * dK; // 0 1 0 1 - dR += 0.1412 * dX; - - dX = dRevC * dM * dY * dRevK; // 0 1 1 0 - dR += 0.9294 * dX; - dG += 0.1098 * dX; - dB += 0.1412 * dX; - - dX = dRevC * dM * dY * dK; // 0 1 1 1 - dR += 0.1333 * dX; - - dX = dC * dRevM * dRevY * dRevK; // 1 0 0 0 - dG += 0.6784 * dX; - dB += 0.9373 * dX; - - dX = dC * dRevM * dRevY * dK; // 1 0 0 1 - dG += 0.0588 * dX; - dB += 0.1412 * dX; - - dX = dC * dRevM * dY * dRevK; // 1 0 1 0 - dG += 0.6510 * dX; - dB += 0.3137 * dX; - - dX = dC * dRevM * dY * dK; // 1 0 1 1 - dG += 0.0745 * dX; - - dX = dC * dM * dRevY * dRevK; // 1 1 0 0 - dR += 0.1804 * dX; - dG += 0.1922 * dX; - dB += 0.5725 * dX; - - dX = dC * dM * dRevY * dK; // 1 1 0 1 - dB += 0.0078 * dX; - - dX = dC * dM * dY * dRevK; // 1 1 1 0 - dR += 0.2118 * dX; - dG += 0.2119 * dX; - dB += 0.2235 * dX; - - pRGB->r = ClipToBounds(DoubleToColor(dR)); - pRGB->g = ClipToBounds(DoubleToColor(dG)); - pRGB->b = ClipToBounds(DoubleToColor(dB)); - } - - void GrDeviceCMYKColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - pCMYK->c = ClipToBounds(pColor->arrComp[0]); - pCMYK->m = ClipToBounds(pColor->arrComp[1]); - pCMYK->y = ClipToBounds(pColor->arrComp[2]); - pCMYK->k = ClipToBounds(pColor->arrComp[3]); - } - - void GrDeviceCMYKColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - pColor->arrComp[1] = 0; - pColor->arrComp[2] = 0; - pColor->arrComp[3] = GrColorComp1; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrLabColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - // Это обратная матрица к матрице LMN, данной в примере 4.10 в спецификации - // PostScript Language Reference, Third Edition. - static double c_arrLMNReverse[3][3] = - { - { 3.240449, -1.537136, -0.498531 }, - { -0.969265, 1.876011, 0.041556 }, - { 0.055643, -0.204026, 1.057229 } - }; - - GrLabColorSpace::GrLabColorSpace() - { - m_dWhiteX = m_dWhiteY = m_dWhiteZ = 1; - m_dBlackX = m_dBlackY = m_dBlackZ = 0; - m_dMinA = m_dMinB = -100; - m_dMaxA = m_dMaxB = 100; - } - - GrLabColorSpace::~GrLabColorSpace() - { - } - - GrColorSpace *GrLabColorSpace::Copy() - { - GrLabColorSpace *pColorSpace = new GrLabColorSpace(); - pColorSpace->m_dWhiteX = m_dWhiteX; - pColorSpace->m_dWhiteY = m_dWhiteY; - pColorSpace->m_dWhiteZ = m_dWhiteZ; - pColorSpace->m_dBlackX = m_dBlackX; - pColorSpace->m_dBlackY = m_dBlackY; - pColorSpace->m_dBlackZ = m_dBlackZ; - pColorSpace->m_dMinA = m_dMinA; - pColorSpace->m_dMaxA = m_dMaxA; - pColorSpace->m_dMinB = m_dMinB; - pColorSpace->m_dMaxB = m_dMaxB; - pColorSpace->m_dMultR = m_dMultR; - pColorSpace->m_dMultG = m_dMultG; - pColorSpace->m_dMultB = m_dMultB; - return pColorSpace; - } - - GrColorSpace *GrLabColorSpace::Parse(Array *pArray) - { - Object obj1, obj2, obj3; - - Object oDict; - pArray->Get(1, &oDict); - if (!oDict.IsDict()) - { - // TO DO: Error "Bad Lab color space" - oDict.Free(); - return NULL; - } - GrLabColorSpace *pColorSpace = new GrLabColorSpace(); - - Object oDictItem; - if (oDict.DictLookup("WhitePoint", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 3) - { - Object oTemp; - oDictItem.ArrayGet(0, &oTemp); - pColorSpace->m_dWhiteX = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(1, &oTemp); - pColorSpace->m_dWhiteY = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(2, &oTemp); - pColorSpace->m_dWhiteZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - if (oDict.DictLookup("BlackPoint", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 3) - { - Object oTemp; - oDictItem.ArrayGet(0, &oTemp); - pColorSpace->m_dBlackX = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(1, &oTemp); - pColorSpace->m_dBlackY = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(2, &oTemp); - pColorSpace->m_dBlackZ = oTemp.GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - if (oDict.DictLookup("Range", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4) - { - Object oTemp; - oDictItem.ArrayGet(0, &oTemp); - pColorSpace->m_dMinA = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(1, &oTemp); - pColorSpace->m_dMaxA = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(2, &oTemp); - pColorSpace->m_dMinB = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(3, &oTemp); - pColorSpace->m_dMaxB = oTemp.GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - oDict.Free(); - - - pColorSpace->m_dMultR = 1 / (c_arrLMNReverse[0][0] * pColorSpace->m_dWhiteX + c_arrLMNReverse[0][1] * pColorSpace->m_dWhiteY + c_arrLMNReverse[0][2] * pColorSpace->m_dWhiteZ); - pColorSpace->m_dMultG = 1 / (c_arrLMNReverse[1][0] * pColorSpace->m_dWhiteX + c_arrLMNReverse[1][1] * pColorSpace->m_dWhiteY + c_arrLMNReverse[1][2] * pColorSpace->m_dWhiteZ); - pColorSpace->m_dMultB = 1 / (c_arrLMNReverse[2][0] * pColorSpace->m_dWhiteX + c_arrLMNReverse[2][1] * pColorSpace->m_dWhiteY + c_arrLMNReverse[2][2] * pColorSpace->m_dWhiteZ); - - return pColorSpace; - } - - void GrLabColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - GrRGB oRGB; - - GetRGB(pColor, &oRGB); - *pGray = ClipToBounds((GrColorComp)(0.299 * oRGB.r + 0.587 * oRGB.g + 0.114 * oRGB.b + 0.5)); - } - - void GrLabColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - double dX, dY, dZ; - - // L*a*b* -> CIE 1931 XYZ - double dTemp1 = (ColorToDouble(pColor->arrComp[0]) + 16) / 116; - double dTemp2 = dTemp1 + ColorToDouble(pColor->arrComp[1]) / 500; - if (dTemp2 >= (6.0 / 29.0)) - { - dX = dTemp2 * dTemp2 * dTemp2; - } - else - { - dX = (108.0 / 841.0) * (dTemp2 - (4.0 / 29.0)); - } - dX *= m_dWhiteX; - if (dTemp1 >= (6.0 / 29.0)) - { - dY = dTemp1 * dTemp1 * dTemp1; - } - else - { - dY = (108.0 / 841.0) * (dTemp1 - (4.0 / 29.0)); - } - dY *= m_dWhiteY; - dTemp2 = dTemp1 - ColorToDouble(pColor->arrComp[2]) / 200; - if (dTemp2 >= (6.0 / 29.0)) - { - dZ = dTemp2 * dTemp2 * dTemp2; - } - else - { - dZ = (108.0 / 841.0) * (dTemp2 - (4.0 / 29.0)); - } - dZ *= m_dWhiteZ; - - // XYZ -> RGB ( учитывая гамма коррекцию ) - double dR = c_arrLMNReverse[0][0] * dX + c_arrLMNReverse[0][1] * dY + c_arrLMNReverse[0][2] * dZ; - double dG = c_arrLMNReverse[1][0] * dX + c_arrLMNReverse[1][1] * dY + c_arrLMNReverse[1][2] * dZ; - double dB = c_arrLMNReverse[2][0] * dX + c_arrLMNReverse[2][1] * dY + c_arrLMNReverse[2][2] * dZ; - pRGB->r = DoubleToColor(pow(ClipToBounds(dR * m_dMultR), 0.5)); - pRGB->g = DoubleToColor(pow(ClipToBounds(dG * m_dMultG), 0.5)); - pRGB->b = DoubleToColor(pow(ClipToBounds(dB * m_dMultB), 0.5)); - } - - void GrLabColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - GrRGB oRGB; - - GetRGB(pColor, &oRGB); - GrColorComp nC = ClipToBounds(GrColorComp1 - oRGB.r); - GrColorComp nM = ClipToBounds(GrColorComp1 - oRGB.g); - GrColorComp nY = ClipToBounds(GrColorComp1 - oRGB.b); - GrColorComp nK = nC; - - if (nM < nK) - { - nK = nM; - } - if (nY < nK) - { - nK = nY; - } - pCMYK->c = nC - nK; - pCMYK->m = nM - nK; - pCMYK->y = nY - nK; - pCMYK->k = nK; - } - - void GrLabColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - if (m_dMinA > 0) - { - pColor->arrComp[1] = DoubleToColor(m_dMinA); - } - else if (m_dMaxA < 0) - { - pColor->arrComp[1] = DoubleToColor(m_dMaxA); - } - else - { - pColor->arrComp[1] = 0; - } - if (m_dMinB > 0) - { - pColor->arrComp[2] = DoubleToColor(m_dMinB); - } - else if (m_dMaxB < 0) - { - pColor->arrComp[2] = DoubleToColor(m_dMaxB); - } - else - { - pColor->arrComp[2] = 0; - } - } - - void GrLabColorSpace::GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue) - { - pDecodeLow[0] = 0; - pDecodeRange[0] = 100; - pDecodeLow[1] = m_dMinA; - pDecodeRange[1] = m_dMaxA - m_dMinA; - pDecodeLow[2] = m_dMinB; - pDecodeRange[2] = m_dMaxB - m_dMinB; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrICCBasedColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrICCBasedColorSpace::GrICCBasedColorSpace(int nComponentsCount, GrColorSpace *pAlternate, Ref *pICCProfileStream) - { - m_nComponentsCount = nComponentsCount; - m_pAlternate = pAlternate; - m_oICCProfileStream = *pICCProfileStream; - m_arrdRangeMin[0] = m_arrdRangeMin[1] = m_arrdRangeMin[2] = m_arrdRangeMin[3] = 0; - m_arrdRangeMax[0] = m_arrdRangeMax[1] = m_arrdRangeMax[2] = m_arrdRangeMax[3] = 1; - } - - GrICCBasedColorSpace::~GrICCBasedColorSpace() - { - if (m_pAlternate) - delete m_pAlternate; - } - - GrColorSpace *GrICCBasedColorSpace::Copy() - { - GrICCBasedColorSpace *pColorSpaces = new GrICCBasedColorSpace(m_nComponentsCount, m_pAlternate->Copy(), &m_oICCProfileStream); - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - pColorSpaces->m_arrdRangeMin[nIndex] = m_arrdRangeMin[nIndex]; - pColorSpaces->m_arrdRangeMax[nIndex] = m_arrdRangeMax[nIndex]; - } - return pColorSpaces; - } - - GrColorSpace *GrICCBasedColorSpace::Parse(Array *pArray) - { - Ref oICCProfileStream; - Object oStream; - pArray->GetCopy(1, &oStream); - if (oStream.IsRef()) - { - oICCProfileStream = oStream.GetRef(); - } - else - { - oICCProfileStream.nNum = 0; - oICCProfileStream.nGen = 0; - } - oStream.Free(); - pArray->Get(1, &oStream); - if (!oStream.IsStream()) - { - // TO DO: Error "Bad ICCBased color space (stream)" - oStream.Free(); - return NULL; - } - Dict *pDict = oStream.StreamGetDict(); - - Object oDictItem; - if (!pDict->Search("N", &oDictItem)->IsInt()) - { - // TO DO: Error "Bad ICCBased color space (N)" - oDictItem.Free(); - oStream.Free(); - return NULL; - } - int nCompCount = oDictItem.GetInt(); - oDictItem.Free(); - - if (nCompCount > GrColorMaxComps) - { - // TO DO: Error "ICCBased color space with too many (%d > %d) components" - nCompCount = GrColorMaxComps; - } - - GrColorSpace *pAlternativeCS; - if (pDict->Search("Alternate", &oDictItem)->IsNull() || !(pAlternativeCS = GrColorSpace::Parse(&oDictItem))) - { - switch (nCompCount) - { - case 1: - pAlternativeCS = new GrDeviceGrayColorSpace(); - break; - case 3: - pAlternativeCS = new GrDeviceRGBColorSpace(); - break; - case 4: - pAlternativeCS = new GrDeviceCMYKColorSpace(); - break; - default: - // TO DO: Error "Bad ICCBased color space - invalid N" - oDictItem.Free(); - oStream.Free(); - return NULL; - } - } - oDictItem.Free(); - GrICCBasedColorSpace *pColorSpace = new GrICCBasedColorSpace(nCompCount, pAlternativeCS, &oICCProfileStream); - - if (pDict->Search("Range", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2 * nCompCount) - { - for (int nIndex = 0; nIndex < nCompCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(2 * nIndex, &oTemp); - pColorSpace->m_arrdRangeMin[nIndex] = oTemp.GetNum(); - oTemp.Free(); - - oDictItem.ArrayGet(2 * nIndex + 1, &oTemp); - pColorSpace->m_arrdRangeMax[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - oDictItem.Free(); - oStream.Free(); - return pColorSpace; - } - - void GrICCBasedColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - m_pAlternate->GetGray(pColor, pGray); - } - - void GrICCBasedColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - m_pAlternate->GetRGB(pColor, pRGB); - } - - void GrICCBasedColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - m_pAlternate->GetCMYK(pColor, pCMYK); - } - - void GrICCBasedColorSpace::GetDefaultColor(GrColor *pColor) - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - if (m_arrdRangeMin[nIndex] > 0) - { - pColor->arrComp[nIndex] = DoubleToColor(m_arrdRangeMin[nIndex]); - } - else if (m_arrdRangeMax[nIndex] < 0) - { - pColor->arrComp[nIndex] = DoubleToColor(m_arrdRangeMax[nIndex]); - } - else - { - pColor->arrComp[nIndex] = 0; - } - } - } - - void GrICCBasedColorSpace::GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue) - { - m_pAlternate->GetDefaultRanges(pDecodeLow, pDecodeRange, nMaxImagePixelValue); - -#if 0 - // Так должно работать, но некоторые PDF фалй не содержат корректных данных в полях Range - // в словаре ICCBased. - - for ( int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex ) - { - pDecodeLow[nIndex] = m_arrdRangeMin[nIndex]; - pDecodeRange[nIndex] = m_arrdRangeMax[nIndex] - m_arrdRangeMin[nIndex]; - } -#endif - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrIndexedColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrIndexedColorSpace::GrIndexedColorSpace(GrColorSpace *pBase, int nHival) - { - m_pBase = pBase; - m_nHival = nHival; - m_pLookup = (unsigned char *)MemUtilsMallocArray((m_nHival + 1) * m_pBase->GetComponentsCount(), sizeof(unsigned char)); - } - - GrIndexedColorSpace::~GrIndexedColorSpace() - { - if (m_pBase) - delete m_pBase; - - MemUtilsFree(m_pLookup); - } - - GrColorSpace *GrIndexedColorSpace::Copy() - { - GrIndexedColorSpace *pColorSpace = new GrIndexedColorSpace(m_pBase->Copy(), m_nHival); - memcpy(pColorSpace->m_pLookup, m_pLookup, (m_nHival + 1) * m_pBase->GetComponentsCount() * sizeof(unsigned char)); - return pColorSpace; - } - - GrColorSpace *GrIndexedColorSpace::Parse(Array *pArray) - { - // [ /Indexed base hival lookup ] - массив из 4 элементов должен быть - if (pArray->GetCount() != 4) - { - // TO DO: Error "Bad Indexed color space" - return NULL; - } - - Object oArrayItem; - pArray->Get(1, &oArrayItem); - GrColorSpace *pBase = NULL; - if (!(pBase = GrColorSpace::Parse(&oArrayItem))) - { - // TO DO: Error "Bad Indexed color space (base color space)" - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - - if (!pArray->Get(2, &oArrayItem)->IsInt()) - { - // TO DO: Error "Bad Indexed color space (hival)" - if (pBase) - delete pBase; - oArrayItem.Free(); - return NULL; - } - int nHival = oArrayItem.GetInt(); - - if (nHival < 0 || nHival > 255) // По спецификации PDF значение hival должно лежать в отрезке [0,255] - { - // TO DO: Error "Bad Indexed color space (invalid hival value)" - if (pBase) - delete pBase; - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - GrIndexedColorSpace *pColorSpace = new GrIndexedColorSpace(pBase, nHival); - - pArray->Get(3, &oArrayItem); - int nCompCount = pBase->GetComponentsCount(); - - if (oArrayItem.IsStream()) - { - oArrayItem.StreamReset(); - for (int nIndex = 0; nIndex <= nHival; ++nIndex) - { - for (int nComp = 0; nComp < nCompCount; ++nComp) - { - int nChar = 0; - if ((nChar = oArrayItem.StreamGetChar()) == EOF) - { - // TO DO: Error "Bad Indexed color space (lookup table stream too short)" - if (pColorSpace) - delete pColorSpace; - oArrayItem.Free(); - return NULL; - } - pColorSpace->m_pLookup[nIndex * nCompCount + nComp] = (unsigned char)nChar; - } - } - oArrayItem.StreamClose(); - } - else if (oArrayItem.IsString()) - { - if (oArrayItem.GetString()->GetLength() < (nHival + 1) * nCompCount) - { - // TO DO: Error "Bad Indexed color space (lookup table string too short)" - if (pColorSpace) - delete pColorSpace; - oArrayItem.Free(); - return NULL; - } - char *sString = oArrayItem.GetString()->GetBuffer(); - for (int nIndex = 0; nIndex <= nHival; ++nIndex) - { - for (int nComp = 0; nComp < nCompCount; ++nComp) - { - pColorSpace->m_pLookup[nIndex * nCompCount + nComp] = (unsigned char)*sString++; - } - } - } - else - { - // TO DO: Error "Bad Indexed color space (lookup table)" - if (pColorSpace) - delete pColorSpace; - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - return pColorSpace; - } - - GrColor *GrIndexedColorSpace::MapColorToBase(GrColor *pColor, GrColor *pBaseColor) - { - double arrLow[GrColorMaxComps], arrRange[GrColorMaxComps]; - - int nCompsCount = m_pBase->GetComponentsCount(); - m_pBase->GetDefaultRanges(arrLow, arrRange, m_nHival); - unsigned char *pLookup = &m_pLookup[(int)(ColorToDouble(pColor->arrComp[0]) + 0.5) * nCompsCount]; - for (int nIndex = 0; nIndex < nCompsCount; ++nIndex) - { - pBaseColor->arrComp[nIndex] = DoubleToColor(arrLow[nIndex] + (pLookup[nIndex] / 255.0) * arrRange[nIndex]); - } - return pBaseColor; - } - - void GrIndexedColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - GrColor oTempColor; - - m_pBase->GetGray(MapColorToBase(pColor, &oTempColor), pGray); - } - - void GrIndexedColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - GrColor oTempColor; - - m_pBase->GetRGB(MapColorToBase(pColor, &oTempColor), pRGB); - } - - void GrIndexedColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - GrColor oTempColor; - - m_pBase->GetCMYK(MapColorToBase(pColor, &oTempColor), pCMYK); - } - - void GrIndexedColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = 0; - } - - void GrIndexedColorSpace::GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue) - { - pDecodeLow[0] = 0; - pDecodeRange[0] = nMaxImagePixelValue; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrSeparationColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrSeparationColorSpace::GrSeparationColorSpace(StringExt *seName, GrColorSpace *pAlternate, Function *pFunction) - { - m_seName = seName; - m_pAlternateSpace = pAlternate; - m_pFunction = pFunction; - m_bNonMarking = !m_seName->Compare("None"); - } - - GrSeparationColorSpace::~GrSeparationColorSpace() - { - if (m_seName) - delete m_seName; - if (m_pAlternateSpace) - delete m_pAlternateSpace; - if (m_pFunction) - delete m_pFunction; - } - - GrColorSpace *GrSeparationColorSpace::Copy() - { - return new GrSeparationColorSpace(m_seName->Copy(), m_pAlternateSpace->Copy(), m_pFunction->Copy()); - } - - GrColorSpace *GrSeparationColorSpace::Parse(Array *pArray) - { - // [ /Separation name alternateSpace tintTransform ] - должен быть массив из 4 элементов - if (pArray->GetCount() != 4) - { - // TO DO: Error "Bad Separation color space" - return NULL; - } - - Object oArrayItem; - if (!pArray->Get(1, &oArrayItem)->IsName()) - { - // TO DO: Error "Bad Separation color space (name)" - oArrayItem.Free(); - return NULL; - } - - StringExt *seName = new StringExt(oArrayItem.GetName()); - oArrayItem.Free(); - - pArray->Get(2, &oArrayItem); - GrColorSpace *pAlternate = NULL; - if (!(pAlternate = GrColorSpace::Parse(&oArrayItem))) - { - // TO DO: Error "Bad Separation color space (alternate color space)" - if (seName) - delete seName; - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - - pArray->Get(3, &oArrayItem); - Function *pFunction = NULL; - if (!(pFunction = Function::Parse(&oArrayItem))) - { - if (pAlternate) - delete pAlternate; - if (seName) - delete seName; - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - - GrSeparationColorSpace *pColorSpace = new GrSeparationColorSpace(seName, pAlternate, pFunction); - return pColorSpace; - } - - void GrSeparationColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - double arrDestColor[GrColorMaxComps]; - GrColor oAltColor; - - double dSrcColor = ColorToDouble(pColor->arrComp[0]); - m_pFunction->Transform(&dSrcColor, arrDestColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDestColor[nIndex]); - } - m_pAlternateSpace->GetGray(&oAltColor, pGray); - } - - void GrSeparationColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - double arrDestColor[GrColorMaxComps]; - GrColor oAltColor; - - double dSrcColor = ColorToDouble(pColor->arrComp[0]); - m_pFunction->Transform(&dSrcColor, arrDestColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDestColor[nIndex]); - } - m_pAlternateSpace->GetRGB(&oAltColor, pRGB); - } - - void GrSeparationColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - double arrDestColor[GrColorMaxComps]; - GrColor oAltColor; - - double dSrcColor = ColorToDouble(pColor->arrComp[0]); - m_pFunction->Transform(&dSrcColor, arrDestColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDestColor[nIndex]); - } - m_pAlternateSpace->GetCMYK(&oAltColor, pCMYK); - } - - void GrSeparationColorSpace::GetDefaultColor(GrColor *pColor) - { - pColor->arrComp[0] = GrColorComp1; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceNColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrDeviceNColorSpace::GrDeviceNColorSpace(int nComponentsCount, GrColorSpace *pAlternate, Function *pFunction) - { - m_nComponentsCount = nComponentsCount; - m_pAlternateSpace = pAlternate; - m_pFunction = pFunction; - m_bNonMarking = false; - } - - GrDeviceNColorSpace::~GrDeviceNColorSpace() - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - if (m_arrseNames[nIndex]) - delete m_arrseNames[nIndex]; - } - if (m_pAlternateSpace) - delete m_pAlternateSpace; - if (m_pFunction) - delete m_pFunction; - } - - GrColorSpace *GrDeviceNColorSpace::Copy() - { - GrDeviceNColorSpace *pColorSpace = new GrDeviceNColorSpace(m_nComponentsCount, m_pAlternateSpace->Copy(), m_pFunction->Copy()); - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - pColorSpace->m_arrseNames[nIndex] = m_arrseNames[nIndex]->Copy(); - } - pColorSpace->m_bNonMarking = m_bNonMarking; - return pColorSpace; - } - - GrColorSpace *GrDeviceNColorSpace::Parse(Array *pArray) - { - StringExt *arrseNames[GrColorMaxComps]; - - // Запись о данном цветом пространстве должны быть одной из следующих двух: - // [ /DeviceN names alternateSpace tintTransform ] - // [ /DeviceN names alternateSpace tintTransform attributes ] - - if (pArray->GetCount() != 4 && pArray->GetCount() != 5) - { - // TO DO: Error "Bad DeviceN color space" - return NULL; - } - - Object oArrayItem; - if (!pArray->Get(1, &oArrayItem)->IsArray()) - { - // TO DO: Error "Bad DeviceN color space (names)" - oArrayItem.Free(); - return NULL; - } - - int nCompsCount = oArrayItem.ArrayGetLength(); - if (nCompsCount > GrColorMaxComps) - { - // TO DO: Error "DeviceN color space with too many components" - nCompsCount = GrColorMaxComps; - } - for (int nIndex = 0; nIndex < nCompsCount; ++nIndex) - { - Object oName; - if (!oArrayItem.ArrayGet(nIndex, &oName)->IsName()) - { - // TO DO: Error "Bad DeviceN color space (names)" - oName.Free(); - oArrayItem.Free(); - return NULL; - } - arrseNames[nIndex] = new StringExt(oName.GetName()); - oName.Free(); - } - oArrayItem.Free(); - - pArray->Get(2, &oArrayItem); - GrColorSpace *pAlternate = NULL; - if (!(pAlternate = GrColorSpace::Parse(&oArrayItem))) - { - // TO DO: Error "Bad DeviceN color space (alternate color space)" - for (int nIndex = 0; nIndex < nCompsCount; ++nIndex) - { - if (arrseNames[nIndex]) - delete arrseNames[nIndex]; - } - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - - pArray->Get(3, &oArrayItem); - Function *pFunction = NULL; - if (!(pFunction = Function::Parse(&oArrayItem))) - { - if (pAlternate) - delete pAlternate; - for (int nIndex = 0; nIndex < nCompsCount; ++nIndex) - { - if (arrseNames[nIndex]) - delete arrseNames[nIndex]; - } - oArrayItem.Free(); - return NULL; - } - oArrayItem.Free(); - - GrDeviceNColorSpace *pColorSpace = new GrDeviceNColorSpace(nCompsCount, pAlternate, pFunction); - pColorSpace->m_bNonMarking = true; - - for (int nIndex = 0; nIndex < nCompsCount; ++nIndex) - { - pColorSpace->m_arrseNames[nIndex] = arrseNames[nIndex]; - if (arrseNames[nIndex]->Compare("None")) - { - pColorSpace->m_bNonMarking = false; - } - } - return pColorSpace; - } - - void GrDeviceNColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - double arrSrcColor[GrColorMaxComps], arrDstColor[GrColorMaxComps]; - GrColor oAltColor; - - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - arrSrcColor[nIndex] = ColorToDouble(pColor->arrComp[nIndex]); - } - m_pFunction->Transform(arrSrcColor, arrDstColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDstColor[nIndex]); - } - m_pAlternateSpace->GetGray(&oAltColor, pGray); - } - - void GrDeviceNColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - double arrSrcColor[GrColorMaxComps], arrDstColor[GrColorMaxComps]; - GrColor oAltColor; - - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - arrSrcColor[nIndex] = ColorToDouble(pColor->arrComp[nIndex]); - } - m_pFunction->Transform(arrSrcColor, arrDstColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDstColor[nIndex]); - } - m_pAlternateSpace->GetRGB(&oAltColor, pRGB); - } - - void GrDeviceNColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - double arrSrcColor[GrColorMaxComps], arrDstColor[GrColorMaxComps]; - GrColor oAltColor; - - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - arrSrcColor[nIndex] = ColorToDouble(pColor->arrComp[nIndex]); - } - m_pFunction->Transform(arrSrcColor, arrDstColor); - for (int nIndex = 0; nIndex < m_pAlternateSpace->GetComponentsCount(); ++nIndex) - { - oAltColor.arrComp[nIndex] = DoubleToColor(arrDstColor[nIndex]); - } - m_pAlternateSpace->GetCMYK(&oAltColor, pCMYK); - } - - void GrDeviceNColorSpace::GetDefaultColor(GrColor *pColor) - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - pColor->arrComp[nIndex] = GrColorComp1; - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPatternColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - GrPatternColorSpace::GrPatternColorSpace(GrColorSpace *pUnder) - { - m_pUnder = pUnder; - } - - GrPatternColorSpace::~GrPatternColorSpace() - { - if (m_pUnder) - { - delete m_pUnder; - } - } - - GrColorSpace *GrPatternColorSpace::Copy() - { - return new GrPatternColorSpace(m_pUnder ? m_pUnder->Copy() : (GrColorSpace *)NULL); - } - - GrColorSpace *GrPatternColorSpace::Parse(Array *pArray) - { - if (pArray->GetCount() != 1 && pArray->GetCount() != 2) - { - // TO DO: Error "Bad Pattern color space" - return NULL; - } - GrColorSpace *pUnder = NULL; - if (pArray->GetCount() == 2) - { - Object oTemp; - pArray->Get(1, &oTemp); - if (!(pUnder = GrColorSpace::Parse(&oTemp))) - { - // TO DO: Error "Bad Pattern color space (underlying color space)" - oTemp.Free(); - return NULL; - } - oTemp.Free(); - } - GrPatternColorSpace *pColorSpace = new GrPatternColorSpace(pUnder); - return pColorSpace; - } - - void GrPatternColorSpace::GetGray(GrColor *pColor, GrGray *pGray) - { - *pGray = 0; - } - - void GrPatternColorSpace::GetRGB(GrColor *pColor, GrRGB *pRGB) - { - pRGB->r = pRGB->g = pRGB->b = 0; - } - - void GrPatternColorSpace::GetCMYK(GrColor *pColor, GrCMYK *pCMYK) - { - pCMYK->c = pCMYK->m = pCMYK->y = 0; - pCMYK->k = 1; - } - - void GrPatternColorSpace::GetDefaultColor(GrColor *pColor) - { - // не используется - } - - //============================================================================================================================== - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPattern - //------------------------------------------------------------------------------------------------------------------------------- - - GrPattern::GrPattern(int nType) - { - m_nType = nType; - } - - GrPattern::~GrPattern() - { - } - - GrPattern *GrPattern::Parse(Object *pObject) - { - Object oTemp; - - if (pObject->IsDict()) - { - pObject->DictLookup("PatternType", &oTemp); - } - else if (pObject->IsStream()) - { - pObject->StreamGetDict()->Search("PatternType", &oTemp); - } - else - { - return NULL; - } - GrPattern *pPattern = NULL; - - if (oTemp.IsInt() && oTemp.GetInt() == 1) - { - pPattern = GrTilingPattern::Parse(pObject); - } - else if (oTemp.IsInt() && oTemp.GetInt() == 2) - { - pPattern = GrShadingPattern::Parse(pObject); - } - oTemp.Free(); - return pPattern; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrTilingPattern - //------------------------------------------------------------------------------------------------------------------------------- - - GrTilingPattern *GrTilingPattern::Parse(Object *pPatternObject) - { - int nPaintType = 0, nTilingType = 0; - double dXStep = 0, dYStep = 0; - Object oResources; - - if (!pPatternObject->IsStream()) - { - return NULL; - } - Dict *pDict = pPatternObject->StreamGetDict(); - - Object oDictItem; - if (pDict->Search("PaintType", &oDictItem)->IsInt()) - { - nPaintType = oDictItem.GetInt(); - } - else - { - nPaintType = 1; - // TO DO: Error "Invalid or missing PaintType in pattern" - } - oDictItem.Free(); - - if (pDict->Search("TilingType", &oDictItem)->IsInt()) - { - nTilingType = oDictItem.GetInt(); - } - else - { - nTilingType = 1; - // TO DO: Error "Invalid or missing TilingType in pattern" - } - oDictItem.Free(); - - double arrBBox[4] ={ 0, 0, 1, 1 }; - - if (pDict->Search("BBox", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4) - { - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - arrBBox[nIndex] = oTemp.GetNum(); - } - oTemp.Free(); - } - } - else - { - // TO DO: Error "Invalid or missing BBox in pattern" - } - oDictItem.Free(); - - if (pDict->Search("XStep", &oDictItem)->IsNum()) - { - dXStep = oDictItem.GetNum(); - } - else - { - dXStep = 1; - // TO DO: Error "Invalid or missing XStep in pattern" - } - oDictItem.Free(); - - if (pDict->Search("YStep", &oDictItem)->IsNum()) - { - dYStep = oDictItem.GetNum(); - } - else - { - dYStep = 1; - // TO DO: Error "Invalid or missing YStep in pattern" - } - oDictItem.Free(); - - if (!pDict->Search("Resources", &oResources)->IsDict()) - { - oResources.Free(); - oResources.InitNull(); - // TO DO: Error "Invalid or missing Resources in pattern" - } - - double arrMatrix[6] ={ 1, 0, 0, 1, 0, 0 }; - - if (pDict->Search("Matrix", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 6) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - arrMatrix[nIndex] = oTemp.GetNum(); - } - oTemp.Free(); - } - } - oDictItem.Free(); - - GrTilingPattern *pPattern = new GrTilingPattern(nPaintType, nTilingType, arrBBox, dXStep, dYStep, &oResources, arrMatrix, pPatternObject); - oResources.Free(); - return pPattern; - } - - GrTilingPattern::GrTilingPattern(int nPaintType, int nTilingType, double *pBBox, double dXStep, double dYStep, Object *pResources, double *pMatrix, Object *pContentStream) : - GrPattern(1) - { - m_nPaintType = nPaintType; - m_nTilingType = nTilingType; - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - m_arrBBox[nIndex] = pBBox[nIndex]; - } - m_dXStep = dXStep; - m_dYStep = dYStep; - pResources->Copy(&m_oResources); - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrMatrix[nIndex] = pMatrix[nIndex]; - } - pContentStream->Copy(&m_oContentStream); - } - - GrTilingPattern::~GrTilingPattern() - { - m_oResources.Free(); - m_oContentStream.Free(); - } - - GrPattern *GrTilingPattern::Copy() - { - return new GrTilingPattern(m_nPaintType, m_nTilingType, m_arrBBox, m_dXStep, m_dYStep, &m_oResources, m_arrMatrix, &m_oContentStream); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrShadingPattern - //------------------------------------------------------------------------------------------------------------------------------- - - GrShadingPattern *GrShadingPattern::Parse(Object *pPatternObject) - { - if (!pPatternObject->IsDict()) - { - return NULL; - } - Dict *pDict = pPatternObject->GetDict(); - - Object oDictItem; - pDict->Search("Shading", &oDictItem); - GrShading *pShading = GrShading::Parse(&oDictItem); - oDictItem.Free(); - - if (!pShading) - { - return NULL; - } - - double arrMatrix[6] ={ 1, 0, 0, 1, 0, 0 }; - if (pDict->Search("Matrix", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 6) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - Object oTemp; - if (oDictItem.ArrayGet(nIndex, &oTemp)->IsNum()) - { - arrMatrix[nIndex] = oTemp.GetNum(); - } - oTemp.Free(); - } - } - oDictItem.Free(); - - // TO DO: Надо сделать чтение поля ExtGState - - return new GrShadingPattern(pShading, arrMatrix); - } - - GrShadingPattern::GrShadingPattern(GrShading *pShading, double *pMatrix) : - GrPattern(2) - { - m_pShading = pShading; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrMatrix[nIndex] = pMatrix[nIndex]; - } - } - - GrShadingPattern::~GrShadingPattern() - { - delete m_pShading; - } - - GrPattern *GrShadingPattern::Copy() - { - return new GrShadingPattern(m_pShading->Copy(), m_arrMatrix); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrShading::GrShading(int nType) - { - m_nType = nType; - m_pColorSpace = NULL; - } - - GrShading::GrShading(GrShading *pShading) - { - m_nType = pShading->m_nType; - m_pColorSpace = pShading->m_pColorSpace->Copy(); - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - m_oBackground.arrComp[nIndex] = pShading->m_oBackground.arrComp[nIndex]; - } - m_bHasBackground = pShading->m_bHasBackground; - m_dXMin = pShading->m_dXMin; - m_dYMin = pShading->m_dYMin; - m_dXMax = pShading->m_dXMax; - m_dYMax = pShading->m_dYMax; - m_bHasBBox = pShading->m_bHasBBox; - } - - GrShading::~GrShading() - { - if (m_pColorSpace) - { - delete m_pColorSpace; - } - } - - GrShading *GrShading::Parse(Object *pObject) - { - GrShading *pShading = NULL; - - Dict *pDict = NULL; - if (pObject->IsDict()) - { - pDict = pObject->GetDict(); - } - else if (pObject->IsStream()) - { - pDict = pObject->StreamGetDict(); - } - else - { - return NULL; - } - - Object oDictItem; - if (!pDict->Search("ShadingType", &oDictItem)->IsInt()) - { - // TO DO: Error "Invalid ShadingType in shading dictionary" - oDictItem.Free(); - return NULL; - } - int nType = oDictItem.GetInt(); - oDictItem.Free(); - - switch (nType) - { - case 1: - pShading = GrFunctionShading::Parse(pDict); - break; - case 2: - pShading = GrAxialShading::Parse(pDict); - break; - case 3: - pShading = GrRadialShading::Parse(pDict); - break; - case 4: - if (pObject->IsStream()) - { - pShading = GrGouraudTriangleShading::Parse(4, pDict, pObject->GetStream()); - } - else - { - // TO DO: Error "Invalid Type 4 shading object" - return NULL; - } - break; - case 5: - if (pObject->IsStream()) - { - pShading = GrGouraudTriangleShading::Parse(5, pDict, pObject->GetStream()); - } - else - { - // TO DO: Error "Invalid Type 5 shading object" - return NULL; - } - break; - case 6: - if (pObject->IsStream()) - { - pShading = GrPatchMeshShading::Parse(6, pDict, pObject->GetStream()); - } - else - { - // TO DO: Error "Invalid Type 6 shading object" - return NULL; - } - break; - case 7: - if (pObject->IsStream()) - { - pShading = GrPatchMeshShading::Parse(7, pDict, pObject->GetStream()); - } - else - { - // TO DO: Error "Invalid Type 7 shading object" - return NULL; - } - break; - default: - // TO DO: Error "Unimplemented shading type" - return NULL; - } - - // TO DO: Добавить чтение поля AntiAlias - - return pShading; - } - - bool GrShading::Initialize(Dict *pDict) - { - Object oDictItem; - pDict->Search("ColorSpace", &oDictItem); - if (!(m_pColorSpace = GrColorSpace::Parse(&oDictItem))) - { - // TO DO: Error "Bad color space in shading dictionary" - oDictItem.Free(); - return false; - } - oDictItem.Free(); - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - m_oBackground.arrComp[nIndex] = 0; - } - m_bHasBackground = false; - - if (pDict->Search("Background", &oDictItem)->IsArray()) - { - if (oDictItem.ArrayGetLength() == m_pColorSpace->GetComponentsCount()) - { - m_bHasBackground = true; - for (int nIndex = 0; nIndex < m_pColorSpace->GetComponentsCount(); ++nIndex) - { - Object oTemp; - m_oBackground.arrComp[nIndex] = DoubleToColor(oDictItem.ArrayGet(nIndex, &oTemp)->GetNum()); - oTemp.Free(); - } - } - else - { - // TO DO: Error "Bad Background in shading dictionary" - } - } - oDictItem.Free(); - - m_dXMin = m_dYMin = m_dXMax = m_dYMax = 0; - m_bHasBBox = false; - if (pDict->Search("BBox", &oDictItem)->IsArray()) - { - if (oDictItem.ArrayGetLength() == 4) - { - Object oTemp; - m_bHasBBox = true; - m_dXMin = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - - m_dYMin = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - - m_dXMax = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - - m_dYMax = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - } - else - { - // TO DO: Error "Bad BBox in shading dictionary" - } - } - oDictItem.Free(); - - // TO DO: Добавить чтение поля AntiAlias - - return true; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrFunctionShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrFunctionShading::GrFunctionShading(double dMinX, double dMinY, double dMaxX, double dMaxY, double *pMatrix, Function **ppFunctions, int nFuncsCount) : - GrShading(1) - { - m_dDomainMinX = dMinX; - m_dDomainMinY = dMinY; - m_dDomainMaxX = dMaxX; - m_dDomainMaxY = dMaxY; - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrMatrix[nIndex] = pMatrix[nIndex]; - } - m_nFunctionsCount = nFuncsCount; - - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = ppFunctions[nIndex]; - } - } - - GrFunctionShading::GrFunctionShading(GrFunctionShading *pShading) : - GrShading(pShading) - { - m_dDomainMinX = pShading->m_dDomainMinX; - m_dDomainMinY = pShading->m_dDomainMinY; - m_dDomainMaxX = pShading->m_dDomainMaxX; - m_dDomainMaxY = pShading->m_dDomainMaxY; - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrMatrix[nIndex] = pShading->m_arrMatrix[nIndex]; - } - m_nFunctionsCount = pShading->m_nFunctionsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = pShading->m_arrFunctions[nIndex]->Copy(); - } - } - - GrFunctionShading::~GrFunctionShading() - { - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - if (m_arrFunctions[nIndex]) - delete m_arrFunctions[nIndex]; - } - } - - GrFunctionShading *GrFunctionShading::Parse(Dict *pDict) - { - Function *arrFunctions[GrColorMaxComps]; - - double dMinX = 0, dMinY = 0; - double dMaxX = 1, dMaxY = 1; - Object oDictItem; - if (pDict->Search("Domain", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4) - { - Object oTemp; - dMinX = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - // TO DO: Проверить здесь чтение(было не по спецификации) - dMaxX = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - dMinY = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - dMaxY = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - double arrMatrix[6] ={ 1, 0, 0, 1, 0, 0 }; - if (pDict->Search("Matrix", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 6) - { - Object oTemp; - arrMatrix[0] = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - arrMatrix[1] = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - arrMatrix[2] = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - arrMatrix[3] = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - arrMatrix[4] = oDictItem.ArrayGet(4, &oTemp)->GetNum(); - oTemp.Free(); - arrMatrix[5] = oDictItem.ArrayGet(5, &oTemp)->GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - pDict->Search("Function", &oDictItem); - int nFuncsCount = 0; - if (oDictItem.IsArray()) - { - nFuncsCount = oDictItem.ArrayGetLength(); - if (nFuncsCount > GrColorMaxComps) - { - // TO DO: Error "Invalid Function array in shading dictionary" - oDictItem.Free(); - return NULL; - } - for (int nIndex = 0; nIndex < nFuncsCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - if (!(arrFunctions[nIndex] = Function::Parse(&oTemp))) - { - oTemp.Free(); - oDictItem.Free(); - return NULL; - } - oTemp.Free(); - } - } - else - { - nFuncsCount = 1; - if (!(arrFunctions[0] = Function::Parse(&oDictItem))) - { - oDictItem.Free(); - return NULL; - } - } - oDictItem.Free(); - - GrFunctionShading *pShading = new GrFunctionShading(dMinX, dMinY, dMaxX, dMaxY, arrMatrix, arrFunctions, nFuncsCount); - if (!pShading->Initialize(pDict)) - { - delete pShading; - return NULL; - } - return pShading; - } - - GrShading *GrFunctionShading::Copy() - { - return new GrFunctionShading(this); - } - - void GrFunctionShading::GetColor(double dX, double dY, GrColor *pColor) - { - double arrInput[2], arrOutput[GrColorMaxComps]; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - arrOutput[nIndex] = 0; - } - arrInput[0] = dX; - arrInput[1] = dY; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex]->Transform(arrInput, &arrOutput[nIndex]); - } - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - pColor->arrComp[nIndex] = DoubleToColor(arrOutput[nIndex]); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrAxialShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrAxialShading::GrAxialShading(double dX0, double dY0, double dX1, double dY1, double dT0, double dT1, Function **ppFunctions, int nFuncsCount, bool bExtendStart, bool bExtendEnd) : - GrShading(2) - { - m_dAxisX0 = dX0; - m_dAxisY0 = dY0; - m_dAxisX1 = dX1; - m_dAxisY1 = dY1; - m_dT0 = dT0; - m_dT1 = dT1; - m_nFunctionsCount = nFuncsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = ppFunctions[nIndex]; - } - m_bExtendStart = bExtendStart; - m_bExtendEnd = bExtendEnd; - } - - GrAxialShading::GrAxialShading(GrAxialShading *pShading) : - GrShading(pShading) - { - m_dAxisX0 = pShading->m_dAxisX0; - m_dAxisY0 = pShading->m_dAxisY0; - m_dAxisX1 = pShading->m_dAxisX1; - m_dAxisY1 = pShading->m_dAxisY1; - m_dT0 = pShading->m_dT0; - m_dT1 = pShading->m_dT1; - m_nFunctionsCount = pShading->m_nFunctionsCount; - - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = pShading->m_arrFunctions[nIndex]->Copy(); - } - m_bExtendStart = pShading->m_bExtendStart; - m_bExtendEnd = pShading->m_bExtendEnd; - } - - GrAxialShading::~GrAxialShading() - { - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - delete m_arrFunctions[nIndex]; - } - } - - GrAxialShading *GrAxialShading::Parse(Dict *pDict) - { - Function *arrFunctions[GrColorMaxComps]; - - double dX0 = 0, dY0 = 0, dX1 = 0, dY1 = 0; - Object oDictItem; - if (pDict->Search("Coords", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 4) - { - Object oTemp; - dX0 = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dY0 = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - dX1 = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - dY1 = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - } - else - { - // TO DO: Error "Missing or invalid Coords in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - double dT0 = 0, dT1 = 1; - if (pDict->Search("Domain", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2) - { - Object oTemp; - dT0 = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dT1 = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - pDict->Search("Function", &oDictItem); - int nFuncsCount = 0; - if (oDictItem.IsArray()) - { - nFuncsCount = oDictItem.ArrayGetLength(); - if (nFuncsCount > GrColorMaxComps) - { - // TO DO: Error "Invalid Function array in shading dictionary" - oDictItem.Free(); - return NULL; - } - for (int nIndex = 0; nIndex < nFuncsCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - if (!(arrFunctions[nIndex] = Function::Parse(&oTemp))) - { - oDictItem.Free(); - oTemp.Free(); - return NULL; - } - oTemp.Free(); - } - } - else - { - nFuncsCount = 1; - if (!(arrFunctions[0] = Function::Parse(&oDictItem))) - { - oDictItem.Free(); - return NULL; - } - } - oDictItem.Free(); - - bool bExtendStart = false, bExtendEnd = false; - if (pDict->Search("Extend", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2) - { - Object oTemp; - bExtendStart = oDictItem.ArrayGet(0, &oTemp)->GetBool(); - oTemp.Free(); - bExtendEnd = oDictItem.ArrayGet(1, &oTemp)->GetBool(); - oTemp.Free(); - } - oDictItem.Free(); - - GrAxialShading *pShading = new GrAxialShading(dX0, dY0, dX1, dY1, dT0, dT1, arrFunctions, nFuncsCount, bExtendStart, bExtendEnd); - if (!pShading->Initialize(pDict)) - { - delete pShading; - return NULL; - } - return pShading; - } - - GrShading *GrAxialShading::Copy() - { - return new GrAxialShading(this); - } - - void GrAxialShading::GetColor(double dT, GrColor *pColor) - { - double arrOutput[GrColorMaxComps]; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - arrOutput[nIndex] = 0; - } - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex]->Transform(&dT, &arrOutput[nIndex]); - } - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - pColor->arrComp[nIndex] = DoubleToColor(arrOutput[nIndex]); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrRadialShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrRadialShading::GrRadialShading(double dFirstX, double dFirstY, double dFirstRad, double dSecondX, double dSecondY, double dSecondRad, double dT0, double dT1, Function **ppFunctions, int nFuncsCount, bool bExtendFirst, bool bExtendSecond) : - GrShading(3) - { - m_dFirstX = dFirstX; - m_dFirstY = dFirstY; - m_dFirstRad = dFirstRad; - m_dSecondX = dSecondX; - m_dSecondY = dSecondY; - m_dSecondRad = dSecondRad; - m_dT0 = dT0; - m_dT1 = dT1; - m_nFunctionsCount = nFuncsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = ppFunctions[nIndex]; - } - m_bExtendFirst = bExtendFirst; - m_bExtendSecond = bExtendSecond; - } - - GrRadialShading::GrRadialShading(GrRadialShading *pShading) : - GrShading(pShading) - { - m_dFirstX = pShading->m_dFirstX; - m_dFirstY = pShading->m_dFirstY; - m_dFirstRad = pShading->m_dFirstRad; - m_dSecondX = pShading->m_dSecondX; - m_dSecondY = pShading->m_dSecondY; - m_dSecondRad = pShading->m_dSecondRad; - m_dT0 = pShading->m_dT0; - m_dT1 = pShading->m_dT1; - m_nFunctionsCount = pShading->m_nFunctionsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex] = pShading->m_arrFunctions[nIndex]->Copy(); - } - m_bExtendFirst = pShading->m_bExtendFirst; - m_bExtendSecond = pShading->m_bExtendSecond; - } - - GrRadialShading::~GrRadialShading() - { - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - if (m_arrFunctions[nIndex]) - delete m_arrFunctions[nIndex]; - } - } - - GrRadialShading *GrRadialShading::Parse(Dict *pDict) - { - Function *arrFunctions[GrColorMaxComps]; - - Object oDictItem; - double dFirstX = 0, dFirstY = 0, dFirstRad = 0, dSecondX = 0, dSecondY = 0, dSecondRad = 0; - if (pDict->Search("Coords", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 6) - { - Object oTemp; - dFirstX = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dFirstY = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - dFirstRad = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - dSecondX = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - dSecondY = oDictItem.ArrayGet(4, &oTemp)->GetNum(); - oTemp.Free(); - dSecondRad = oDictItem.ArrayGet(5, &oTemp)->GetNum(); - oTemp.Free(); - } - else - { - // TO DO: Error "Missing or invalid Coords in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - double dT0 = 0, dT1 = 1; - if (pDict->Search("Domain", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2) - { - Object oTemp; - dT0 = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dT1 = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - pDict->Search("Function", &oDictItem); - int nFuncsCount = 0; - if (oDictItem.IsArray()) - { - nFuncsCount = oDictItem.ArrayGetLength(); - if (nFuncsCount > GrColorMaxComps) - { - // TO DO: Error "Invalid Function array in shading dictionary" - oDictItem.Free(); - return NULL; - } - for (int nIndex = 0; nIndex < nFuncsCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - if (!(arrFunctions[nIndex] = Function::Parse(&oTemp))) - { - oDictItem.Free(); - oTemp.Free(); - return NULL; - } - oTemp.Free(); - } - } - else - { - nFuncsCount = 1; - if (!(arrFunctions[0] = Function::Parse(&oDictItem))) - { - oDictItem.Free(); - return NULL; - } - } - oDictItem.Free(); - - bool bExtendFirst = false, bExtendSecond = false; - if (pDict->Search("Extend", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() == 2) - { - Object oTemp; - bExtendFirst = oDictItem.ArrayGet(0, &oTemp)->GetBool(); - oTemp.Free(); - bExtendSecond = oDictItem.ArrayGet(1, &oTemp)->GetBool(); - oTemp.Free(); - } - oDictItem.Free(); - - GrRadialShading *pShading = new GrRadialShading(dFirstX, dFirstY, dFirstRad, dSecondX, dSecondY, dSecondRad, dT0, dT1, arrFunctions, nFuncsCount, bExtendFirst, bExtendSecond); - if (!pShading->Initialize(pDict)) - { - delete pShading; - return NULL; - } - return pShading; - } - - GrShading *GrRadialShading::Copy() - { - return new GrRadialShading(this); - } - - void GrRadialShading::GetColor(double dT, GrColor *pColor) - { - double arrOutput[GrColorMaxComps]; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - arrOutput[nIndex] = 0; - } - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_arrFunctions[nIndex]->Transform(&dT, &arrOutput[nIndex]); - } - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - pColor->arrComp[nIndex] = DoubleToColor(arrOutput[nIndex]); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrShadingBitBuffer - //------------------------------------------------------------------------------------------------------------------------------- - - class GrShadingBitBuffer - { - public: - - GrShadingBitBuffer(Stream *pStream) - { - m_pStream = pStream; - m_pStream->Reset(); - m_nBitBuffer = 0; - m_nBitsCount = 0; - } - ~GrShadingBitBuffer() - { - m_pStream->Close(); - } - bool GetBits(int nCount, unsigned int *pValue) - { - int nResult = 0; - - if (m_nBitsCount >= nCount) - { - nResult = (m_nBitBuffer >> (m_nBitsCount - nCount)) & ((1 << nCount) - 1); - m_nBitsCount -= nCount; - } - else - { - nResult = 0; - if (m_nBitsCount > 0) - { - nResult = m_nBitBuffer & ((1 << m_nBitsCount) - 1); - nCount -= m_nBitsCount; - m_nBitsCount = 0; - } - while (nCount > 0) - { - if ((m_nBitBuffer = m_pStream->GetChar()) == EOF) - { - m_nBitsCount = 0; - return false; - } - if (nCount >= 8) - { - nResult = (nResult << 8) | m_nBitBuffer; - nCount -= 8; - } - else - { - nResult = (nResult << nCount) | (m_nBitBuffer >> (8 - nCount)); - m_nBitsCount = 8 - nCount; - nCount = 0; - } - } - } - *pValue = nResult; - return true; - } - - void FlushBits() - { - m_nBitBuffer = 0; - m_nBitsCount = 0; - } - - private: - - Stream *m_pStream; - int m_nBitBuffer; - int m_nBitsCount; - }; - //------------------------------------------------------------------------------------------------------------------------------- - // GrGouraudTriangleShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrGouraudTriangleShading::GrGouraudTriangleShading(int nType, GrGouraudVertex *pVertexes, int nVertexesCount, int(*pTriangles)[3], int nTrianglesCount, Function **ppFunctions, int nFunctionsCount) : - GrShading(nType) - { - m_arrVertexs = pVertexes; - m_nVertexsCount = nVertexesCount; - m_arrTriangles = pTriangles; - m_nTrianglesCount = nTrianglesCount; - m_nFunctionsCount = nFunctionsCount; - - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_ppFunctions[nIndex] = ppFunctions[nIndex]; - } - } - - GrGouraudTriangleShading::GrGouraudTriangleShading(GrGouraudTriangleShading *pShading) : - GrShading(pShading) - { - m_nVertexsCount = pShading->m_nVertexsCount; - m_arrVertexs = (GrGouraudVertex *)MemUtilsMallocArray(m_nVertexsCount, sizeof(GrGouraudVertex)); - memcpy(m_arrVertexs, pShading->m_arrVertexs, m_nVertexsCount * sizeof(GrGouraudVertex)); - - m_nTrianglesCount = pShading->m_nTrianglesCount; - m_arrTriangles = (int(*)[3])MemUtilsMallocArray(m_nTrianglesCount * 3, sizeof(int)); - memcpy(m_arrTriangles, pShading->m_arrTriangles, m_nTrianglesCount * 3 * sizeof(int)); - - m_nFunctionsCount = pShading->m_nFunctionsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_ppFunctions[nIndex] = pShading->m_ppFunctions[nIndex]->Copy(); - } - } - - GrGouraudTriangleShading::~GrGouraudTriangleShading() - { - MemUtilsFree(m_arrVertexs); - MemUtilsFree(m_arrTriangles); - - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - if (m_ppFunctions[nIndex]) - delete m_ppFunctions[nIndex]; - } - } - - GrGouraudTriangleShading *GrGouraudTriangleShading::Parse(int nType, Dict *pDict, Stream *pStream) - { - int nBitsPerCoordinate = 0, nBitsPerComponent = 0; - - int nIndex = 0; - - Object oDictItem; - if (pDict->Search("BitsPerCoordinate", &oDictItem)->IsInt()) - { - nBitsPerCoordinate = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerCoordinate in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - if (pDict->Search("BitsPerComponent", &oDictItem)->IsInt()) - { - nBitsPerComponent = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerComponent in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - int nBitsPerFlag = 0, nVerticesPerRow = 0; - if (nType == 4) - { - if (pDict->Search("BitsPerFlag", &oDictItem)->IsInt()) - { - nBitsPerFlag = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerFlag in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - } - else - { - if (pDict->Search("VerticesPerRow", &oDictItem)->IsInt()) - { - nVerticesPerRow = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid VerticesPerRow in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - } - - // [ Xmin Xmax Ymin Ymax C1,min C1,max ... Cn,min Cn,max ], поэтому как минимум массив должен быть из 6 элементов - double dXMin, dXMax, dYMin, dYMax; - double arrCMin[GrColorMaxComps], arrCMax[GrColorMaxComps]; - double dXMul, dYMul; - double arrCMul[GrColorMaxComps]; - int nComponentsCount = 0; - if (pDict->Search("Decode", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() >= 6) - { - Object oTemp; - dXMin = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dXMax = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - dXMul = (dXMax - dXMin) / (pow(2.0, nBitsPerCoordinate) - 1); - dYMin = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - dYMax = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - dYMul = (dYMax - dYMin) / (pow(2.0, nBitsPerCoordinate) - 1); - - for (nIndex = 0; 5 + 2 * nIndex < oDictItem.ArrayGetLength() && nIndex < GrColorMaxComps; ++nIndex) - { - arrCMin[nIndex] = oDictItem.ArrayGet(4 + 2 * nIndex, &oTemp)->GetNum(); - oTemp.Free(); - arrCMax[nIndex] = oDictItem.ArrayGet(5 + 2 * nIndex, &oTemp)->GetNum(); - oTemp.Free(); - arrCMul[nIndex] = (arrCMax[nIndex] - arrCMin[nIndex]) / (double)((1 << nBitsPerComponent) - 1); - } - nComponentsCount = nIndex; - } - else - { - // TO DO: Error "Missing or invalid Decode array in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - int nFunctionsCount = 0; - Function *ppFunctions[GrColorMaxComps]; - if (!pDict->Search("Function", &oDictItem)->IsNull()) - { - if (oDictItem.IsArray()) - { - nFunctionsCount = oDictItem.ArrayGetLength(); - if (nFunctionsCount > GrColorMaxComps) - { - // TO DO: Error "Invalid Function array in shading dictionary" - oDictItem.Free(); - return NULL; - } - for (int nIndex = 0; nIndex < nFunctionsCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - if (!(ppFunctions[nIndex] = Function::Parse(&oTemp))) - { - oDictItem.Free(); - oTemp.Free(); - return NULL; - } - oTemp.Free(); - } - } - else - { - nFunctionsCount = 1; - if (!(ppFunctions[0] = Function::Parse(&oDictItem))) - { - oDictItem.Free(); - return NULL; - } - } - } - else - { - nFunctionsCount = 0; - } - oDictItem.Free(); - - // Дальше читаем данные из потока(набор вершин) - int nVerticesCount = 0, nTrianglesCount = 0; - GrGouraudVertex *pVertices = NULL; - int(*pTriangles)[3] = NULL; - int nVertSize = 0, nTriSize = 0; - int nState = 0; - unsigned int unFlag = 0, unX = 0, unY = 0; - unsigned int arrunC[GrColorMaxComps]; - GrShadingBitBuffer *pBitBuffer = new GrShadingBitBuffer(pStream); - if (NULL == pBitBuffer) - return NULL; - - while (1) - { - if (nType == 4) // В типе 5 нет флага вначале - { - if (!pBitBuffer->GetBits(nBitsPerFlag, &unFlag)) - { - break; - } - } - if (!pBitBuffer->GetBits(nBitsPerCoordinate, &unX) || !pBitBuffer->GetBits(nBitsPerCoordinate, &unY)) - { - break; - } - for (nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - if (!pBitBuffer->GetBits(nBitsPerComponent, &arrunC[nIndex])) - { - break; - } - } - if (nIndex < nComponentsCount) - { - break; - } - if (nVerticesCount == nVertSize) - { - nVertSize = (nVertSize == 0) ? 16 : 2 * nVertSize; - pVertices = (GrGouraudVertex *)MemUtilsReallocArray(pVertices, nVertSize, sizeof(GrGouraudVertex)); - } - pVertices[nVerticesCount].dX = dXMin + dXMul * (double)unX; - pVertices[nVerticesCount].dY = dYMin + dYMul * (double)unY; - - for (int nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - pVertices[nVerticesCount].oColor.arrComp[nIndex] = DoubleToColor(arrCMin[nIndex] + arrCMul[nIndex] * (double)arrunC[nIndex]); - } - ++nVerticesCount; - - pBitBuffer->FlushBits(); - if (nType == 4) - { - if (nState == 0 || nState == 1) - { - ++nState; - } - else if (nState == 2 || unFlag > 0) - { - if (nTrianglesCount == nTriSize) - { - nTriSize = (nTriSize == 0) ? 16 : 2 * nTriSize; - pTriangles = (int(*)[3]) MemUtilsReallocArray(pTriangles, nTriSize * 3, sizeof(int)); - } - if (nState == 2) - { - pTriangles[nTrianglesCount][0] = nVerticesCount - 3; - pTriangles[nTrianglesCount][1] = nVerticesCount - 2; - pTriangles[nTrianglesCount][2] = nVerticesCount - 1; - ++nState; - } - else if (unFlag == 1) - { - pTriangles[nTrianglesCount][0] = pTriangles[nTrianglesCount - 1][1]; - pTriangles[nTrianglesCount][1] = pTriangles[nTrianglesCount - 1][2]; - pTriangles[nTrianglesCount][2] = nVerticesCount - 1; - } - else // unFlag == 2 - { - pTriangles[nTrianglesCount][0] = pTriangles[nTrianglesCount - 1][0]; - pTriangles[nTrianglesCount][1] = pTriangles[nTrianglesCount - 1][2]; - pTriangles[nTrianglesCount][2] = nVerticesCount - 1; - } - ++nTrianglesCount; - } - else // nState == 3 && unFlag == 0 - { - nState = 1; - } - } - } - delete pBitBuffer; - if (nType == 5) - { - int nRowsCount = nVerticesCount / nVerticesPerRow; - nTrianglesCount = (nRowsCount - 1) * 2 * (nVerticesPerRow - 1); - pTriangles = (int(*)[3])MemUtilsMallocArray(nTrianglesCount * 3, sizeof(int)); - int nTriangleIndex = 0; - for (int nRowIndex = 0; nRowIndex < nRowsCount - 1; ++nRowIndex) - { - for (int nVertIndex = 0; nVertIndex < nVerticesPerRow - 1; ++nVertIndex) - { - pTriangles[nTriangleIndex][0] = nRowIndex * nVerticesPerRow + nVertIndex; - pTriangles[nTriangleIndex][1] = nRowIndex * nVerticesPerRow + nVertIndex + 1; - pTriangles[nTriangleIndex][2] = (nRowIndex + 1) * nVerticesPerRow + nVertIndex; - ++nTriangleIndex; - pTriangles[nTriangleIndex][0] = nRowIndex * nVerticesPerRow + nVertIndex + 1; - pTriangles[nTriangleIndex][1] = (nRowIndex + 1) * nVerticesPerRow + nVertIndex; - pTriangles[nTriangleIndex][2] = (nRowIndex + 1) * nVerticesPerRow + nVertIndex + 1; - ++nTriangleIndex; - } - } - } - - GrGouraudTriangleShading *pShading = new GrGouraudTriangleShading(nType, pVertices, nVerticesCount, pTriangles, nTrianglesCount, ppFunctions, nFunctionsCount); - if (!pShading) - return NULL; - if (!pShading->Initialize(pDict)) - { - delete pShading; - return NULL; - } - return pShading; - } - - GrShading *GrGouraudTriangleShading::Copy() - { - return new GrGouraudTriangleShading(this); - } - - void GrGouraudTriangleShading::GetTriangle(int nIndex, double *pdX0, double *pdY0, GrColor *pColor0, double *pdX1, double *pdY1, GrColor *pColor1, double *pdX2, double *pdY2, GrColor *pColor2) - { - double dIn = 0; - double arrOut[GrColorMaxComps]; - int nVertexIndex; - - nVertexIndex = m_arrTriangles[nIndex][0]; - *pdX0 = m_arrVertexs[nVertexIndex].dX; - *pdY0 = m_arrVertexs[nVertexIndex].dY; - if (m_nFunctionsCount > 0) - { - dIn = ColorToDouble(m_arrVertexs[nVertexIndex].oColor.arrComp[0]); - for (int nJ = 0; nJ < m_nFunctionsCount; ++nJ) - { - m_ppFunctions[nJ]->Transform(&dIn, &arrOut[nJ]); - } - for (int nJ = 0; nJ < GrColorMaxComps; ++nJ) - { - pColor0->arrComp[nJ] = DoubleToColor(arrOut[nJ]); - } - } - else - { - *pColor0 = m_arrVertexs[nVertexIndex].oColor; - } - - nVertexIndex = m_arrTriangles[nIndex][1]; - *pdX1 = m_arrVertexs[nVertexIndex].dX; - *pdY1 = m_arrVertexs[nVertexIndex].dY; - if (m_nFunctionsCount > 0) - { - dIn = ColorToDouble(m_arrVertexs[nVertexIndex].oColor.arrComp[0]); - for (int nJ = 0; nJ < m_nFunctionsCount; ++nJ) - { - m_ppFunctions[nJ]->Transform(&dIn, &arrOut[nJ]); - } - for (int nJ = 0; nJ < GrColorMaxComps; ++nJ) - { - pColor1->arrComp[nJ] = DoubleToColor(arrOut[nJ]); - } - } - else - { - *pColor1 = m_arrVertexs[nVertexIndex].oColor; - } - - nVertexIndex = m_arrTriangles[nIndex][2]; - *pdX2 = m_arrVertexs[nVertexIndex].dX; - *pdY2 = m_arrVertexs[nVertexIndex].dY; - if (m_nFunctionsCount > 0) - { - dIn = ColorToDouble(m_arrVertexs[nVertexIndex].oColor.arrComp[0]); - for (int nJ = 0; nJ < m_nFunctionsCount; ++nJ) - { - m_ppFunctions[nJ]->Transform(&dIn, &arrOut[nJ]); - } - for (int nJ = 0; nJ < GrColorMaxComps; ++nJ) - { - pColor2->arrComp[nJ] = DoubleToColor(arrOut[nJ]); - } - } - else - { - *pColor2 = m_arrVertexs[nVertexIndex].oColor; - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPatchMeshShading - //------------------------------------------------------------------------------------------------------------------------------- - - GrPatchMeshShading::GrPatchMeshShading(int nType, GrPatch *pPatches, int nPatchesCount, Function **ppFunctions, int nFunctionsCount) : - GrShading(nType) - { - m_pPatches = pPatches; - m_nPatchesCount = nPatchesCount; - m_nFunctionsCount = nFunctionsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_ppFunctions[nIndex] = ppFunctions[nIndex]; - } - } - - GrPatchMeshShading::GrPatchMeshShading(GrPatchMeshShading *pShading) : - GrShading(pShading) - { - m_nPatchesCount = pShading->m_nPatchesCount; - m_pPatches = (GrPatch *)MemUtilsMallocArray(m_nPatchesCount, sizeof(GrPatch)); - memcpy(m_pPatches, pShading->m_pPatches, m_nPatchesCount * sizeof(GrPatch)); - - m_nFunctionsCount = pShading->m_nFunctionsCount; - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - m_ppFunctions[nIndex] = pShading->m_ppFunctions[nIndex]->Copy(); - } - } - - GrPatchMeshShading::~GrPatchMeshShading() - { - MemUtilsFree(m_pPatches); - for (int nIndex = 0; nIndex < m_nFunctionsCount; ++nIndex) - { - if (m_ppFunctions[nIndex]) - delete m_ppFunctions[nIndex]; - } - } - - GrPatchMeshShading *GrPatchMeshShading::Parse(int nType, Dict *pDict, Stream *pStream) - { - int nBitsPerCoordinate = 0, nBitsPerComponent = 0, nBitsPerFlag = 0; - int nIndex = 0; - - Object oDictItem; - if (pDict->Search("BitsPerCoordinate", &oDictItem)->IsInt()) - { - nBitsPerCoordinate = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerCoordinate in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - if (pDict->Search("BitsPerComponent", &oDictItem)->IsInt()) - { - nBitsPerComponent = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerComponent in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - if (pDict->Search("BitsPerFlag", &oDictItem)->IsInt()) - { - nBitsPerFlag = oDictItem.GetInt(); - } - else - { - // TO DO: Error "Missing or invalid BitsPerFlag in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - double dXMin, dXMax, dYMin, dYMax; - double arrCMin[GrColorMaxComps], arrCMax[GrColorMaxComps]; - double dXMul, dYMul; - double arrCMul[GrColorMaxComps]; - int nComponentsCount = 0; - - // [ Xmin Xmax Ymin Ymax C1,min C1,max ... Cn,min Cn,max ], поэтому как минимум массив должен быть из 6 элементов - if (pDict->Search("Decode", &oDictItem)->IsArray() && oDictItem.ArrayGetLength() >= 6) - { - Object oTemp; - dXMin = oDictItem.ArrayGet(0, &oTemp)->GetNum(); - oTemp.Free(); - dXMax = oDictItem.ArrayGet(1, &oTemp)->GetNum(); - oTemp.Free(); - dXMul = (dXMax - dXMin) / (pow(2.0, nBitsPerCoordinate) - 1); - dYMin = oDictItem.ArrayGet(2, &oTemp)->GetNum(); - oTemp.Free(); - dYMax = oDictItem.ArrayGet(3, &oTemp)->GetNum(); - oTemp.Free(); - dYMul = (dYMax - dYMin) / (pow(2.0, nBitsPerCoordinate) - 1); - for (nIndex = 0; 5 + 2 * nIndex < oDictItem.ArrayGetLength() && nIndex < GrColorMaxComps; ++nIndex) - { - arrCMin[nIndex] = oDictItem.ArrayGet(4 + 2 * nIndex, &oTemp)->GetNum(); - oTemp.Free(); - arrCMax[nIndex] = oDictItem.ArrayGet(5 + 2 * nIndex, &oTemp)->GetNum(); - oTemp.Free(); - arrCMul[nIndex] = (arrCMax[nIndex] - arrCMin[nIndex]) / (double)((1 << nBitsPerComponent) - 1); - } - nComponentsCount = nIndex; - } - else - { - // TO DO: Error "Missing or invalid Decode array in shading dictionary" - oDictItem.Free(); - return NULL; - } - oDictItem.Free(); - - int nFunctionsCount = 0; - Function *ppFunctions[GrColorMaxComps]; - if (!pDict->Search("Function", &oDictItem)->IsNull()) - { - if (oDictItem.IsArray()) - { - nFunctionsCount = oDictItem.ArrayGetLength(); - if (nFunctionsCount > GrColorMaxComps) - { - // TO DO: Error "Invalid Function array in shading dictionary" - oDictItem.Free(); - return NULL; - } - for (nIndex = 0; nIndex < nFunctionsCount; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - if (!(ppFunctions[nIndex] = Function::Parse(&oTemp))) - { - oDictItem.Free(); - oTemp.Free(); - return NULL; - } - oDictItem.Free(); - } - } - else - { - nFunctionsCount = 1; - if (!(ppFunctions[0] = Function::Parse(&oDictItem))) - { - oDictItem.Free(); - return NULL; - } - } - } - else - { - nFunctionsCount = 0; - } - oDictItem.Free(); - - int nPatchesCount = 0, nPatchesSize = 0; - GrPatch *pPatches = NULL; - GrShadingBitBuffer *pBitBuffer = new GrShadingBitBuffer(pStream); - - double arrX[16], arrY[16]; - GrColorComp arrC[4][GrColorMaxComps]; - - while (1) - { - unsigned int unFlag = 0; - int nPointsCount = 0, nColorsCount = 0; - if (!pBitBuffer->GetBits(nBitsPerFlag, &unFlag)) - { - break; - } - if (nType == 6) - { - switch (unFlag) - { - case 0: nPointsCount = 12; nColorsCount = 4; break; - case 1: - case 2: - case 3: - default: nPointsCount = 8; nColorsCount = 2; break; - } - } - else - { - switch (unFlag) - { - case 0: nPointsCount = 16; nColorsCount = 4; break; - case 1: - case 2: - case 3: - default: nPointsCount = 12; nColorsCount = 2; break; - } - } - for (nIndex = 0; nIndex < nPointsCount; ++nIndex) - { - unsigned int unX = 0, unY = 0; - if (!pBitBuffer->GetBits(nBitsPerCoordinate, &unX) || !pBitBuffer->GetBits(nBitsPerCoordinate, &unY)) - { - break; - } - arrX[nIndex] = dXMin + dXMul * (double)unX; - arrY[nIndex] = dYMin + dYMul * (double)unY; - } - if (nIndex < nPointsCount) - { - break; - } - for (nIndex = 0; nIndex < nColorsCount; ++nIndex) - { - int nJ = 0; - unsigned int arrunC[4]; - for (nJ = 0; nJ < nComponentsCount; ++nJ) - { - if (!pBitBuffer->GetBits(nBitsPerComponent, &arrunC[nJ])) - { - break; - } - arrC[nIndex][nJ] = DoubleToColor(arrCMin[nJ] + arrCMul[nJ] * (double)arrunC[nJ]); - } - if (nJ < nComponentsCount) - { - break; - } - } - if (nIndex < nColorsCount) - { - break; - } - if (nPatchesCount == nPatchesSize) - { - nPatchesSize = (nPatchesSize == 0) ? 16 : 2 * nPatchesSize; - pPatches = (GrPatch *)MemUtilsReallocArray(pPatches, nPatchesSize, sizeof(GrPatch)); - } - GrPatch *pCurPatch = &pPatches[nPatchesCount]; - if (nType == 6) - { - switch (unFlag) - { - case 0: - pCurPatch->arrX[0][0] = arrX[0]; pCurPatch->arrY[0][0] = arrY[0]; - pCurPatch->arrX[0][1] = arrX[1]; pCurPatch->arrY[0][1] = arrY[1]; - pCurPatch->arrX[0][2] = arrX[2]; pCurPatch->arrY[0][2] = arrY[2]; - pCurPatch->arrX[0][3] = arrX[3]; pCurPatch->arrY[0][3] = arrY[3]; - pCurPatch->arrX[1][3] = arrX[4]; pCurPatch->arrY[1][3] = arrY[4]; - pCurPatch->arrX[2][3] = arrX[5]; pCurPatch->arrY[2][3] = arrY[5]; - pCurPatch->arrX[3][3] = arrX[6]; pCurPatch->arrY[3][3] = arrY[6]; - pCurPatch->arrX[3][2] = arrX[7]; pCurPatch->arrY[3][2] = arrY[7]; - pCurPatch->arrX[3][1] = arrX[8]; pCurPatch->arrY[3][1] = arrY[8]; - pCurPatch->arrX[3][0] = arrX[9]; pCurPatch->arrY[3][0] = arrY[9]; - pCurPatch->arrX[2][0] = arrX[10]; pCurPatch->arrY[2][0] = arrY[10]; - pCurPatch->arrX[1][0] = arrX[11]; pCurPatch->arrY[1][0] = arrY[11]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = arrC[1][nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[2][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[3][nJ]; - } - break; - case 1: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[0][3]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[0][3]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[1][3]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[1][3]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[2][3]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[2][3]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[3][3]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[3][3]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[0][1].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][1].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - case 2: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[3][3]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[3][3]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[3][2]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[3][2]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[3][1]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[3][1]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[3][0]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[3][0]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][1].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][0].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - case 3: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[3][0]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[3][0]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[2][0]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[2][0]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[1][0]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[1][0]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[0][0]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[0][0]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][0].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[0][0].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - } - } - else - { - switch (unFlag) - { - case 0: - pCurPatch->arrX[0][0] = arrX[0]; pCurPatch->arrY[0][0] = arrY[0]; - pCurPatch->arrX[0][1] = arrX[1]; pCurPatch->arrY[0][1] = arrY[1]; - pCurPatch->arrX[0][2] = arrX[2]; pCurPatch->arrY[0][2] = arrY[2]; - pCurPatch->arrX[0][3] = arrX[3]; pCurPatch->arrY[0][3] = arrY[3]; - pCurPatch->arrX[1][3] = arrX[4]; pCurPatch->arrY[1][3] = arrY[4]; - pCurPatch->arrX[2][3] = arrX[5]; pCurPatch->arrY[2][3] = arrY[5]; - pCurPatch->arrX[3][3] = arrX[6]; pCurPatch->arrY[3][3] = arrY[6]; - pCurPatch->arrX[3][2] = arrX[7]; pCurPatch->arrY[3][2] = arrY[7]; - pCurPatch->arrX[3][1] = arrX[8]; pCurPatch->arrY[3][1] = arrY[8]; - pCurPatch->arrX[3][0] = arrX[9]; pCurPatch->arrY[3][0] = arrY[9]; - pCurPatch->arrX[2][0] = arrX[10]; pCurPatch->arrY[2][0] = arrY[10]; - pCurPatch->arrX[1][0] = arrX[11]; pCurPatch->arrY[1][0] = arrY[11]; - pCurPatch->arrX[1][1] = arrX[12]; pCurPatch->arrY[1][1] = arrY[12]; - pCurPatch->arrX[1][2] = arrX[13]; pCurPatch->arrY[1][2] = arrY[13]; - pCurPatch->arrX[2][2] = arrX[14]; pCurPatch->arrY[2][2] = arrY[14]; - pCurPatch->arrX[2][1] = arrX[15]; pCurPatch->arrY[2][1] = arrY[15]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = arrC[1][nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[2][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[3][nJ]; - } - break; - case 1: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[0][3]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[0][3]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[1][3]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[1][3]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[2][3]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[2][3]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[3][3]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[3][3]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - pCurPatch->arrX[1][1] = arrX[8]; pCurPatch->arrY[1][1] = arrY[8]; - pCurPatch->arrX[1][2] = arrX[9]; pCurPatch->arrY[1][2] = arrY[9]; - pCurPatch->arrX[2][2] = arrX[10]; pCurPatch->arrY[2][2] = arrY[10]; - pCurPatch->arrX[2][1] = arrX[11]; pCurPatch->arrY[2][1] = arrY[11]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[0][1].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][1].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - case 2: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[3][3]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[3][3]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[3][2]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[3][2]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[3][1]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[3][1]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[3][0]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[3][0]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - pCurPatch->arrX[1][1] = arrX[8]; pCurPatch->arrY[1][1] = arrY[8]; - pCurPatch->arrX[1][2] = arrX[9]; pCurPatch->arrY[1][2] = arrY[9]; - pCurPatch->arrX[2][2] = arrX[10]; pCurPatch->arrY[2][2] = arrY[10]; - pCurPatch->arrX[2][1] = arrX[11]; pCurPatch->arrY[2][1] = arrY[11]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][1].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][0].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - case 3: - pCurPatch->arrX[0][0] = pPatches[nPatchesCount - 1].arrX[3][0]; pCurPatch->arrY[0][0] = pPatches[nPatchesCount - 1].arrY[3][0]; - pCurPatch->arrX[0][1] = pPatches[nPatchesCount - 1].arrX[2][0]; pCurPatch->arrY[0][1] = pPatches[nPatchesCount - 1].arrY[2][0]; - pCurPatch->arrX[0][2] = pPatches[nPatchesCount - 1].arrX[1][0]; pCurPatch->arrY[0][2] = pPatches[nPatchesCount - 1].arrY[1][0]; - pCurPatch->arrX[0][3] = pPatches[nPatchesCount - 1].arrX[0][0]; pCurPatch->arrY[0][3] = pPatches[nPatchesCount - 1].arrY[0][0]; - pCurPatch->arrX[1][3] = arrX[0]; pCurPatch->arrY[1][3] = arrY[0]; - pCurPatch->arrX[2][3] = arrX[1]; pCurPatch->arrY[2][3] = arrY[1]; - pCurPatch->arrX[3][3] = arrX[2]; pCurPatch->arrY[3][3] = arrY[2]; - pCurPatch->arrX[3][2] = arrX[3]; pCurPatch->arrY[3][2] = arrY[3]; - pCurPatch->arrX[3][1] = arrX[4]; pCurPatch->arrY[3][1] = arrY[4]; - pCurPatch->arrX[3][0] = arrX[5]; pCurPatch->arrY[3][0] = arrY[5]; - pCurPatch->arrX[2][0] = arrX[6]; pCurPatch->arrY[2][0] = arrY[6]; - pCurPatch->arrX[1][0] = arrX[7]; pCurPatch->arrY[1][0] = arrY[7]; - pCurPatch->arrX[1][1] = arrX[8]; pCurPatch->arrY[1][1] = arrY[8]; - pCurPatch->arrX[1][2] = arrX[9]; pCurPatch->arrY[1][2] = arrY[9]; - pCurPatch->arrX[2][2] = arrX[10]; pCurPatch->arrY[2][2] = arrY[10]; - pCurPatch->arrX[2][1] = arrX[11]; pCurPatch->arrY[2][1] = arrY[11]; - for (int nJ = 0; nJ < nComponentsCount; ++nJ) - { - pCurPatch->arrColor[0][0].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[1][0].arrComp[nJ]; - pCurPatch->arrColor[0][1].arrComp[nJ] = pPatches[nPatchesCount - 1].arrColor[0][0].arrComp[nJ]; - pCurPatch->arrColor[1][1].arrComp[nJ] = arrC[0][nJ]; - pCurPatch->arrColor[1][0].arrComp[nJ] = arrC[1][nJ]; - } - break; - } - } - ++nPatchesCount; - pBitBuffer->FlushBits(); - } - delete pBitBuffer; - - if (nType == 6) - { - for (nIndex = 0; nIndex < nPatchesCount; ++nIndex) - { - GrPatch *p = &pPatches[nIndex]; - p->arrX[1][1] = (-4 * p->arrX[0][0] + 6 * (p->arrX[0][1] + p->arrX[1][0]) - 2 * (p->arrX[0][3] + p->arrX[3][0]) + 3 * (p->arrX[3][1] + p->arrX[1][3]) - p->arrX[3][3]) / 9; - p->arrY[1][1] = (-4 * p->arrY[0][0] + 6 * (p->arrY[0][1] + p->arrY[1][0]) - 2 * (p->arrY[0][3] + p->arrY[3][0]) + 3 * (p->arrY[3][1] + p->arrY[1][3]) - p->arrY[3][3]) / 9; - - p->arrX[1][2] = (-4 * p->arrX[0][3] + 6 * (p->arrX[0][2] + p->arrX[1][3]) - 2 * (p->arrX[0][0] + p->arrX[3][3]) + 3 * (p->arrX[3][2] + p->arrX[1][0]) - p->arrX[3][0]) / 9; - p->arrY[1][2] = (-4 * p->arrY[0][3] + 6 * (p->arrY[0][2] + p->arrY[1][3]) - 2 * (p->arrY[0][0] + p->arrY[3][3]) + 3 * (p->arrY[3][2] + p->arrY[1][0]) - p->arrY[3][0]) / 9; - - p->arrX[2][1] = (-4 * p->arrX[3][0] + 6 * (p->arrX[3][1] + p->arrX[2][0]) - 2 * (p->arrX[3][3] + p->arrX[0][0]) + 3 * (p->arrX[0][1] + p->arrX[2][3]) - p->arrX[0][3]) / 9; - p->arrY[2][1] = (-4 * p->arrY[3][0] + 6 * (p->arrY[3][1] + p->arrY[2][0]) - 2 * (p->arrY[3][3] + p->arrY[0][0]) + 3 * (p->arrY[0][1] + p->arrY[2][3]) - p->arrY[0][3]) / 9; - - p->arrX[2][2] = (-4 * p->arrX[3][3] + 6 * (p->arrX[3][2] + p->arrX[2][3]) - 2 * (p->arrX[3][0] + p->arrX[0][3]) + 3 * (p->arrX[0][2] + p->arrX[2][0]) - p->arrX[0][0]) / 9; - p->arrY[2][2] = (-4 * p->arrY[3][3] + 6 * (p->arrY[3][2] + p->arrY[2][3]) - 2 * (p->arrY[3][0] + p->arrY[0][3]) + 3 * (p->arrY[0][2] + p->arrY[2][0]) - p->arrY[0][0]) / 9; - } - } - - GrPatchMeshShading *pShading = new GrPatchMeshShading(nType, pPatches, nPatchesCount, ppFunctions, nFunctionsCount); - if (!pShading) - return NULL; - if (!pShading->Initialize(pDict)) - { - delete pShading; - return NULL; - } - return pShading; - } - - GrShading *GrPatchMeshShading::Copy() - { - return new GrPatchMeshShading(this); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrImageColorMap - //------------------------------------------------------------------------------------------------------------------------------- - - GrImageColorMap::GrImageColorMap(int nBitsPerComponent, Object *pDecode, GrColorSpace *pColorSpace) - { - m_bSuccess = true; - - m_nBitsPerComponent = nBitsPerComponent; - int nMaxPixelIndex = (1 << m_nBitsPerComponent) - 1; - m_pColorSpace = pColorSpace; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - m_ppLookup[nIndex] = NULL; - } - - if (pDecode->IsNull()) - { - m_nComponentsCount = m_pColorSpace->GetComponentsCount(); - m_pColorSpace->GetDefaultRanges(m_arrDecodeLow, m_arrDecodeRange, nMaxPixelIndex); - } - else if (pDecode->IsArray()) - { - m_nComponentsCount = pDecode->ArrayGetLength() / 2; - if (m_nComponentsCount != m_pColorSpace->GetComponentsCount()) - { - m_bSuccess = false; - return; - } - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - Object oTemp; - pDecode->ArrayGet(2 * nIndex, &oTemp); - if (!oTemp.IsNum()) - { - oTemp.Free(); - m_bSuccess = false; - return; - } - m_arrDecodeLow[nIndex] = oTemp.GetNum(); - oTemp.Free(); - - pDecode->ArrayGet(2 * nIndex + 1, &oTemp); - if (!oTemp.IsNum()) - { - oTemp.Free(); - m_bSuccess = false; - return; - } - m_arrDecodeRange[nIndex] = oTemp.GetNum() - m_arrDecodeLow[nIndex]; - oTemp.Free(); - } - } - else - { - m_bSuccess = false; - return; - } - - // Строим таблицу поиска, в которой будут храниться, предварительно вычисленные(декодированные), - // значения какждой компоненты. - // Оптимизация для цветовых пространств Indexed and Separation(имеющих одну компоненту): - // в таблице будет хранится значения цвета, а не значения компонент. - m_pColorSpace2 = NULL; - m_nComponentsCount2 = 0; - double arrX[GrColorMaxComps], arrY[GrColorMaxComps]; - if (m_pColorSpace->GetMode() == csIndexed) - { - // Возможно, что nHival != nMaxPixelIndex - GrIndexedColorSpace *pIndexedCS = (GrIndexedColorSpace *)m_pColorSpace; - m_pColorSpace2 = pIndexedCS->GetBase(); - int nHival = pIndexedCS->GetHival(); - m_nComponentsCount2 = m_pColorSpace2->GetComponentsCount(); - unsigned char *pLookup2 = pIndexedCS->GetLookup(); - m_pColorSpace2->GetDefaultRanges(arrX, arrY, nHival); - - for (int nComp = 0; nComp < m_nComponentsCount2; ++nComp) - { - m_ppLookup[nComp] = (GrColorComp *)MemUtilsMallocArray(nMaxPixelIndex + 1, sizeof(GrColorComp)); - for (int nIndex = 0; nIndex <= nMaxPixelIndex; ++nIndex) - { - int nCurIndex = (int)(m_arrDecodeLow[0] + (nIndex * m_arrDecodeRange[0]) / nMaxPixelIndex + 0.5); - if (nCurIndex < 0) - { - nCurIndex = 0; - } - else if (nCurIndex > nHival) - { - nCurIndex = nHival; - } - m_ppLookup[nComp][nIndex] = DoubleToColor(arrX[nComp] + (pLookup2[nCurIndex * m_nComponentsCount2 + nComp] / 255.0) * arrY[nComp]); - } - } - } - else if (m_pColorSpace->GetMode() == csSeparation) - { - GrSeparationColorSpace *pSeparateCS = (GrSeparationColorSpace *)m_pColorSpace; - m_pColorSpace2 = pSeparateCS->GetAlternateSpace(); - m_nComponentsCount2 = m_pColorSpace2->GetComponentsCount(); - Function *pSepFunc = pSeparateCS->GetTransformFunction(); - - for (int nComp = 0; nComp < m_nComponentsCount2; ++nComp) - { - m_ppLookup[nComp] = (GrColorComp *)MemUtilsMallocArray(nMaxPixelIndex + 1, sizeof(GrColorComp)); - for (int nIndex = 0; nIndex <= nMaxPixelIndex; ++nIndex) - { - arrX[0] = m_arrDecodeLow[0] + (nIndex * m_arrDecodeRange[0]) / nMaxPixelIndex; - pSepFunc->Transform(arrX, arrY); - m_ppLookup[nComp][nIndex] = DoubleToColor(arrY[nComp]); - } - } - } - else - { - for (int nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - m_ppLookup[nComp] = (GrColorComp *)MemUtilsMallocArray(nMaxPixelIndex + 1, sizeof(GrColorComp)); - for (int nIndex = 0; nIndex <= nMaxPixelIndex; ++nIndex) - { - m_ppLookup[nComp][nIndex] = DoubleToColor(m_arrDecodeLow[nComp] + (nIndex * m_arrDecodeRange[nComp]) / nMaxPixelIndex); - } - } - } - - return; - } - - GrImageColorMap::GrImageColorMap(GrImageColorMap *pColorMap) - { - m_pColorSpace = pColorMap->m_pColorSpace->Copy(); - m_nBitsPerComponent = pColorMap->m_nBitsPerComponent; - m_nComponentsCount = pColorMap->m_nComponentsCount; - m_nComponentsCount2 = pColorMap->m_nComponentsCount2; - m_pColorSpace2 = NULL; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - m_ppLookup[nIndex] = NULL; - } - int nBitsCount = 1 << m_nBitsPerComponent; - if (m_pColorSpace->GetMode() == csIndexed) - { - m_pColorSpace2 = ((GrIndexedColorSpace *)m_pColorSpace)->GetBase(); - for (int nIndex = 0; nIndex < m_nComponentsCount2; ++nIndex) - { - m_ppLookup[nIndex] = (GrColorComp *)MemUtilsMallocArray(nBitsCount, sizeof(GrColorComp)); - memcpy(m_ppLookup[nIndex], pColorMap->m_ppLookup[nIndex], nBitsCount * sizeof(GrColorComp)); - } - } - else if (m_pColorSpace->GetMode() == csSeparation) - { - m_pColorSpace2 = ((GrSeparationColorSpace *)m_pColorSpace)->GetAlternateSpace(); - for (int nIndex = 0; nIndex < m_nComponentsCount2; ++nIndex) - { - m_ppLookup[nIndex] = (GrColorComp *)MemUtilsMallocArray(nBitsCount, sizeof(GrColorComp)); - memcpy(m_ppLookup[nIndex], pColorMap->m_ppLookup[nIndex], nBitsCount * sizeof(GrColorComp)); - } - } - else - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - m_ppLookup[nIndex] = (GrColorComp *)MemUtilsMallocArray(nBitsCount, sizeof(GrColorComp)); - memcpy(m_ppLookup[nIndex], pColorMap->m_ppLookup[nIndex], nBitsCount * sizeof(GrColorComp)); - } - } - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - m_arrDecodeLow[nIndex] = pColorMap->m_arrDecodeLow[nIndex]; - m_arrDecodeRange[nIndex] = pColorMap->m_arrDecodeRange[nIndex]; - } - m_bSuccess = true; - } - - GrImageColorMap::~GrImageColorMap() - { - if (m_pColorSpace) - delete m_pColorSpace; - - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - MemUtilsFree(m_ppLookup[nIndex]); - } - } - - void GrImageColorMap::GetGray(unsigned char *pColorValue, GrGray *pGray) - { - GrColor oColor; - - if (m_pColorSpace2) - { - for (int nIndex = 0; nIndex < m_nComponentsCount2; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[0]]; - } - m_pColorSpace2->GetGray(&oColor, pGray); - } - else - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[nIndex]]; - } - m_pColorSpace->GetGray(&oColor, pGray); - } - } - - void GrImageColorMap::GetRGB(unsigned char *pColorValue, GrRGB *pRGB) - { - GrColor oColor; - - if (m_pColorSpace2) - { - for (int nIndex = 0; nIndex < m_nComponentsCount2; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[0]]; - } - m_pColorSpace2->GetRGB(&oColor, pRGB); - } - else - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[nIndex]]; - } - m_pColorSpace->GetRGB(&oColor, pRGB); - } - } - - void GrImageColorMap::GetCMYK(unsigned char *pColorValue, GrCMYK *pCMYK) - { - GrColor oColor; - - if (m_pColorSpace2) - { - for (int nIndex = 0; nIndex < m_nComponentsCount2; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[0]]; - } - m_pColorSpace2->GetCMYK(&oColor, pCMYK); - } - else - { - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - oColor.arrComp[nIndex] = m_ppLookup[nIndex][pColorValue[nIndex]]; - } - m_pColorSpace->GetCMYK(&oColor, pCMYK); - } - } - - void GrImageColorMap::GetColor(unsigned char *pColorValue, GrColor *pColor) - { - int nMaxPixel = (1 << m_nBitsPerComponent) - 1; - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - pColor->arrComp[nIndex] = DoubleToColor(m_arrDecodeLow[nIndex] + (pColorValue[nIndex] * m_arrDecodeRange[nIndex]) / nMaxPixel); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrSubpath and GrPath - //------------------------------------------------------------------------------------------------------------------------------- - - GrSubpath::GrSubpath(double dX, double dY) - { - m_nSize = 16; - m_pX = (double *)MemUtilsMallocArray(m_nSize, sizeof(double)); - m_pY = (double *)MemUtilsMallocArray(m_nSize, sizeof(double)); - m_pbCurve = (bool *)MemUtilsMallocArray(m_nSize, sizeof(bool)); - m_nPointsCount = 1; - m_pX[0] = dX; - m_pY[0] = dY; - m_pbCurve[0] = false; - m_bClosed = false; - } - - GrSubpath::~GrSubpath() - { - MemUtilsFree(m_pX); - MemUtilsFree(m_pY); - MemUtilsFree(m_pbCurve); - } - - GrSubpath::GrSubpath(GrSubpath *pSubpath) - { - m_nSize = pSubpath->m_nSize; - m_nPointsCount = pSubpath->m_nPointsCount; - m_pX = (double *)MemUtilsMallocArray(m_nSize, sizeof(double)); - m_pY = (double *)MemUtilsMallocArray(m_nSize, sizeof(double)); - m_pbCurve = (bool *)MemUtilsMallocArray(m_nSize, sizeof(bool)); - memcpy(m_pX, pSubpath->m_pX, m_nPointsCount * sizeof(double)); - memcpy(m_pY, pSubpath->m_pY, m_nPointsCount * sizeof(double)); - memcpy(m_pbCurve, pSubpath->m_pbCurve, m_nPointsCount * sizeof(bool)); - m_bClosed = pSubpath->m_bClosed; - } - - void GrSubpath::LineTo(double dX, double dY) - { - if (m_nPointsCount >= m_nSize) - { - m_nSize += 16; - m_pX = (double *)MemUtilsReallocArray(m_pX, m_nSize, sizeof(double)); - m_pY = (double *)MemUtilsReallocArray(m_pY, m_nSize, sizeof(double)); - m_pbCurve = (bool *)MemUtilsReallocArray(m_pbCurve, m_nSize, sizeof(bool)); - } - m_pX[m_nPointsCount] = dX; - m_pY[m_nPointsCount] = dY; - m_pbCurve[m_nPointsCount] = false; - ++m_nPointsCount; - } - - void GrSubpath::CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3) - { - if (m_nPointsCount + 3 > m_nSize) - { - m_nSize += 16; - m_pX = (double *)MemUtilsReallocArray(m_pX, m_nSize, sizeof(double)); - m_pY = (double *)MemUtilsReallocArray(m_pY, m_nSize, sizeof(double)); - m_pbCurve = (bool *)MemUtilsReallocArray(m_pbCurve, m_nSize, sizeof(bool)); - } - m_pX[m_nPointsCount + 0] = dX1; - m_pY[m_nPointsCount + 0] = dY1; - m_pX[m_nPointsCount + 1] = dX2; - m_pY[m_nPointsCount + 1] = dY2; - m_pX[m_nPointsCount + 2] = dX3; - m_pY[m_nPointsCount + 2] = dY3; - m_pbCurve[m_nPointsCount + 0] = m_pbCurve[m_nPointsCount + 1] = true; - m_pbCurve[m_nPointsCount + 2] = false; - m_nPointsCount += 3; - } - - void GrSubpath::Close() - { - if (m_pX[m_nPointsCount - 1] != m_pX[0] || m_pY[m_nPointsCount - 1] != m_pY[0]) - { - LineTo(m_pX[0], m_pY[0]); - } - m_bClosed = true; - } - - void GrSubpath::Offset(double dDx, double dDy) - { - for (int nIndex = 0; nIndex < m_nPointsCount; ++nIndex) - { - m_pX[nIndex] += dDx; - m_pY[nIndex] += dDy; - } - } - - void GrSubpath::Transform(double *pMatrix) - { - for (int nIndex = 0; nIndex < m_nPointsCount; nIndex++) - { - double dOldX = m_pX[nIndex]; - double dOldY = m_pY[nIndex]; - - m_pX[nIndex] = dOldX * pMatrix[0] + dOldY * pMatrix[2] + pMatrix[4]; - m_pY[nIndex] = dOldX * pMatrix[1] + dOldY * pMatrix[3] + pMatrix[5]; - } - } - GrPath::GrPath() - { - m_bJustStarted = false; - m_nSize = 16; - m_nSubpathsCount = 0; - m_dFirstX = m_dFirstY = 0; - m_ppSubpaths = (GrSubpath **)MemUtilsMallocArray(m_nSize, sizeof(GrSubpath *)); - } - - GrPath::~GrPath() - { - for (int nIndex = 0; nIndex < m_nSubpathsCount; ++nIndex) - { - if (m_ppSubpaths[nIndex]) - delete m_ppSubpaths[nIndex]; - } - MemUtilsFree(m_ppSubpaths); - } - - GrPath::GrPath(bool bJustStarted, double dFirstX, double dFirstY, GrSubpath **ppSubpaths, int nSubpathCount, int nSize) - { - m_bJustStarted = bJustStarted; - m_dFirstX = dFirstX; - m_dFirstY = dFirstY; - m_nSize = nSize; - m_nSubpathsCount = nSubpathCount; - m_ppSubpaths = (GrSubpath **)MemUtilsMallocArray(m_nSize, sizeof(GrSubpath *)); - for (int nIndex = 0; nIndex < m_nSubpathsCount; ++nIndex) - m_ppSubpaths[nIndex] = ppSubpaths[nIndex]->Copy(); - } - - void GrPath::MoveTo(double dX, double dY) - { - m_bJustStarted = true; - m_dFirstX = dX; - m_dFirstY = dY; - } - - void GrPath::LineTo(double dX, double dY) - { - if (m_bJustStarted) - { - if (m_nSubpathsCount >= m_nSize) - { - m_nSize += 16; - m_ppSubpaths = (GrSubpath **)MemUtilsReallocArray(m_ppSubpaths, m_nSize, sizeof(GrSubpath *)); - } - m_ppSubpaths[m_nSubpathsCount] = new GrSubpath(m_dFirstX, m_dFirstY); - ++m_nSubpathsCount; - m_bJustStarted = false; - } - m_ppSubpaths[m_nSubpathsCount - 1]->LineTo(dX, dY); - } - - void GrPath::CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3) - { - if (m_bJustStarted) - { - if (m_nSubpathsCount >= m_nSize) - { - m_nSize += 16; - m_ppSubpaths = (GrSubpath **)MemUtilsReallocArray(m_ppSubpaths, m_nSize, sizeof(GrSubpath *)); - } - m_ppSubpaths[m_nSubpathsCount] = new GrSubpath(m_dFirstX, m_dFirstY); - ++m_nSubpathsCount; - m_bJustStarted = false; - } - m_ppSubpaths[m_nSubpathsCount - 1]->CurveTo(dX1, dY1, dX2, dY2, dX3, dY3); - } - - void GrPath::Close() - { - if (m_bJustStarted) - { - if (m_nSubpathsCount >= m_nSize) - { - m_nSize += 16; - m_ppSubpaths = (GrSubpath **)MemUtilsReallocArray(m_ppSubpaths, m_nSize, sizeof(GrSubpath *)); - } - m_ppSubpaths[m_nSubpathsCount] = new GrSubpath(m_dFirstX, m_dFirstY); - ++m_nSubpathsCount; - m_bJustStarted = false; - } - m_ppSubpaths[m_nSubpathsCount - 1]->Close(); - } - - void GrPath::Append(GrPath *pPath) - { - if (m_nSubpathsCount + pPath->m_nSubpathsCount > m_nSize) - { - m_nSize = m_nSubpathsCount + pPath->m_nSubpathsCount; - m_ppSubpaths = (GrSubpath **)MemUtilsReallocArray(m_ppSubpaths, m_nSize, sizeof(GrSubpath *)); - } - for (int nIndex = 0; nIndex < pPath->m_nSubpathsCount; ++nIndex) - { - m_ppSubpaths[m_nSubpathsCount++] = pPath->m_ppSubpaths[nIndex]->Copy(); - } - m_bJustStarted = false; - } - - void GrPath::Offset(double dDx, double dDy) - { - for (int nIndex = 0; nIndex < m_nSubpathsCount; ++nIndex) - { - m_ppSubpaths[nIndex]->Offset(dDx, dDy); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrClip - //------------------------------------------------------------------------------------------------------------------------------- - - GrClip::GrClip(double dMinX, double dMinY, double dMaxX, double dMaxY) - { - if (dMinX < dMaxX) - { - m_dMinX = dMinX; - m_dMaxX = dMaxX; - } - else - { - m_dMinX = dMaxX; - m_dMaxX = dMinX; - } - if (dMinY < dMaxY) - { - m_dMinY = dMinY; - m_dMaxY = dMaxY; - } - else - { - m_dMinY = dMaxY; - m_dMaxY = dMinY; - } - - m_nMinX = (int)floor(m_dMinX); - m_nMinY = (int)floor(m_dMinY); - m_nMaxX = (int)floor(m_dMaxX); - m_nMaxY = (int)floor(m_dMaxY); - - m_nPathsCount = m_nSize = 0; - m_ppPaths = NULL; - m_pMatrix = NULL; - m_pFlags = NULL; - - m_pTextClip = new GrTextClip(); - } - - GrClip::GrClip(GrClip *pClip) - { - m_dMinX = pClip->m_dMinX; - m_dMinY = pClip->m_dMinY; - m_dMaxX = pClip->m_dMaxX; - m_dMaxY = pClip->m_dMaxY; - m_nMinX = pClip->m_nMinX; - m_nMinY = pClip->m_nMinY; - m_nMaxX = pClip->m_nMaxX; - m_nMaxY = pClip->m_nMaxY; - - m_nPathsCount = pClip->m_nPathsCount; - m_nSize = pClip->m_nSize; - - m_ppPaths = (GrPath **)MemUtilsMallocArray(m_nSize, sizeof(GrPath *)); - m_pMatrix = (Matrix *)MemUtilsMallocArray(m_nSize, sizeof(Matrix)); - m_pFlags = (unsigned char *)MemUtilsMallocArray(m_nSize, sizeof(unsigned char)); - - for (int nIndex = 0; nIndex < m_nPathsCount; ++nIndex) - { - m_ppPaths[nIndex] = pClip->m_ppPaths[nIndex]->Copy(); - m_pMatrix[nIndex] = pClip->m_pMatrix[nIndex]; - m_pFlags[nIndex] = pClip->m_pFlags[nIndex]; - } - - m_pTextClip = pClip->m_pTextClip->Copy(); - } - - GrClip::~GrClip() - { - for (int nIndex = 0; nIndex < m_nPathsCount; ++nIndex) - { - if (m_ppPaths[nIndex]) - { - delete m_ppPaths[nIndex]; - } - } - - MemUtilsFree(m_ppPaths); - MemUtilsFree(m_pMatrix); - MemUtilsFree(m_pFlags); - - if (m_pTextClip) - delete m_pTextClip; - } - - void GrClip::Resize(int nPathsCount) - { - if (m_nPathsCount + nPathsCount > m_nSize) - { - if (m_nSize == 0) - { - m_nSize = 32; - } - while (m_nSize < m_nPathsCount + nPathsCount) - { - m_nSize *= 2; - } - - m_ppPaths = (GrPath **)MemUtilsReallocArray(m_ppPaths, m_nSize, sizeof(GrPath *)); - m_pMatrix = (Matrix *)MemUtilsReallocArray(m_pMatrix, m_nSize, sizeof(Matrix)); - m_pFlags = (unsigned char *)MemUtilsReallocArray(m_pFlags, m_nSize, sizeof(unsigned char)); - } - } - - void GrClip::ResetToRect(double dX0, double dY0, double dX1, double dY1) - { - for (int nIndex = 0; nIndex < m_nPathsCount; ++nIndex) - { - if (m_ppPaths[nIndex]) - { - delete m_ppPaths[nIndex]; - } - } - - MemUtilsFree(m_ppPaths); - MemUtilsFree(m_pMatrix); - MemUtilsFree(m_pFlags); - - m_ppPaths = NULL; - m_pFlags = NULL; - - m_nPathsCount = m_nSize = 0; - - if (dX0 < dX1) - { - m_dMinX = dX0; - m_dMaxX = dX1; - } - else - { - m_dMinX = dX1; - m_dMaxX = dX0; - } - - if (dY0 < dY1) - { - m_dMinY = dY0; - m_dMaxY = dY1; - } - else - { - m_dMinY = dY1; - m_dMaxY = dY0; - } - - m_nMinX = (int)floor(m_dMinX); - m_nMinY = (int)floor(m_dMinY); - m_nMaxX = (int)floor(m_dMaxX); - m_nMaxY = (int)floor(m_dMaxY); - } - - void GrClip::ClipToRect(double dX0, double dY0, double dX1, double dY1) - { - if (dX0 < dX1) - { - if (dX0 > m_dMinX) - { - m_dMinX = dX0; - m_nMinX = (int)floor(m_dMinX); - } - if (dX1 < m_dMaxX) - { - m_dMaxX = dX1; - m_nMaxX = (int)floor(m_dMaxX); - } - } - else - { - if (dX1 > m_dMinX) - { - m_dMinX = dX1; - m_nMinX = (int)floor(m_dMinX); - } - if (dX0 < m_dMaxX) - { - m_dMaxX = dX0; - m_nMaxX = (int)floor(m_dMaxX); - } - } - - if (dY0 < dY1) - { - if (dY0 > m_dMinY) - { - m_dMinY = dY0; - m_nMinY = (int)floor(m_dMinY); - } - if (dY1 < m_dMaxY) - { - m_dMaxY = dY1; - m_nMaxY = (int)floor(m_dMaxY); - } - } - else - { - if (dY1 > m_dMinY) - { - m_dMinY = dY1; - m_nMinY = (int)floor(m_dMinY); - } - if (dY0 < m_dMaxY) - { - m_dMaxY = dY0; - m_nMaxY = (int)floor(m_dMaxY); - } - } - - return; - } - - void GrClip::ClipToPath(GrPath *pPath, double *pMatrix, bool bEO) - { - Resize(1); - - m_ppPaths[m_nPathsCount] = pPath; - m_pMatrix[m_nPathsCount].FromDoublePointer(pMatrix); - m_pFlags[m_nPathsCount] = (bEO ? GrClipEOFlag : 0); - ++m_nPathsCount; - return; - } - GrPath *GrClip::PathRect(double dX0, double dY0, double dX1, double dY1) - { - GrPath *pPath = new GrPath(); - - pPath->MoveTo(dX0, dY0); - pPath->LineTo(dX1, dY0); - pPath->LineTo(dX1, dY1); - pPath->LineTo(dX0, dY1); - pPath->Close(); - - return pPath; - } - //------------------------------------------------------------------------------------------------------------------------------- - // GrState - //------------------------------------------------------------------------------------------------------------------------------- - - GrState::GrState(double dHorizDPI, double dVertDPI, PDFRectangle *pPageBox, int nRotateAngle, bool bUpsideDown) - { - m_dHorDPI = dHorizDPI; - m_dVerDPI = dVertDPI; - m_nRotate = nRotateAngle; - m_dPageLeft = pPageBox->m_dLeft; - m_dPageBottom = pPageBox->m_dBottom; - m_dPageRight = pPageBox->m_dRight; - m_dPageTop = pPageBox->m_dTop; - - double dKoefX = m_dHorDPI / 72.0; - double dKoefY = m_dVerDPI / 72.0; - if (m_nRotate == 90) - { - m_arrCTM[0] = 0; - m_arrCTM[1] = bUpsideDown ? dKoefY : -dKoefY; - m_arrCTM[2] = dKoefX; - m_arrCTM[3] = 0; - m_arrCTM[4] = -dKoefX * m_dPageBottom; - m_arrCTM[5] = dKoefY * (bUpsideDown ? -m_dPageLeft : m_dPageRight); - m_dPageWidth = dKoefX * (m_dPageTop - m_dPageBottom); - m_dPageHeight = dKoefY * (m_dPageRight - m_dPageLeft); - } - else if (m_nRotate == 180) - { - m_arrCTM[0] = -dKoefX; - m_arrCTM[1] = 0; - m_arrCTM[2] = 0; - m_arrCTM[3] = bUpsideDown ? dKoefY : -dKoefY; - m_arrCTM[4] = dKoefX * m_dPageRight; - m_arrCTM[5] = dKoefY * (bUpsideDown ? -m_dPageBottom : m_dPageTop); - m_dPageWidth = dKoefX * (m_dPageRight - m_dPageLeft); - m_dPageHeight = dKoefY * (m_dPageTop - m_dPageBottom); - } - else if (m_nRotate == 270) - { - m_arrCTM[0] = 0; - m_arrCTM[1] = bUpsideDown ? -dKoefY : dKoefY; - m_arrCTM[2] = -dKoefX; - m_arrCTM[3] = 0; - m_arrCTM[4] = dKoefX * m_dPageTop; - m_arrCTM[5] = dKoefY * (bUpsideDown ? m_dPageRight : -m_dPageLeft); - m_dPageWidth = dKoefX * (m_dPageTop - m_dPageBottom); - m_dPageHeight = dKoefY * (m_dPageRight - m_dPageLeft); - } - else - { - m_arrCTM[0] = dKoefX; - m_arrCTM[1] = 0; - m_arrCTM[2] = 0; - m_arrCTM[3] = bUpsideDown ? -dKoefY : dKoefY; - m_arrCTM[4] = -dKoefX * m_dPageLeft; - m_arrCTM[5] = dKoefY * (bUpsideDown ? m_dPageTop : -m_dPageBottom); - m_dPageWidth = dKoefX * (m_dPageRight - m_dPageLeft); - m_dPageHeight = dKoefY * (m_dPageTop - m_dPageBottom); - } - - m_pFillColorSpace = new GrDeviceGrayColorSpace(); - m_pStrokeColorSpace = new GrDeviceGrayColorSpace(); - m_oFillColor.arrComp[0] = 0; - m_oStrokeColor.arrComp[0] = 0; - m_pFillPattern = NULL; - m_pStrokePattern = NULL; - m_eBlendMode = grBlendNormal; - m_dFillOpacity = 1; - m_dStrokeOpacity = 1; - m_bFillOverprint = false; - m_bStrokeOverprint = false; - m_ppTransfer[0] = m_ppTransfer[1] = m_ppTransfer[2] = m_ppTransfer[3] = NULL; - - m_dLineWidth = 1; - m_pLineDash = NULL; - m_nLineDashSize = 0; - m_dLineDashStart = 0; - m_nFlatness = 1; - m_nLineJoin = 0; - m_nLineCap = 0; - m_dMiterLimit = 10; - m_bStrokeAdjust = false; - - m_pFont = NULL; - m_dFontSize = 0; - m_arrTextMatrix[0] = 1; m_arrTextMatrix[1] = 0; - m_arrTextMatrix[2] = 0; m_arrTextMatrix[3] = 1; - m_arrTextMatrix[4] = 0; m_arrTextMatrix[5] = 0; - m_dCharSpace = 0; - m_dWordSpace = 0; - m_dHorizScaling = 1; - m_dLeading = 0; - m_nRise = 0; - m_nRenderMode = 0; - - m_pPath = new GrPath(); - m_dCurX = m_dCurY = 0; - m_dTextLineX = m_dTextLineY = 0; - - m_pClip = new GrClip(0, 0, m_dPageWidth, m_dPageHeight); - m_dClipXMin = 0; - m_dClipYMin = 0; - m_dClipXMax = m_dPageWidth; - m_dClipYMax = m_dPageHeight; - - m_pNext = NULL; - } - - GrState::~GrState() - { - if (m_pFillColorSpace) - { - delete m_pFillColorSpace; - } - if (m_pStrokeColorSpace) - { - delete m_pStrokeColorSpace; - } - if (m_pFillPattern) - { - delete m_pFillPattern; - } - if (m_pStrokePattern) - { - delete m_pStrokePattern; - } - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - if (m_ppTransfer[nIndex]) - { - delete m_ppTransfer[nIndex]; - } - } - MemUtilsFree(m_pLineDash); - if (m_pPath) - { - delete m_pPath; - } - if (m_pClip) - { - delete m_pClip; - } - if (m_pNext) - { - delete m_pNext; - } - } - - GrState::GrState(GrState *pState) - { - memcpy(this, pState, sizeof(GrState)); - - if (m_pFillColorSpace) - { - m_pFillColorSpace = pState->m_pFillColorSpace->Copy(); - } - if (m_pStrokeColorSpace) - { - m_pStrokeColorSpace = pState->m_pStrokeColorSpace->Copy(); - } - if (m_pFillPattern) - { - m_pFillPattern = pState->m_pFillPattern->Copy(); - } - if (m_pStrokePattern) - { - m_pStrokePattern = pState->m_pStrokePattern->Copy(); - } - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - if (m_ppTransfer[nIndex]) - { - m_ppTransfer[nIndex] = pState->m_ppTransfer[nIndex]->Copy(); - } - } - if (m_nLineDashSize > 0) - { - m_pLineDash = (double *)MemUtilsMallocArray(m_nLineDashSize, sizeof(double)); - memcpy(m_pLineDash, pState->m_pLineDash, m_nLineDashSize * sizeof(double)); - } - if (m_pClip) - { - m_pClip = pState->m_pClip->Copy(); - } - m_pNext = NULL; - } - - void GrState::SetPath(GrPath *pPath) - { - if (m_pPath) - delete m_pPath; - m_pPath = pPath; - } - - void GrState::GetUserClipBBox(double *pdXMin, double *pdYMin, double *pdXMax, double *pdYMax) - { - double arrInvCTM[6]; - double dXMin, dYMin, dXMax, dYMax; - - double dDet_ = m_arrCTM[0] * m_arrCTM[3] - m_arrCTM[1] * m_arrCTM[2]; - if (fabs(dDet_) < FLT_EPSILON) - { - *pdXMin = 0; - *pdYMin = 0; - *pdXMax = 0; - *pdYMax = 0; - return; - } - - // Обратная матрица для матрицы CTM - double dDet = 1 / dDet_; - arrInvCTM[0] = m_arrCTM[3] * dDet; - arrInvCTM[1] = -m_arrCTM[1] * dDet; - arrInvCTM[2] = -m_arrCTM[2] * dDet; - arrInvCTM[3] = m_arrCTM[0] * dDet; - arrInvCTM[4] = (m_arrCTM[2] * m_arrCTM[5] - m_arrCTM[3] * m_arrCTM[4]) * dDet; - arrInvCTM[5] = (m_arrCTM[1] * m_arrCTM[4] - m_arrCTM[0] * m_arrCTM[5]) * dDet; - - dXMin = dXMax = m_dClipXMin * arrInvCTM[0] + m_dClipYMin * arrInvCTM[2] + arrInvCTM[4]; - dYMin = dYMax = m_dClipXMin * arrInvCTM[1] + m_dClipYMin * arrInvCTM[3] + arrInvCTM[5]; - double dTransX = m_dClipXMin * arrInvCTM[0] + m_dClipYMax * arrInvCTM[2] + arrInvCTM[4]; - double dTransY = m_dClipXMin * arrInvCTM[1] + m_dClipYMax * arrInvCTM[3] + arrInvCTM[5]; - if (dTransX < dXMin) - { - dXMin = dTransX; - } - else if (dTransX > dXMax) - { - dXMax = dTransX; - } - if (dTransY < dYMin) - { - dYMin = dTransY; - } - else if (dTransY > dYMax) - { - dYMax = dTransY; - } - dTransX = m_dClipXMax * arrInvCTM[0] + m_dClipYMin * arrInvCTM[2] + arrInvCTM[4]; - dTransY = m_dClipXMax * arrInvCTM[1] + m_dClipYMin * arrInvCTM[3] + arrInvCTM[5]; - if (dTransX < dXMin) - { - dXMin = dTransX; - } - else if (dTransX > dXMax) - { - dXMax = dTransX; - } - if (dTransY < dYMin) - { - dYMin = dTransY; - } - else if (dTransY > dYMax) - { - dYMax = dTransY; - } - dTransX = m_dClipXMax * arrInvCTM[0] + m_dClipYMax * arrInvCTM[2] + arrInvCTM[4]; - dTransY = m_dClipXMax * arrInvCTM[1] + m_dClipYMax * arrInvCTM[3] + arrInvCTM[5]; - if (dTransX < dXMin) - { - dXMin = dTransX; - } - else if (dTransX > dXMax) - { - dXMax = dTransX; - } - if (dTransY < dYMin) - { - dYMin = dTransY; - } - else if (dTransY > dYMax) - { - dYMax = dTransY; - } - - *pdXMin = dXMin; - *pdYMin = dYMin; - *pdXMax = dXMax; - *pdYMax = dYMax; - } - - double GrState::TransformWidth(double dWidth) - { - double dX = m_arrCTM[0] + m_arrCTM[2]; - double dY = m_arrCTM[1] + m_arrCTM[3]; - return dWidth * sqrt(0.5 * (dX * dX + dY * dY)); - } - - double GrState::GetTransformedFontSize() - { - double dX1 = m_arrTextMatrix[2] * m_dFontSize; - double dY1 = m_arrTextMatrix[3] * m_dFontSize; - double dX2 = m_arrCTM[0] * dX1 + m_arrCTM[2] * dY1; - double dY2 = m_arrCTM[1] * dX1 + m_arrCTM[3] * dY1; - return sqrt(dX2 * dX2 + dY2 * dY2); - } - - void GrState::GetFontTransformMatrix(double *pdM11, double *pdM12, double *pdM21, double *pdM22) - { - *pdM11 = (m_arrTextMatrix[0] * m_arrCTM[0] + m_arrTextMatrix[1] * m_arrCTM[2]) * m_dFontSize; - *pdM12 = (m_arrTextMatrix[0] * m_arrCTM[1] + m_arrTextMatrix[1] * m_arrCTM[3]) * m_dFontSize; - *pdM21 = (m_arrTextMatrix[2] * m_arrCTM[0] + m_arrTextMatrix[3] * m_arrCTM[2]) * m_dFontSize; - *pdM22 = (m_arrTextMatrix[2] * m_arrCTM[1] + m_arrTextMatrix[3] * m_arrCTM[3]) * m_dFontSize; - } - - void GrState::SetCTM(double dA, double dB, double dC, double dD, double dE, double dF) - { - m_arrCTM[0] = dA; - m_arrCTM[1] = dB; - m_arrCTM[2] = dC; - m_arrCTM[3] = dD; - m_arrCTM[4] = dE; - m_arrCTM[5] = dF; - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - if (m_arrCTM[nIndex] > 1e10) - { - m_arrCTM[nIndex] = 1e10; - } - else if (m_arrCTM[nIndex] < -1e10) - { - m_arrCTM[nIndex] = -1e10; - } - } - } - - void GrState::ConcatCTM(double dA, double dB, double dC, double dD, double dE, double dF) - { - double dOldA = m_arrCTM[0]; - double dOldB = m_arrCTM[1]; - double dOldC = m_arrCTM[2]; - double dOldD = m_arrCTM[3]; - - m_arrCTM[0] = dA * dOldA + dB * dOldC; - m_arrCTM[1] = dA * dOldB + dB * dOldD; - m_arrCTM[2] = dC * dOldA + dD * dOldC; - m_arrCTM[3] = dC * dOldB + dD * dOldD; - m_arrCTM[4] = dE * dOldA + dF * dOldC + m_arrCTM[4]; - m_arrCTM[5] = dE * dOldB + dF * dOldD + m_arrCTM[5]; - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - if (m_arrCTM[nIndex] > 1e10) - { - m_arrCTM[nIndex] = 1e10; - } - else if (m_arrCTM[nIndex] < -1e10) - { - m_arrCTM[nIndex] = -1e10; - } - } - } - - void GrState::ShiftCTM(double dShiftX, double dShiftY) - { - m_arrCTM[4] += dShiftX; - m_arrCTM[5] += dShiftY; - m_dClipXMin += dShiftX; - m_dClipYMin += dShiftY; - m_dClipXMax += dShiftX; - m_dClipYMax += dShiftY; - } - - void GrState::SetFillColorSpace(GrColorSpace *pColorSpace) - { - if (m_pFillColorSpace) - { - delete m_pFillColorSpace; - } - m_pFillColorSpace = pColorSpace; - } - - void GrState::SetStrokeColorSpace(GrColorSpace *pColorSpace) - { - if (m_pStrokeColorSpace) - { - delete m_pStrokeColorSpace; - } - m_pStrokeColorSpace = pColorSpace; - } - - void GrState::SetFillPattern(GrPattern *pPattern) - { - if (m_pFillPattern) - { - delete m_pFillPattern; - } - m_pFillPattern = pPattern; - } - - void GrState::SetStrokePattern(GrPattern *pPattern) - { - if (m_pStrokePattern) - { - delete m_pStrokePattern; - } - m_pStrokePattern = pPattern; - } - - void GrState::SetTransfer(Function **ppFunctions) - { - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - if (m_ppTransfer[nIndex]) - { - delete m_ppTransfer[nIndex]; - } - m_ppTransfer[nIndex] = ppFunctions[nIndex]; - } - } - - void GrState::SetLineDash(double *pDash, int nSize, double dStart) - { - MemUtilsFree(m_pLineDash); - m_pLineDash = pDash; - m_nLineDashSize = nSize; - m_dLineDashStart = dStart; - } - - void GrState::ClearPath() - { - if (m_pPath) - delete m_pPath; - m_pPath = new GrPath(); - } - - void GrState::Clip() - { - double dXMin = 0, dYMin = 0, dXMax = 0, dYMax = 0, dX = 0, dY = 0; - - for (int nSubPathIndex = 0; nSubPathIndex < m_pPath->GetSubpathsCount(); ++nSubPathIndex) - { - GrSubpath *pSubpath = m_pPath->GetSubpath(nSubPathIndex); - for (int nPointIndex = 0; nPointIndex < pSubpath->GetPointsCount(); ++nPointIndex) - { - Transform(pSubpath->GetX(nPointIndex), pSubpath->GetY(nPointIndex), &dX, &dY); - if (nSubPathIndex == 0 && nPointIndex == 0) - { - dXMin = dXMax = dX; - dYMin = dYMax = dY; - } - else - { - if (dX < dXMin) - { - dXMin = dX; - } - else if (dX > dXMax) - { - dXMax = dX; - } - if (dY < dYMin) - { - dYMin = dY; - } - else if (dY > dYMax) - { - dYMax = dY; - } - } - } - } - if (dXMin > m_dClipXMin) - { - m_dClipXMin = dXMin; - } - if (dYMin > m_dClipYMin) - { - m_dClipYMin = dYMin; - } - if (dXMax < m_dClipXMax) - { - m_dClipXMax = dXMax; - } - if (dYMax < m_dClipYMax) - { - m_dClipYMax = dYMax; - } - } - - void GrState::ClipToStrokePath() - { - double dXMin = 0, dYMin = 0, dXMax = 0, dYMax = 0, dX = 0, dY = 0; - - for (int nSubPathIndex = 0; nSubPathIndex < m_pPath->GetSubpathsCount(); ++nSubPathIndex) - { - GrSubpath *pSubpath = m_pPath->GetSubpath(nSubPathIndex); - for (int nPointIndex = 0; nPointIndex < pSubpath->GetPointsCount(); ++nPointIndex) - { - Transform(pSubpath->GetX(nPointIndex), pSubpath->GetY(nPointIndex), &dX, &dY); - if (nSubPathIndex == 0 && nPointIndex == 0) - { - dXMin = dXMax = dX; - dYMin = dYMax = dY; - } - else - { - if (dX < dXMin) - { - dXMin = dX; - } - else if (dX > dXMax) - { - dXMax = dX; - } - if (dY < dYMin) - { - dYMin = dY; - } - else if (dY > dYMax) - { - dYMax = dY; - } - } - } - } - - // Учитываем толщину линии - double dT0 = fabs(m_arrCTM[0]); - double dT1 = fabs(m_arrCTM[2]); - if (dT0 > dT1) - { - dXMin -= 0.5 * m_dLineWidth * dT0; - dXMax += 0.5 * m_dLineWidth * dT0; - } - else - { - dXMin -= 0.5 * m_dLineWidth * dT1; - dXMax += 0.5 * m_dLineWidth * dT1; - } - // TO DO: Проверит здесь!!!! Сдается, что нужно m_arrCTM[1] поставить - dT0 = fabs(m_arrCTM[0]); - dT1 = fabs(m_arrCTM[3]); - if (dT0 > dT1) - { - dYMin -= 0.5 * m_dLineWidth * dT0; - dYMax += 0.5 * m_dLineWidth * dT0; - } - else - { - dYMin -= 0.5 * m_dLineWidth * dT1; - dYMax += 0.5 * m_dLineWidth * dT1; - } - - if (dXMin > m_dClipXMin) - { - m_dClipXMin = dXMin; - } - if (dYMin > m_dClipYMin) - { - m_dClipYMin = dYMin; - } - if (dXMax < m_dClipXMax) - { - m_dClipXMax = dXMax; - } - if (dYMax < m_dClipYMax) - { - m_dClipYMax = dYMax; - } - } - - void GrState::TextShift(double dShiftX, double dShiftY) - { - double dDx = 0, dDy = 0; - - TextTransformDelta(dShiftX, dShiftY, &dDx, &dDy); - m_dCurX += dDx; - m_dCurY += dDy; - } - - void GrState::Shift(double dShiftX, double dShiftY) - { - m_dCurX += dShiftX; - m_dCurY += dShiftY; - } - - GrState *GrState::Save() - { - GrState *pNewState = Copy(); - pNewState->m_pNext = this; - return pNewState; - } - - GrState *GrState::Restore() - { - GrState *pOldState = NULL; - - if (m_pNext) - { - pOldState = m_pNext; - - // Следующие значения не сохраняются/восстанавливаются с помощью операций q/Q - pOldState->m_pPath = m_pPath; - pOldState->m_dCurX = m_dCurX; - pOldState->m_dCurY = m_dCurY; - pOldState->m_dTextLineX = m_dTextLineX; - pOldState->m_dTextLineY = m_dTextLineY; - - m_pPath = NULL; - m_pNext = NULL; - delete this; - - } - else - { - pOldState = this; - } - - return pOldState; - } - - bool GrState::ParseBlendMode(Object *pObject, GraphicsBlendMode *peMode) - { - if (pObject->IsName()) - { - for (int nIndex = 0; nIndex < GrBlendModeNamesCount; ++nIndex) - { - if (!strcmp(pObject->GetName(), c_arrsGrBlendModeNames[nIndex].sName)) - { - *peMode = c_arrsGrBlendModeNames[nIndex].eMode; - return true; - } - } - return false; - } - else if (pObject->IsArray()) - { - for (int nIndex = 0; nIndex < pObject->ArrayGetLength(); ++nIndex) - { - Object oTemp; - pObject->ArrayGet(nIndex, &oTemp); - if (!oTemp.IsName()) - { - oTemp.Free(); - return false; - } - for (int nJ = 0; nJ < GrBlendModeNamesCount; ++nJ) - { - if (!strcmp(oTemp.GetName(), c_arrsGrBlendModeNames[nJ].sName)) - { - oTemp.Free(); - *peMode = c_arrsGrBlendModeNames[nJ].eMode; - return true; - } - } - oTemp.Free(); - } - *peMode = grBlendNormal; - return true; - } - else - { - return false; - } - } -} diff --git a/PdfReader/old/GState.h b/PdfReader/old/GState.h deleted file mode 100644 index e3edb377d8..0000000000 --- a/PdfReader/old/GState.h +++ /dev/null @@ -1,2425 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_GSTATE_H -#define _PDF_READER_GSTATE_H - -#include "../../DesktopEditor/common/Types.h" -#include "Object.h" -#include "Function.h" -#include - -namespace PdfReader -{ - class Array; - class GrFont; - class PDFRectangle; - class GrShading; - - //------------------------------------------------------------------------------------------------------------------------------- - // GraphicsBlendMode - //------------------------------------------------------------------------------------------------------------------------------- - - enum GraphicsBlendMode - { - grBlendNormal, - grBlendMultiply, - grBlendScreen, - grBlendOverlay, - grBlendDarken, - grBlendLighten, - grBlendColorDodge, - grBlendColorBurn, - grBlendHardLight, - grBlendSoftLight, - grBlendDifference, - grBlendExclusion, - grBlendHue, - grBlendSaturation, - grBlendColor, - grBlendLuminosity - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrColorComp - //------------------------------------------------------------------------------------------------------------------------------- - - // 16.16 - typedef int GrColorComp; - -#define GrColorComp1 0x10000 - - static inline GrColorComp DoubleToColor(double dValue) - { - return (GrColorComp)(dValue * GrColorComp1); - } - - static inline double ColorToDouble(GrColorComp nColor) - { - return (double)nColor / (double)GrColorComp1; - } - - static inline GrColorComp ByteToColor(unsigned char nByte) - { - // (nByte / 255) << 16 = (0.0000000100000001... * nByte) << 16 - // = ((nByte << 8) + (nByte) + (nByte >> 8) + ...) << 16 - // = (nByte << 8) + (nByte) + (nByte >> 7) - // [для округления] - return (GrColorComp)((nByte << 8) + nByte + (nByte >> 7)); - } - - static inline unsigned char ColorToByte(GrColorComp nColor) - { - // 255 * nColor + 0.5 = 256 * nColor - nColor + 0x8000 - return (unsigned char)(((nColor << 8) - nColor + 0x8000) >> 16); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // GrColor - //------------------------------------------------------------------------------------------------------------------------------- - -#define GrColorMaxComps funcMaxOutputs - - struct GrColor - { - GrColorComp arrComp[GrColorMaxComps]; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrGray - //------------------------------------------------------------------------------------------------------------------------------- - - typedef GrColorComp GrGray; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrRGB - //------------------------------------------------------------------------------------------------------------------------------- - - struct GrRGB - { - GrColorComp r, g, b; - }; - - //------------------------------------------------------------------------ - // GrCMYK - //------------------------------------------------------------------------ - - struct GrCMYK - { - GrColorComp c, m, y, k; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - // Константы GrColorSpaceModes и массив GrColorSpaceModeNames, определенный - // в GState.cpp должны совпадать. - enum GrColorSpaceMode - { - csDeviceGray, - csCalGray, - csDeviceRGB, - csCalRGB, - csDeviceCMYK, - csLab, - csICCBased, - csIndexed, - csSeparation, - csDeviceN, - csPattern - }; - - class GrColorSpace - { - public: - - GrColorSpace(); - virtual ~GrColorSpace(); - virtual GrColorSpace *Copy() = 0; - virtual GrColorSpaceMode GetMode() = 0; - - static GrColorSpace *Parse(Object *pColorSpaceObject); - - // Конвертируем в -> Gray, RGB, или CMYK. - virtual void GetGray(GrColor *pColor, GrGray *pGray) = 0; - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB) = 0; - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK) = 0; - - // Количество компонент. - virtual int GetComponentsCount() = 0; - - // Получаем стандартное значение цвета в данном цветовом пространстве. - virtual void GetDefaultColor(GrColor *pColor) = 0; - - // Стандартные границчные значения для каждой компоненты пикселя, где nMaxImagePixelValue - максимальное значение пикселя. - virtual void GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue); - - // True, если в данном цветовом пространстве на странице ничего не нарисовано. - virtual bool IsNonMarking() - { - return false; - } - - // Число различных цветовых пространств. - static int GetColorSpaceModesCount(); - - // Имя соответствующего цветового пространства. - static char *GetColorSpaceModeName(int nIndex); - - DWORD GetDwordColor(GrColor *pColor) - { - GrRGB oRGB; - GetRGB(pColor, &oRGB); - unsigned char nR = ColorToByte(oRGB.r); - unsigned char nG = ColorToByte(oRGB.g); - unsigned char nB = ColorToByte(oRGB.b); - return ((nB << 16) | (nG << 8) | nR); - } - - private: - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceGrayColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrDeviceGrayColorSpace : public GrColorSpace - { - public: - - GrDeviceGrayColorSpace(); - virtual ~GrDeviceGrayColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csDeviceGray; - } - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 1; - } - virtual void GetDefaultColor(GrColor *pColor); - - private: - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrCalGrayColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrCalGrayColorSpace : public GrColorSpace - { - public: - - GrCalGrayColorSpace(); - virtual ~GrCalGrayColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csCalGray; - } - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 1; - } - virtual void GetDefaultColor(GrColor *pColor); - - // Возвращаем значения, специфичные пространству CalGray. - double GetWhiteX() - { - return m_dWhiteX; - } - double GetWhiteY() - { - return m_dWhiteY; - } - double GetWhiteZ() - { - return m_dWhiteZ; - } - double GetBlackX() - { - return m_dBlackX; - } - double GetBlackY() - { - return m_dBlackY; - } - double GetBlackZ() - { - return m_dBlackZ; - } - double GetGamma() - { - return m_dGamma; - } - - private: - - double m_dWhiteX; // - double m_dWhiteY; // White point - double m_dWhiteZ; // - - double m_dBlackX; // - double m_dBlackY; // Black point - double m_dBlackZ; // - - double m_dGamma; // Gamma - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceRGBColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrDeviceRGBColorSpace : public GrColorSpace - { - public: - - GrDeviceRGBColorSpace(); - virtual ~GrDeviceRGBColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csDeviceRGB; - } - - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 3; - } - virtual void GetDefaultColor(GrColor *pColor); - - private: - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrCalRGBColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrCalRGBColorSpace : public GrColorSpace - { - public: - - GrCalRGBColorSpace(); - virtual ~GrCalRGBColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csCalRGB; - } - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 3; - } - virtual void GetDefaultColor(GrColor *pColor); - - // Возвращаем значения, специфичные пространству CalRBG. - double GetWhiteX() - { - return m_dWhiteX; - } - double GetWhiteY() - { - return m_dWhiteY; - } - double GetWhiteZ() - { - return m_dWhiteZ; - } - double GetBlackX() - { - return m_dBlackX; - } - double GetBlackY() - { - return m_dBlackY; - } - double GetBlackZ() - { - return m_dBlackZ; - } - double GetGammaR() - { - return m_dGammaR; - } - double GetGammaG() - { - return m_dGammaG; - } - double GetGammaB() - { - return m_dGammaB; - } - double *GetMatrix() - { - return m_arrdMatrix; - } - - private: - - double m_dWhiteX; // - double m_dWhiteY; // White point - double m_dWhiteZ; // - - double m_dBlackX; // - double m_dBlackY; // Black point - double m_dBlackZ; // - - double m_dGammaR; // - double m_dGammaG; // Gamma - double m_dGammaB; // - - double m_arrdMatrix[9]; // Матрица преобразования: ABC -> XYZ - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceCMYKColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrDeviceCMYKColorSpace : public GrColorSpace - { - public: - - GrDeviceCMYKColorSpace(); - virtual ~GrDeviceCMYKColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csDeviceCMYK; - } - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 4; - } - virtual void GetDefaultColor(GrColor *pColor); - - private: - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrLabColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrLabColorSpace : public GrColorSpace - { - public: - - GrLabColorSpace(); - virtual ~GrLabColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csLab; - } - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 3; - } - virtual void GetDefaultColor(GrColor *pColor); - - virtual void GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue); - - // Возвращаем значения, специфичные пространству Lab. - double GetWhiteX() - { - return m_dWhiteX; - } - double GetWhiteY() - { - return m_dWhiteY; - } - double GetWhiteZ() - { - return m_dWhiteZ; - } - double GetBlackX() - { - return m_dBlackX; - } - double GetBlackY() - { - return m_dBlackY; - } - double GetBlackZ() - { - return m_dBlackZ; - } - double GetMinA() - { - return m_dMinA; - } - double GetMaxA() - { - return m_dMaxA; - } - double GetMinB() - { - return m_dMinB; - } - double GetMaxB() - { - return m_dMaxB; - } - - private: - - double m_dWhiteX; // - double m_dWhiteY; // White point - double m_dWhiteZ; // - - double m_dBlackX; // - double m_dBlackY; // Black point - double m_dBlackZ; // - - double m_dMinA; // - double m_dMaxA; // Границы для компонент А и В - double m_dMinB; // - double m_dMaxB; // - - double m_dMultR; // - double m_dMultG; // Дополнительные сомножители - double m_dMultB; // - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrICCBasedColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrICCBasedColorSpace : public GrColorSpace - { - public: - - GrICCBasedColorSpace(int nCompontnsCount, GrColorSpace *pAlternate, Ref *pICCProfileStream); - virtual ~GrICCBasedColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csICCBased; - } - - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return m_nComponentsCount; - } - virtual void GetDefaultColor(GrColor *pColor); - - virtual void GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue); - - // Возвращаем значения, специфичные пространству Lab. - GrColorSpace *GetAlternate() - { - return m_pAlternate; - } - - private: - - int m_nComponentsCount; // Число компонент цвета (1, 3, or 4) - GrColorSpace *m_pAlternate; // Альтернативное цветовое пространство - double m_arrdRangeMin[4]; // Минимальные значения для каждой компоненты - double m_arrdRangeMax[4]; // Максимальные значения для каждой компоненты - Ref m_oICCProfileStream; // ICC - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrIndexedColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrIndexedColorSpace : public GrColorSpace - { - public: - - GrIndexedColorSpace(GrColorSpace *pBase, int nHival); - virtual ~GrIndexedColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csIndexed; - } - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 1; - } - virtual void GetDefaultColor(GrColor *pColor); - - virtual void GetDefaultRanges(double *pDecodeLow, double *pDecodeRange, int nMaxImagePixelValue); - - // Возвращаем значения, специфичные пространству Indexed. - GrColorSpace *GetBase() - { - return m_pBase; - } - int GetHival() - { - return m_nHival; - } - unsigned char *GetLookup() - { - return m_pLookup; - } - - private: - - GrColor *MapColorToBase(GrColor *pColor, GrColor *pBaseColor); - - private: - - GrColorSpace *m_pBase; // Базовое цветовое пространство - int m_nHival; // Hival = max valid index value - unsigned char *m_pLookup; // Таблица цветов - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrSeparationColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrSeparationColorSpace : public GrColorSpace - { - public: - - GrSeparationColorSpace(StringExt *seName, GrColorSpace *pAlternate, Function *pFunction); - virtual ~GrSeparationColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csSeparation; - } - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 1; - } - virtual void GetDefaultColor(GrColor *pColor); - - virtual bool IsNonMarking() - { - return m_bNonMarking; - } - - // Возвращаем значения, специфичные пространству Separation. - StringExt *GetName() - { - return m_seName; - } - GrColorSpace *GetAlternateSpace() - { - return m_pAlternateSpace; - } - Function *GetTransformFunction() - { - return m_pFunction; - } - - private: - - StringExt *m_seName; // Color space family name - GrColorSpace *m_pAlternateSpace; // Альтернативное цветовое пространство - Function *m_pFunction; // tintTransform ( функция преобразования в альтернативное пространство) - - bool m_bNonMarking; // Будет ли видимой графика, использующая данное цветовое пространство - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrDeviceNColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrDeviceNColorSpace : public GrColorSpace - { - public: - - GrDeviceNColorSpace(int nComponentsCount, GrColorSpace *pAlternate, Function *pFunction); - virtual ~GrDeviceNColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csDeviceN; - } - - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return m_nComponentsCount; - } - virtual void GetDefaultColor(GrColor *pColor); - - virtual bool IsNonMarking() - { - return m_bNonMarking; - } - - // Возвращаем значения, специфичные пространству DeviceN. - StringExt *GetColorantName(int nIndex) - { - return m_arrseNames[nIndex]; - } - GrColorSpace *GetAlternateColor() - { - return m_pAlternateSpace; - } - Function *GetTransformFunction() - { - return m_pFunction; - } - - private: - - int m_nComponentsCount; // Число компонент - StringExt *m_arrseNames[GrColorMaxComps]; // Объекты типа "Name" определяющие каждую цветовую компоненту - GrColorSpace *m_pAlternateSpace; // Альтернативное цветовое пространство - Function *m_pFunction; // tintTransform ( функция преобразования в альтернативное пространство) - - bool m_bNonMarking; // Будет ли видимой графика, использующая данное цветовое пространство - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPatternColorSpace - //------------------------------------------------------------------------------------------------------------------------------- - - class GrPatternColorSpace : public GrColorSpace - { - public: - - GrPatternColorSpace(GrColorSpace *pUnder); - virtual ~GrPatternColorSpace(); - virtual GrColorSpace *Copy(); - virtual GrColorSpaceMode GetMode() - { - return csPattern; - } - - - static GrColorSpace *Parse(Array *pArray); - - virtual void GetGray(GrColor *pColor, GrGray *pGray); - virtual void GetRGB(GrColor *pColor, GrRGB *pRGB); - virtual void GetCMYK(GrColor *pColor, GrCMYK *pCMYK); - - virtual int GetComponentsCount() - { - return 0; - } - virtual void GetDefaultColor(GrColor *pColor); - - // Возвращаем значения, специфичные пространству Pattern. - GrColorSpace *GetUnder() - { - return m_pUnder; - } - - private: - - GrColorSpace *m_pUnder; // Цветовое пространство подкладки (для не цветовых Patterns) - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPattern - //------------------------------------------------------------------------------------------------------------------------------- - - class GrPattern - { - public: - - GrPattern(int nType); - virtual ~GrPattern(); - - static GrPattern *Parse(Object *pObject); - - virtual GrPattern *Copy() = 0; - - int GetType() - { - return m_nType; - } - - private: - - int m_nType; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrTilingPattern - //------------------------------------------------------------------------------------------------------------------------------- - - class GrTilingPattern : public GrPattern - { - public: - - static GrTilingPattern *Parse(Object *pPatternObject); - virtual ~GrTilingPattern(); - - virtual GrPattern *Copy(); - - int GetPaintType() - { - return m_nPaintType; - } - int GetTilingType() - { - return m_nTilingType; - } - double *GetBBox() - { - return m_arrBBox; - } - double GetXStep() - { - return m_dXStep; - } - double GetYStep() - { - return m_dYStep; - } - Dict *GetResourcesDict() - { - return m_oResources.IsDict() ? m_oResources.GetDict() : (Dict *)NULL; - } - double *GetMatrix() - { - return m_arrMatrix; - } - Object *GetContentStream() - { - return &m_oContentStream; - } - - private: - - GrTilingPattern(int nPaintType, int nTilingType, double *pBBox, double dXStep, double dYStep, Object *pResources, double *pMatrix, Object *pContentStream); - - private: - - int m_nPaintType; - int m_nTilingType; - double m_arrBBox[4]; - double m_dXStep; - double m_dYStep; - Object m_oResources; - double m_arrMatrix[6]; - - Object m_oContentStream; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrShadingPattern - //------------------------------------------------------------------------------------------------------------------------------- - - class GrShadingPattern : public GrPattern - { - public: - - static GrShadingPattern *Parse(Object *pPatternObject); - virtual ~GrShadingPattern(); - - virtual GrPattern *Copy(); - - GrShading *GetShading() - { - return m_pShading; - } - double *GetMatrix() - { - return m_arrMatrix; - } - - private: - - GrShadingPattern(GrShading *pShading, double *pMatrix); - - private: - - GrShading *m_pShading; // Сам объект Shading - double m_arrMatrix[6]; // Pattern matrix - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrShading - //------------------------------------------------------------------------------------------------------------------------------- - - class GrShading - { - public: - - GrShading(int nType); - GrShading(GrShading *pShading); - virtual ~GrShading(); - - static GrShading *Parse(Object *pObject); - - virtual GrShading *Copy() = 0; - - int GetType() - { - return m_nType; - } - GrColorSpace *GetColorSpace() - { - return m_pColorSpace; - } - GrColor *GetBackground() - { - return &m_oBackground; - } - bool GetHasBackground() - { - return m_bHasBackground; - } - void GetBBox(double *pdXMin, double *pdYMin, double *pdXMax, double *pdYMax) - { - *pdXMin = m_dXMin; - *pdYMin = m_dYMin; - *pdXMax = m_dXMax; - *pdYMax = m_dYMax; - } - bool GetHasBBox() - { - return m_bHasBBox; - } - - protected: - - bool Initialize(Dict *pDict); - - protected: - - int m_nType; // Тип - GrColorSpace *m_pColorSpace; // Цветовое пространство, в котором рисуем - GrColor m_oBackground; // Цвет подкладки, если она есть - bool m_bHasBackground; // Есть ли подкладка? - - double m_dXMin; // - double m_dYMin; // BBox - double m_dXMax; // - double m_dYMax; // - bool m_bHasBBox; // Задан ли BBox? - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrFunctionShading - //------------------------------------------------------------------------------------------------------------------------------- - - class GrFunctionShading : public GrShading - { - public: - - GrFunctionShading(double dMinX, double dMinY, double dMaxX, double dMaxY, double *pMatrix, Function **ppFunctions, int nFuncsCount); - GrFunctionShading(GrFunctionShading *pShading); - virtual ~GrFunctionShading(); - - static GrFunctionShading *Parse(Dict *pDict); - - virtual GrShading *Copy(); - - void GetDomain(double *pdMinX, double *pdMinY, double *pdMaxX, double *pdMaxY) - { - *pdMinX = m_dDomainMinX; - *pdMinY = m_dDomainMinY; - *pdMaxX = m_dDomainMaxX; - *pdMaxY = m_dDomainMaxY; - } - double *GetMatrix() - { - return m_arrMatrix; - } - int GetFunctionsCount() - { - return m_nFunctionsCount; - } - Function *GetFunction(int nIndex) - { - return m_arrFunctions[nIndex]; - } - void GetColor(double dX, double dY, GrColor *pColor); - - private: - - double m_dDomainMinX; // - double m_dDomainMinY; // Domain - double m_dDomainMaxX; // - double m_dDomainMaxY; // - - double m_arrMatrix[6]; // Матрица преобразования и пространства, определенного Domain, в текущее пространство Shading - Function *m_arrFunctions[GrColorMaxComps]; - int m_nFunctionsCount; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrAxialShading - //------------------------------------------------------------------------------------------------------------------------------- - - class GrAxialShading : public GrShading - { - public: - - GrAxialShading(double dX0, double dY0, double dX1, double dY1, double dT0, double dT1, Function **ppFunctions, int nFuncsCount, bool bExtendStart, bool bExtendEnd); - GrAxialShading(GrAxialShading *pShading); - virtual ~GrAxialShading(); - - static GrAxialShading *Parse(Dict *pDict); - - virtual GrShading *Copy(); - - void GetCoords(double *pdX0, double *pdY0, double *pdX1, double *pdY1) - { - *pdX0 = m_dAxisX0; - *pdY0 = m_dAxisY0; - *pdX1 = m_dAxisX1; - *pdY1 = m_dAxisY1; - } - double GetDomain0() - { - return m_dT0; - } - double GetDomain1() - { - return m_dT1; - } - bool GetExtendStart() - { - return m_bExtendStart; - } - bool GetExtendEnd() - { - return m_bExtendEnd; - } - int GetFunctionsCount() - { - return m_nFunctionsCount; - } - Function *GetFunctions(int nIndex) - { - return m_arrFunctions[nIndex]; - } - void GetColor(double dT, GrColor *pColor); - - private: - - double m_dAxisX0; // Начальная точка вектора - double m_dAxisY0; // - double m_dAxisX1; // Конечная точка вектора - double m_dAxisY1; // - - double m_dT0; // Пределы параметра t(параметризация оси) - double m_dT1; - - Function *m_arrFunctions[GrColorMaxComps]; - int m_nFunctionsCount; - - bool m_bExtendStart; // Продолжать ли за начальную точку оси - bool m_bExtendEnd; // Продолжать ли за конечную точку оси - }; - //------------------------------------------------------------------------------------------------------------------------------- - // GrRadialShading - //------------------------------------------------------------------------------------------------------------------------------- - - class GrRadialShading : public GrShading - { - public: - - GrRadialShading(double dFirstX, double dFirstY, double dFirstRad, double dSecondX, double dSecondY, double dSecondRad, double dT0, double dT1, Function **ppFunctions, int nFuncsCount, bool bExtendFirst, bool bExtendSecond); - GrRadialShading(GrRadialShading *pShading); - virtual ~GrRadialShading(); - - static GrRadialShading *Parse(Dict *pDict); - - virtual GrShading *Copy(); - - void GetCoords(double *pdFirstX, double *pdFirstY, double *pdFirstRad, double *pdSecondX, double *pdSecondY, double *pdSecondRad) - { - *pdFirstX = m_dFirstX; - *pdFirstY = m_dFirstY; - *pdFirstRad = m_dFirstRad; - *pdSecondX = m_dSecondX; - *pdSecondY = m_dSecondY; - *pdSecondRad = m_dSecondRad; - } - double GetDomain0() - { - return m_dT0; - } - double GetDomain1() - { - return m_dT1; - } - bool GetExtendFirst() - { - return m_bExtendFirst; - } - bool GetExtendSecond() - { - return m_bExtendSecond; - } - int GetFunctionsCount() - { - return m_nFunctionsCount; - } - Function *GetFunctions(int nIndex) - { - return m_arrFunctions[nIndex]; - } - void GetColor(double dT, GrColor *pColor); - - private: - - double m_dFirstX; // Координаты центра первой окружности - double m_dFirstY; // - double m_dFirstRad; // Радиус первой окружности - double m_dSecondX; // Координаты центра второй окружности - double m_dSecondY; // - double m_dSecondRad; // Радиус второй окружности - - double m_dT0; // Границы параметра t - double m_dT1; // - - Function *m_arrFunctions[GrColorMaxComps]; - int m_nFunctionsCount; - bool m_bExtendFirst; // Продолжать ли рисовать за первый круг - bool m_bExtendSecond; // Продолжать ли рисовать за второй круг - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrGouraudTriangleShading - //------------------------------------------------------------------------------------------------------------------------------- - - struct GrGouraudVertex - { - double dX; // Координаты вершины - double dY; // - GrColor oColor; // Цвет - }; - - class GrGouraudTriangleShading : public GrShading - { - public: - - GrGouraudTriangleShading(int nType, GrGouraudVertex *pVertexes, int nVertexsCount, int(*pTriangles)[3], int nTrianglesCount, Function **ppFunctions, int nFunctionsCount); - GrGouraudTriangleShading(GrGouraudTriangleShading *pShading); - virtual ~GrGouraudTriangleShading(); - - static GrGouraudTriangleShading *Parse(int nType, Dict *pDict, Stream *pStream); - - virtual GrShading *Copy(); - - int GetTrianglesCount() - { - return m_nTrianglesCount; - } - void GetTriangle(int nIndex, double *pdX0, double *pdY0, GrColor *pColor0, double *pdX1, double *pdY1, GrColor *pColor1, double *pdX2, double *pdY2, GrColor *pColor2); - - private: - - GrGouraudVertex *m_arrVertexs; // Массив всех вершин - int m_nVertexsCount; // Количество вершин - int(*m_arrTriangles)[3]; // Массив треугольников(треугольник определяется по номерам вершин) - int m_nTrianglesCount; // Количество треугольников - Function *m_ppFunctions[GrColorMaxComps]; // Функции - int m_nFunctionsCount; // Количество функций - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrPatchMeshShading - //------------------------------------------------------------------------------------------------------------------------------- - - struct GrPatch - { - double arrX[4][4]; - double arrY[4][4]; - GrColor arrColor[2][2]; - }; - - class GrPatchMeshShading : public GrShading - { - public: - - GrPatchMeshShading(int nType, GrPatch *pPatches, int nPatchesCount, Function **ppFuntions, int nFunctionsCount); - GrPatchMeshShading(GrPatchMeshShading *pShading); - - virtual ~GrPatchMeshShading(); - - static GrPatchMeshShading *Parse(int nType, Dict *pDict, Stream *pStream); - - virtual GrShading *Copy(); - - int GetPatchesCount() - { - return m_nPatchesCount; - } - GrPatch *GetPatch(int nIndex) - { - return &m_pPatches[nIndex]; - } - - private: - - GrPatch *m_pPatches; // Массив частей - int m_nPatchesCount; // Количество частей - Function *m_ppFunctions[GrColorMaxComps]; // Массив функций - int m_nFunctionsCount; // Количество функций - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrImageColorMap - //------------------------------------------------------------------------------------------------------------------------------- - - class GrImageColorMap - { - public: - - GrImageColorMap(int nBitsPerComponent, Object *pDecode, GrColorSpace *pColorSpace); - - ~GrImageColorMap(); - - GrImageColorMap *Copy() - { - return new GrImageColorMap(this); - } - - bool IsValid() - { - return m_bSuccess; - } - - GrColorSpace *GetColorSpace() - { - return m_pColorSpace; - } - - int GetComponentsCount() - { - return m_nComponentsCount; - } - int GetBitsPerComponent() - { - return m_nBitsPerComponent; - } - - double GetDecodeLow(int nIndex) - { - return m_arrDecodeLow[nIndex]; - } - double GetDecodeHigh(int nIndex) - { - return m_arrDecodeLow[nIndex] + m_arrDecodeRange[nIndex]; - } - - void GetGray(unsigned char *pColorValue, GrGray *pGray); - void GetRGB(unsigned char *pColorValue, GrRGB *pRGB); - void GetCMYK(unsigned char *pColorValue, GrCMYK *pCMYK); - void GetColor(unsigned char *pColorValue, GrColor *pColor); - - private: - - GrImageColorMap(GrImageColorMap *pColorMap); - - private: - - GrColorSpace *m_pColorSpace; // Цветовое пространство изображения - int m_nBitsPerComponent; // bits per component - int m_nComponentsCount; // Число цветовых компонент в пикселе - GrColorSpace *m_pColorSpace2; // Второе цветовое пространство - int m_nComponentsCount2; // Число цветовых компонент в пикселе(во втором пространстве) - GrColorComp *m_ppLookup[GrColorMaxComps]; // lookup table - double m_arrDecodeLow[GrColorMaxComps]; // Минимальные значения для каждой компоненты - double m_arrDecodeRange[GrColorMaxComps]; // Значения (Max - min) для каждой компоненты - - bool m_bSuccess; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrSubpath and GrPath - //------------------------------------------------------------------------------------------------------------------------------- - - class GrSubpath - { - public: - - GrSubpath(double dX, double dY); - - ~GrSubpath(); - - GrSubpath *Copy() - { - return new GrSubpath(this); - } - - int GetPointsCount() - { - return m_nPointsCount; - } - double GetX(int nIndex) - { - return m_pX[nIndex]; - } - double GetY(int nIndex) - { - return m_pY[nIndex]; - } - bool GetCurve(int nIndex) - { - return m_pbCurve[nIndex]; - } - - double GetLastX() - { - return m_pX[m_nPointsCount - 1]; - } - double GetLastY() - { - return m_pY[m_nPointsCount - 1]; - } - - - void LineTo(double dX, double dY); - - void CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3); - - void Close(); - - bool IsClosed() - { - return m_bClosed; - } - - - // Добавляем сдвиг (, ) к каждой точке subpath. - void Offset(double dDx, double dDy); - void Transform(double *pMatrix); - - bool IsEqual(GrSubpath *pSubPath) - { - if (m_nPointsCount != pSubPath->m_nPointsCount || m_bClosed != pSubPath->m_bClosed) - return false; - - - for (int nIndex = 0; nIndex < m_nPointsCount; nIndex++) - { - if (fabs(m_pX[nIndex] - pSubPath->m_pX[nIndex]) > 0.001 || fabs(m_pY[nIndex] - pSubPath->m_pY[nIndex]) > 0.001 || m_pbCurve[nIndex] != pSubPath->m_pbCurve[nIndex]) - return false; - } - - return true; - } - - private: - - GrSubpath(GrSubpath *pSubpath); - - private: - - double *m_pX; // Координаты точек в supath - double *m_pY; // - - bool *m_pbCurve; // Если m_bCurve[i] = true => точка i - контрольная точка для кривой Безье - int m_nPointsCount; // Количество точек - int m_nSize; // Размер массивов m_pX/m_pY - bool m_bClosed; // Закрыт ли path? - }; - - class GrPath - { - public: - - GrPath(); - - ~GrPath(); - - GrPath *Copy() - { - return new GrPath(m_bJustStarted, m_dFirstX, m_dFirstY, m_ppSubpaths, m_nSubpathsCount, m_nSize); - } - - // Есть ли текущая точка? - bool IsCurPoint() - { - return m_nSubpathsCount > 0 || m_bJustStarted; - } - - // Пустой ли path, т.е. есть ли в нем хотя бы один subpath? - bool IsPathNonEmpty() - { - return m_nSubpathsCount > 0; - } - - int GetSubpathsCount() - { - return m_nSubpathsCount; - } - GrSubpath *GetSubpath(int nIndex) - { - return m_ppSubpaths[nIndex]; - } - - double GetLastX() - { - return m_ppSubpaths[m_nSubpathsCount - 1]->GetLastX(); - } - double GetLastY() - { - return m_ppSubpaths[m_nSubpathsCount - 1]->GetLastY(); - } - - - void MoveTo(double dX, double dY); - void LineTo(double dX, double dY); - void CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3); - void Close(); - void Append(GrPath *pPath); - - // Добавляем сдвиг (, ) к каждой точке path. - void Offset(double dDx, double dDy); - - bool IsEqual(GrPath *pPath) - { - if (m_nSubpathsCount != pPath->m_nSubpathsCount) - return false; - - for (int nIndex = 0; nIndex < m_nSubpathsCount; nIndex++) - { - if (!m_ppSubpaths[nIndex]->IsEqual(pPath->m_ppSubpaths[nIndex])) - return false; - } - - return true; - } - - private: - - GrPath(bool bJustStarted, double dFirstX, double dFirstY, GrSubpath **ppSubpaths, int nSubpathsCount, int nSize); - - private: - bool m_bJustStarted; // True, если новый subpath был только что начат - double m_dFirstX; // Координаты первой точки нового subpath - double m_dFirstY; // - GrSubpath **m_ppSubpaths; // Список subpaths - int m_nSubpathsCount; // Количетсво subpaths - int m_nSize; // Размер массива m_ppSubpaths - }; - - - //------------------------------------------------------------------------------------------------------------------------------- - // GrTextClip - //------------------------------------------------------------------------------------------------------------------------------- - - class GrTextClip - { - public: - - GrTextClip() - { - m_nTextsCount = m_nSize = 0; - m_pTexts = NULL; - m_pMatrix = NULL; - } - - GrTextClip *Copy() - { - return new GrTextClip(this); - } - - ~GrTextClip() - { - for (int nIndex = 0; nIndex < m_nTextsCount; ++nIndex) - { - FreeWString(m_pTexts[nIndex].wsText); - FreeWString(m_pTexts[nIndex].wsFontName); - FreeWString(m_pTexts[nIndex].wsFontPath); - } - MemUtilsFree(m_pTexts); - MemUtilsFree(m_pMatrix); - } - - void Reset() - { - for (int nIndex = 0; nIndex < m_nTextsCount; ++nIndex) - { - FreeWString(m_pTexts[nIndex].wsText); - FreeWString(m_pTexts[nIndex].wsFontName); - FreeWString(m_pTexts[nIndex].wsFontPath); - } - MemUtilsFree(m_pTexts); - MemUtilsFree(m_pMatrix); - - m_nTextsCount = m_nSize = 0; - m_pTexts = NULL; - m_pMatrix = NULL; - } - void ClipToText(std::wstring& wsFontName, std::wstring& wsFontPath, double dFontSize, int nFontStyle, double *pMatrix, std::wstring& wsText, double dX, double dY, double dWidth = 0, double dHeight = 0, double dBaseLineOffset = 0) - { - Resize(1); - - m_pTexts[m_nTextsCount].wsFontName = AllocWString(wsFontName); - m_pTexts[m_nTextsCount].wsFontPath = AllocWString(wsFontPath); - m_pTexts[m_nTextsCount].dFontSize = dFontSize; - m_pTexts[m_nTextsCount].nFontStyle = nFontStyle; - m_pTexts[m_nTextsCount].wsText = AllocWString(wsText); - m_pTexts[m_nTextsCount].dX = dX; - m_pTexts[m_nTextsCount].dY = dY; - m_pTexts[m_nTextsCount].dWidth = dWidth; - m_pTexts[m_nTextsCount].dHeight = dHeight; - m_pTexts[m_nTextsCount].dBaseLineOffset = dBaseLineOffset; - - m_pMatrix[m_nTextsCount].FromDoublePointer(pMatrix); - - ++m_nTextsCount; - return; - - } - int GetTextsCount() - { - return m_nTextsCount; - } - WString GetText(int nTextIndex, double *pdX, double *pdY, double *pdWidth, double *pdHeight, double *pdBaseLineOffset, WString* pwsFontName, WString* pwsFontPath, double *pdFontSize, int* pnFontStyle) - { - if (nTextIndex < 0 || nTextIndex >= m_nTextsCount) - return NULL; - - *pdX = m_pTexts[nTextIndex].dX; - *pdY = m_pTexts[nTextIndex].dY; - *pdWidth = m_pTexts[nTextIndex].dWidth; - *pdHeight = m_pTexts[nTextIndex].dHeight; - *pdBaseLineOffset = m_pTexts[nTextIndex].dBaseLineOffset; - - *pwsFontName = m_pTexts[nTextIndex].wsFontName; - *pwsFontPath = m_pTexts[nTextIndex].wsFontPath; - *pdFontSize = m_pTexts[nTextIndex].dFontSize; - *pnFontStyle = m_pTexts[nTextIndex].nFontStyle; - - return m_pTexts[nTextIndex].wsText; - } - double* GetMatrix(int nTextIndex) - { - if (nTextIndex < 0 || nTextIndex >= m_nTextsCount) - return NULL; - - return m_pMatrix[nTextIndex].ToDoublePointer(); - } - bool IsEqual(GrTextClip *pClip) - { - if (pClip->m_nTextsCount != m_nTextsCount) - return false; - - for (int nIndex = 0; nIndex < m_nTextsCount; nIndex++) - { - if (!m_pTexts[nIndex].IsEqual(pClip->m_pTexts[nIndex]) || !m_pMatrix[nIndex].IsEqual(pClip->m_pMatrix[nIndex])) - return false; - } - - return true; - } - - private: - - GrTextClip(GrTextClip *pTextClip) - { - m_nTextsCount = pTextClip->m_nTextsCount; - m_nSize = pTextClip->m_nSize; - - m_pTexts = (Text *)MemUtilsMallocArray(m_nSize, sizeof(Text)); - m_pMatrix = (Matrix *)MemUtilsMallocArray(m_nSize, sizeof(Matrix)); - - for (int nIndex = 0; nIndex < m_nTextsCount; ++nIndex) - { - m_pTexts[nIndex].wsText = AllocWString(pTextClip->m_pTexts[nIndex].wsText); - m_pTexts[nIndex].dX = pTextClip->m_pTexts[nIndex].dX; - m_pTexts[nIndex].dY = pTextClip->m_pTexts[nIndex].dY; - m_pTexts[nIndex].dWidth = pTextClip->m_pTexts[nIndex].dWidth; - m_pTexts[nIndex].dHeight = pTextClip->m_pTexts[nIndex].dHeight; - m_pTexts[nIndex].dBaseLineOffset = pTextClip->m_pTexts[nIndex].dBaseLineOffset; - - m_pTexts[nIndex].wsFontName = AllocWString(pTextClip->m_pTexts[nIndex].wsFontName); - m_pTexts[nIndex].wsFontPath = AllocWString(pTextClip->m_pTexts[nIndex].wsFontPath); - m_pTexts[nIndex].dFontSize = pTextClip->m_pTexts[nIndex].dFontSize; - m_pTexts[nIndex].nFontStyle = pTextClip->m_pTexts[nIndex].nFontStyle; - - m_pMatrix[nIndex] = pTextClip->m_pMatrix[nIndex]; - } - - } - void Resize(int nTextsCount) - { - if (m_nTextsCount + nTextsCount > m_nSize) - { - if (m_nSize == 0) - { - m_nSize = 32; - } - while (m_nSize < m_nTextsCount + nTextsCount) - { - m_nSize *= 2; - } - - m_pTexts = (Text *)MemUtilsReallocArray(m_pTexts, m_nSize, sizeof(Text)); - m_pMatrix = (Matrix *)MemUtilsReallocArray(m_pMatrix, m_nSize, sizeof(Matrix)); - } - } - void Transform(double *pMatrix, double dX, double dY, double *pdX, double *pdY) - { - *pdX = dX * pMatrix[0] + dY * pMatrix[2] + pMatrix[4]; - *pdY = dX * pMatrix[1] + dY * pMatrix[3] + pMatrix[5]; - } - - private: - -#pragma pack(push, 1) - struct Matrix - { - double dA; - double dB; - double dC; - double dD; - double dE; - double dF; - - double *ToDoublePointer() - { - return &dA; - } - - void FromDoublePointer(double *pMatrix) - { - dA = pMatrix[0]; - dB = pMatrix[1]; - dC = pMatrix[2]; - dD = pMatrix[3]; - dE = pMatrix[4]; - dF = pMatrix[5]; - } - bool IsEqual(Matrix &oMatrix) - { - if (fabs(dA - oMatrix.dA) < 0.001 && fabs(dB - oMatrix.dB) < 0.001 && fabs(dC - oMatrix.dC) < 0.001 && fabs(dD - oMatrix.dD) < 0.001 && fabs(dE - oMatrix.dE) < 0.001 && fabs(dF - oMatrix.dF) < 0.001) - return true; - - return false; - } - }; - - struct Text - { - WString wsFontName; - WString wsFontPath; - double dFontSize; - int nFontStyle; - - WString wsText; - double dX; - double dY; - double dWidth; - double dHeight; - double dBaseLineOffset; - - bool IsEqual(Text &oText) - { - if (fabs(dX - oText.dX) < 0.001 && fabs(dY - oText.dY) < 0.001 && fabs(dWidth - oText.dWidth) < 0.001 && fabs(dHeight - oText.dHeight) < 0.001 && fabs(dBaseLineOffset - oText.dBaseLineOffset) < 0.001 && std::wstring(wsText) == std::wstring(oText.wsText)) - return true; - - return false; - } - }; - -#pragma pack(pop) - - private: - - Text* m_pTexts; - Matrix* m_pMatrix; - int m_nTextsCount; - int m_nSize; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrClip - //------------------------------------------------------------------------------------------------------------------------------- - -#define GrClipEOFlag 0x01 // Используем правило Even-odd - - class GrClip - { - public: - - GrClip(double dMinX, double dMinY, double dMaxX, double dMaxY); - - GrClip *Copy() - { - return new GrClip(this); - } - - ~GrClip(); - - void ResetToRect(double dX0, double dY0, double dX1, double dY1); - - // Пересекаем Clip с заданным прямоугольником. - void ClipToRect(double dX0, double dY0, double dX1, double dY1); - - // Пересекаем Clip с . - void ClipToPath(GrPath *pPath, double *pMatrix, bool bEO); - - // Пересекаем с текстом - void ClipToText(std::wstring wsFontName, std::wstring wsFontPath, double dFontSize, int nFontStyle, double *pMatrix, std::wstring wsText, double dX, double dY, double dWidth, double dHeight, double dBaseLineOffset) - { - if (!m_pTextClip) - m_pTextClip = new GrTextClip(); - - m_pTextClip->ClipToText(wsFontName, wsFontPath, dFontSize, nFontStyle, pMatrix, wsText, dX, dY, dWidth, dHeight, dBaseLineOffset); - } - - // - void AppendTextClip(GrTextClip *pTextClip) - { - for (int nIndex = 0; nIndex < pTextClip->GetTextsCount(); nIndex++) - { - WString wsFontName, wsFontPath; - int nFontStyle; - double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0; - - WString wsText = pTextClip->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &nFontStyle); - double *pMatrix = pTextClip->GetMatrix(nIndex); - - ClipToText(std::wstring(wsFontName), std::wstring(wsFontPath), dFontSize, nFontStyle, pMatrix, std::wstring(wsText), dX, dY, dWidth, dHeight, dBaseLineOffset); - } - } - - int GetMinX() - { - return m_nMinX; - } - int GetMaxX() - { - return m_nMaxX; - } - int GetMinY() - { - return m_nMinY; - } - int GetMaxY() - { - return m_nMaxY; - } - - int GetPathsCount() - { - return m_nPathsCount; - } - - GrPath *GetPath(int nPathIndex) - { - if (nPathIndex < 0 || nPathIndex >= m_nPathsCount) - return NULL; - - return m_ppPaths[nPathIndex]; - } - double *GetMatrix(int nPathIndex) - { - if (nPathIndex < 0 || nPathIndex >= m_nPathsCount) - return NULL; - - return m_pMatrix[nPathIndex].ToDoublePointer(); - } - int GetFlag(int nPathIndex) - { - if (nPathIndex < 0 || nPathIndex >= m_nPathsCount) - return 0; - - return m_pFlags[nPathIndex]; - } - WString GetText(int nTextIndex, double *pdX, double *pdY, double *pdWidth, double *pdHeight, double *pdBaseLineOffset, WString* pwsFontName, WString* pwsFontPath, double *pdFontSize, int* pnFontStyle) - { - if (m_pTextClip) - { - return m_pTextClip->GetText(nTextIndex, pdX, pdY, pdWidth, pdHeight, pdBaseLineOffset, pwsFontName, pwsFontPath, pdFontSize, pnFontStyle); - } - - return NULL; - } - int GetTextsCount() - { - if (m_pTextClip) - { - return m_pTextClip->GetTextsCount(); - } - return -1; - } - double *GetTextMatrix(int nTextIndex) - { - if (m_pTextClip) - return m_pTextClip->GetMatrix(nTextIndex); - - return NULL; - } - - bool IsEqual(GrClip *pClip, int &nPathIndex) - { - bool bResult = true; - nPathIndex = -1; - - if (!m_pTextClip->IsEqual(pClip->m_pTextClip)) - return false; - - if (m_nPathsCount < pClip->m_nPathsCount) - bResult = false; - else if (m_nPathsCount > pClip->m_nPathsCount) - return false; - - - for (int nIndex = 0; nIndex < m_nPathsCount; nIndex++) - { - if (!m_pMatrix[nIndex].IsEqual(pClip->m_pMatrix[nIndex]) || m_pFlags[nIndex] != pClip->m_pFlags[nIndex] || !m_ppPaths[nIndex]->IsEqual(pClip->m_ppPaths[nIndex])) - return false; - } - - nPathIndex = m_nPathsCount; - - return bResult; - } - - private: - - GrClip(GrClip *pClip); - void Resize(int nPathsCount); - GrPath *PathRect(double dX0, double dY0, double dX1, double dY1); - void Transform(double *pMatrix, double dX, double dY, double *pdX, double *pdY) - { - *pdX = dX * pMatrix[0] + dY * pMatrix[2] + pMatrix[4]; - *pdY = dX * pMatrix[1] + dY * pMatrix[3] + pMatrix[5]; - } - - private: - -#pragma pack(push, 1) - struct Matrix - { - double dA; - double dB; - double dC; - double dD; - double dE; - double dF; - - double *ToDoublePointer() - { - return &dA; - } - - void FromDoublePointer(double *pMatrix) - { - dA = pMatrix[0]; - dB = pMatrix[1]; - dC = pMatrix[2]; - dD = pMatrix[3]; - dE = pMatrix[4]; - dF = pMatrix[5]; - } - - bool IsEqual(Matrix &oMatrix) - { - if (fabs(dA - oMatrix.dA) < 0.001 && fabs(dB - oMatrix.dB) < 0.001 && fabs(dC - oMatrix.dC) < 0.001 && fabs(dD - oMatrix.dD) < 0.001 && fabs(dE - oMatrix.dE) < 0.001 && fabs(dF - oMatrix.dF) < 0.001) - return true; - - return false; - } - - }; -#pragma pack(pop) - - private: - - double m_dMinX; - double m_dMinY; - double m_dMaxX; - double m_dMaxY; - - int m_nMinX; - int m_nMinY; - int m_nMaxX; - int m_nMaxY; - - GrPath **m_ppPaths; - Matrix *m_pMatrix; - unsigned char *m_pFlags; - int m_nPathsCount; - int m_nSize; - - GrTextClip *m_pTextClip; - }; - - - //------------------------------------------------------------------------------------------------------------------------------- - // GrState - //------------------------------------------------------------------------------------------------------------------------------- - - class GrState - { - public: - - GrState(double dHorizDPI, double dVertDPI, PDFRectangle *pPageBox, int nRotate, bool bUpsideDown); - - ~GrState(); - - GrState *Copy() - { - return new GrState(this); - } - - - double GetHorDPI() - { - return m_dHorDPI; - } - double GetVerDPI() - { - return m_dVerDPI; - } - double *GetCTM() - { - return m_arrCTM; - } - double GetPageLeft() - { - return m_dPageLeft; - } - double GetPageBottom() - { - return m_dPageBottom; - } - double GetPageRight() - { - return m_dPageRight; - } - double GetPageTop() - { - return m_dPageTop; - } - double GetPageWidth() - { - return m_dPageWidth; - } - double GetPageHeight() - { - return m_dPageHeight; - } - int GetRotate() - { - return m_nRotate; - } - GrColor *GetFillColor() - { - return &m_oFillColor; - } - GrColor *GetStrokeColor() - { - return &m_oStrokeColor; - } - void GetFillGray(GrGray *pGray) - { - m_pFillColorSpace->GetGray(&m_oFillColor, pGray); - } - void GetStrokeGray(GrGray *pGray) - { - m_pStrokeColorSpace->GetGray(&m_oStrokeColor, pGray); - } - void GetFillRGB(GrRGB *pRGB) - { - m_pFillColorSpace->GetRGB(&m_oFillColor, pRGB); - } - void GetStrokeRGB(GrRGB *pRGB) - { - m_pStrokeColorSpace->GetRGB(&m_oStrokeColor, pRGB); - } - void GetFillCMYK(GrCMYK *pCMYK) - { - m_pFillColorSpace->GetCMYK(&m_oFillColor, pCMYK); - } - void GetStrokeCMYK(GrCMYK *pCMYK) - { - m_pStrokeColorSpace->GetCMYK(&m_oStrokeColor, pCMYK); - } - GrColorSpace *GetFillColorSpace() - { - return m_pFillColorSpace; - } - GrColorSpace *GetStrokeColorSpace() - { - return m_pStrokeColorSpace; - } - GrPattern *GetFillPattern() - { - return m_pFillPattern; - } - GrPattern *GetStrokePattern() - { - return m_pStrokePattern; - } - GraphicsBlendMode GetBlendMode() - { - return m_eBlendMode; - } - double GetFillOpacity() - { - return m_dFillOpacity; - } - double GetStrokeOpacity() - { - return m_dStrokeOpacity; - } - bool GetFillOverprint() - { - return m_bFillOverprint; - } - bool GetStrokeOverprint() - { - return m_bStrokeOverprint; - } - Function **GetTransfer() - { - return m_ppTransfer; - } - double GetLineWidth() - { - return m_dLineWidth; - } - void GetLineDash(double **ppDash, int *pSize, double *pStart) - { - *ppDash = m_pLineDash; - *pSize = m_nLineDashSize; - *pStart = m_dLineDashStart; - } - int GetFlatness() - { - return m_nFlatness; - } - int GetLineJoin() - { - return m_nLineJoin; - } - int GetLineCap() - { - return m_nLineCap; - } - double GetMiterLimit() - { - return m_dMiterLimit; - } - bool GetStrokeAdjust() - { - return m_bStrokeAdjust; - } - GrFont *GetFont() - { - return m_pFont; - } - double GetFontSize() - { - return m_dFontSize; - } - double *GetTextMatrix() - { - return m_arrTextMatrix; - } - double GetCharSpace() - { - return m_dCharSpace; - } - double GetWordSpace() - { - return m_dWordSpace; - } - double GetHorizScaling() - { - return m_dHorizScaling; - } - double GetLeading() - { - return m_dLeading; - } - double GetRise() - { - return m_nRise; - } - int GetRenderMode() - { - return m_nRenderMode; - } - GrPath *GetPath() - { - return m_pPath; - } - double GetCurX() - { - return m_dCurX; - } - double GetCurY() - { - return m_dCurY; - } - void GetClipBBox(double *pXMin, double *pYMin, double *pXMax, double *pYMax) - { - *pXMin = m_dClipXMin; - *pYMin = m_dClipYMin; - *pXMax = m_dClipXMax; - *pYMax = m_dClipYMax; - } - void GetUserClipBBox(double *pXMin, double *pYMin, double *pXMax, double *pYMax); - double GetTextLineX() - { - return m_dTextLineX; - } - double GetTextLineY() - { - return m_dTextLineY; - } - - GrClip *GetClip() - { - return m_pClip; - } - // Есть ли текущая точка? - bool IsCurPoint() - { - return m_pPath->IsCurPoint(); - } - // Есть ли непустой path? - bool IsPathNonEmpty() - { - return m_pPath->IsPathNonEmpty(); - } - - // Различные преобразования координат. - void Transform(double dSrcX, double dSrcY, double *pdResX, double *pdResY) - { - *pdResX = m_arrCTM[0] * dSrcX + m_arrCTM[2] * dSrcY + m_arrCTM[4]; - *pdResY = m_arrCTM[1] * dSrcX + m_arrCTM[3] * dSrcY + m_arrCTM[5]; - } - void TransformDelta(double dSrcX, double dSrcY, double *pdResX, double *pdResY) - { - *pdResX = m_arrCTM[0] * dSrcX + m_arrCTM[2] * dSrcY; - *pdResY = m_arrCTM[1] * dSrcX + m_arrCTM[3] * dSrcY; - } - void TextTransform(double dSrcX, double dSrcY, double *pdResX, double *pdResY) - { - *pdResX = m_arrTextMatrix[0] * dSrcX + m_arrTextMatrix[2] * dSrcY + m_arrTextMatrix[4]; - *pdResY = m_arrTextMatrix[1] * dSrcX + m_arrTextMatrix[3] * dSrcY + m_arrTextMatrix[5]; - } - void TextTransformDelta(double dSrcX, double dSrcY, double *pdResX, double *pdResY) - { - *pdResX = m_arrTextMatrix[0] * dSrcX + m_arrTextMatrix[2] * dSrcY; - *pdResY = m_arrTextMatrix[1] * dSrcX + m_arrTextMatrix[3] * dSrcY; - } - double TransformWidth(double dWidth); - double GetTransformedLineWidth() - { - return TransformWidth(m_dLineWidth); - } - double GetTransformedFontSize(); - void GetFontTransformMatrix(double *pdM11, double *pdM12, double *pdM21, double *pdM22); - - void SetCTM(double dA, double dB, double dC, double dD, double dE, double dF); - void ConcatCTM(double dA, double dB, double dC, double dD, double dE, double dF); - void ShiftCTM(double dShiftX, double dShiftY); - void SetFillColorSpace(GrColorSpace *pColorSpace); - void SetStrokeColorSpace(GrColorSpace *pColorSpace); - void SetFillColor(GrColor *pColor) - { - m_oFillColor = *pColor; - } - void SetStrokeColor(GrColor *pColor) - { - m_oStrokeColor = *pColor; - } - void SetFillPattern(GrPattern *pPattern); - void SetStrokePattern(GrPattern *pPattern); - void SetBlendMode(GraphicsBlendMode eMode) - { - m_eBlendMode = eMode; - } - void SetFillOpacity(double dOpacity) - { - m_dFillOpacity = dOpacity; - } - void SetStrokeOpacity(double dOpacity) - { - m_dStrokeOpacity = dOpacity; - } - void SetFillOverprint(bool bOverprint) - { - m_bFillOverprint = bOverprint; - } - void SetStrokeOverprint(bool bOverprint) - { - m_bStrokeOverprint = bOverprint; - } - void SetTransfer(Function **ppFunctions); - void SetLineWidth(double dWidth) - { - m_dLineWidth = dWidth; - } - void SetLineDash(double *pDash, int nLength, double dStart); - void SetFlatness(int nFlatness) - { - m_nFlatness = nFlatness; - } - void SetLineJoin(int nLineJoin) - { - m_nLineJoin = nLineJoin; - } - void SetLineCap(int nLineCap) - { - m_nLineCap = nLineCap; - } - void SetMiterLimit(double dMiterLimit) - { - m_dMiterLimit = dMiterLimit; - } - void SetStrokeAdjust(bool bStrokeAdjust) - { - m_bStrokeAdjust = bStrokeAdjust; - } - void SetFont(GrFont *pFont, double dFontSize) - { - m_pFont = pFont; - m_dFontSize = dFontSize; - } - void SetTextMatrix(double dA, double dB, double dC, double dD, double dE, double dF) - { - m_arrTextMatrix[0] = dA; - m_arrTextMatrix[1] = dB; - m_arrTextMatrix[2] = dC; - m_arrTextMatrix[3] = dD; - m_arrTextMatrix[4] = dE; - m_arrTextMatrix[5] = dF; - } - void SetCharSpace(double dCharSpace) - { - m_dCharSpace = dCharSpace; - } - void SetWordSpace(double dWordSpace) - { - m_dWordSpace = dWordSpace; - } - void SetHorizScaling(double dScale) - { - m_dHorizScaling = 0.01 * dScale; - } - void SetLeading(double dLeading) - { - m_dLeading = dLeading; - } - void SetRise(double dRise) - { - m_nRise = dRise; - } - void SetRenderMode(int nRenderMode) - { - m_nRenderMode = nRenderMode; - } - void SetPath(GrPath *pPath); - void MoveTo(double dX, double dY) - { - m_pPath->MoveTo(m_dCurX = dX, m_dCurY = dY); - } - void LineTo(double dX, double dY) - { - m_pPath->LineTo(m_dCurX = dX, m_dCurY = dY); - } - void CurveTo(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3) - { - m_pPath->CurveTo(dX1, dY1, dX2, dY2, m_dCurX = dX3, m_dCurY = dY3); - } - void ClosePath() - { - m_pPath->Close(); - m_dCurX = m_pPath->GetLastX(); - m_dCurY = m_pPath->GetLastY(); - } - void ClearPath(); - void Clip(); - void ClipToStrokePath(); - - // Текст. - void TextSetPos(double dX, double dY) - { - m_dTextLineX = dX; - m_dTextLineY = dY; - } - void TextMoveTo(double dX, double dY) - { - m_dTextLineX = dX; - m_dTextLineY = dY; - TextTransform(dX, dY, &m_dCurX, &m_dCurY); - } - void TextShift(double dShiftX, double dShiftY); - void Shift(double dShidtX, double dShiftY); - - // Работа со стеком. - GrState *Save(); - GrState *Restore(); - bool HasSaves() - { - return m_pNext != NULL; - } - - // - bool ParseBlendMode(Object *pObject, GraphicsBlendMode *peMode); - - private: - - GrState(GrState *pState); - - private: - - double m_dHorDPI; // Разрешение по горизонтали - double m_dVerDPI; // Разрешение по вертикали - double m_arrCTM[6]; // Матрица преобразования координат - - double m_dPageLeft; // Координаты левого нижнего угла и - double m_dPageBottom; // правого верхнего в пользовательстких координатах - double m_dPageRight; // - double m_dPageTop; // - - double m_dPageWidth; // Ширина страницы в пикселях(т.е. с учетом разрешения m_dHorDPI) - double m_dPageHeight; // Высота страницы в пикселях(т.е. с учетом разрешения m_dVerDPI) - - int m_nRotate; // Угол поворота страницы - - GrColorSpace *m_pFillColorSpace; // Цветовое пространство для заливки - GrColorSpace *m_pStrokeColorSpace;// Цветовое пространство для обводки - GrColor m_oFillColor; // Цвет для заливки - GrColor m_oStrokeColor; // Цвет для обводки - GrPattern *m_pFillPattern; // Указатель на объект, определяющий заливку - GrPattern *m_pStrokePattern; // Указатель на объект, определяющий обводку - - GraphicsBlendMode m_eBlendMode; // Blend mode (для прозрачности) - - double m_dFillOpacity; // Прозрачность заливки - double m_dStrokeOpacity; // Прозрачность обводки - - bool m_bFillOverprint; // Заливаем поверх всего? - bool m_bStrokeOverprint; // Обводим поверх всего? - Function *m_ppTransfer[4]; // Функция переноса. Варианты входных параметров: - // все NULL = тождествнная функция; - // последние три NULL = одномерная функция; - // все 4 не NULL = R,G,B,gray -функция - - double m_dLineWidth; // Толщина линии - double *m_pLineDash; // Параметры, если линия пунктирная - int m_nLineDashSize; // Размер массива m_pLineDash - double m_dLineDashStart;// - int m_nFlatness; // Flatness Tolerance - int m_nLineJoin; // Тип соединения линий - int m_nLineCap; // Тип оконачния линий - double m_dMiterLimit; // Miter limit - bool m_bStrokeAdjust; // True, автоматически обводить - - GrFont *m_pFont; // Шрифт - double m_dFontSize; // Размер шрифта - double m_arrTextMatrix[6]; // Матрица координатных преобразований текста - double m_dCharSpace; // Расстояние между символами - double m_dWordSpace; // Расстояние между словами - double m_dHorizScaling; // Горизонтальное растяжение текста - double m_dLeading; // Расстояние между строками - double m_nRise; // Поднятие/опускание текста относительно baseline - int m_nRenderMode; // Способ рисования букв - - GrPath *m_pPath; // Массив графических Path - double m_dCurX; // Координаты текущей точки - double m_dCurY; // (в пользовательских координатах) - double m_dTextLineX; // Координаты начальной точки, начиная с которой пишется текст - double m_dTextLineY; // (в текстовых координатах) - - GrClip *m_pClip; - double m_dClipXMin; // - double m_dClipYMin; // Границы для clip region - double m_dClipXMax; // - double m_dClipYMax; // - - GrState *m_pNext; // Следующий GrState в стэке - }; -} -#endif // _PDF_READER_GSTATE_H diff --git a/PdfReader/old/GlobalParams.cpp b/PdfReader/old/GlobalParams.cpp deleted file mode 100644 index 0205ba1a58..0000000000 --- a/PdfReader/old/GlobalParams.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include - -#include "MemoryUtils.h" -#include "StringExt.h" -#include "Constants.h" -#include "List.h" -#include "Hash.h" -#include "File.h" -#include "NameToCharCode.h" -#include "CharCodeToUnicode.h" -#include "UnicodeMap.h" -#include "CMap.h" -#include "BuiltinFontTables.h" -#include "EncodingTables.h" -#include "GlobalParams.h" -#include "NameToUnicodeTable.h" -#include "UnicodeMapTables.h" -#include "UTF8.h" - -#include "../Resources/Fontn022003l.h" -#include "../Resources/Fontn022004l.h" -#include "../Resources/Fontn022024l.h" -#include "../Resources/Fontn022023l.h" -#include "../Resources/Fontn019003l.h" -#include "../Resources/Fontn019004l.h" -#include "../Resources/Fontn019024l.h" -#include "../Resources/Fontn019023l.h" -#include "../Resources/Fonts050000l.h" -#include "../Resources/Fontn021004l.h" -#include "../Resources/Fontn021024l.h" -#include "../Resources/Fontn021023l.h" -#include "../Resources/Fontn021003l.h" -#include "../Resources/Fontd050000l.h" - -#define cidToUnicodeCacheSize 4 -#define unicodeToUnicodeCacheSize 4 - -namespace PdfReader -{ - static struct - { - char* sName; - wchar_t* wsT1FileName; - wchar_t* wsTTFileName; - const unsigned char* pT1Buffer; - const unsigned int unSize; - } c_arrBase14FontTable[] = - { - { "Courier", L"n022003l.pfb", L"cour.ttf", c_arrn022003l, c_nSizen022003l}, - { "Courier-Bold", L"n022004l.pfb", L"courbd.ttf", c_arrn022004l, c_nSizen022004l}, - { "Courier-BoldOblique", L"n022024l.pfb", L"courbi.ttf", c_arrn022024l, c_nSizen022024l}, - { "Courier-Oblique", L"n022023l.pfb", L"couri.ttf", c_arrn022023l, c_nSizen022023l}, - { "Helvetica", L"n019003l.pfb", L"arial.ttf", c_arrn019003l, c_nSizen019003l}, - { "Helvetica-Bold", L"n019004l.pfb", L"arialbd.ttf", c_arrn019004l, c_nSizen019004l}, - { "Helvetica-BoldOblique", L"n019024l.pfb", L"arialbi.ttf", c_arrn019024l, c_nSizen019024l}, - { "Helvetica-Oblique", L"n019023l.pfb", L"ariali.ttf", c_arrn019023l, c_nSizen019023l}, - { "Symbol", L"s050000l.pfb", NULL, c_arrs050000l, c_nSizes050000l}, - { "Times-Bold", L"n021004l.pfb", L"timesbd.ttf", c_arrn021004l, c_nSizen021004l}, - { "Times-BoldItalic", L"n021024l.pfb", L"timesbi.ttf", c_arrn021024l, c_nSizen021024l}, - { "Times-Italic", L"n021023l.pfb", L"timesi.ttf", c_arrn021023l, c_nSizen021023l}, - { "Times-Roman", L"n021003l.pfb", L"times.ttf", c_arrn021003l, c_nSizen021003l}, - { "ZapfDingbats", L"d050000l.pfb", NULL, c_arrd050000l, c_nSized050000l}, - { NULL, NULL, NULL, NULL, 0 } - }; - //------------------------------------------------------------------------------------------------------------------------------- - // GlobalParams - //------------------------------------------------------------------------------------------------------------------------------- - GlobalParams::GlobalParams() : m_pFontManager(NULL) - { - // Просматриваем кодировку в обратном порядке, чтобы присвоить символу наименьше возможный номер - // (если у символа их несколько, например, как у 'space') - m_pMacRomanReverseMap = new NameToCharCode(); - for (int nIndex = 255; nIndex >= 0; --nIndex) - { - if (c_arrMacRomanEncoding[nIndex]) - { - m_pMacRomanReverseMap->Add(c_arrMacRomanEncoding[nIndex], (CharCode)nIndex); - } - } - - // Инициализируем талицу m_pNameToUnicode - m_pNameToUnicode = new NameToCharCode(); - for (int nIndex = 0; c_arrNameToUnicodeTable[nIndex].sName; ++nIndex) - { - m_pNameToUnicode->Add(c_arrNameToUnicodeTable[nIndex].sName, c_arrNameToUnicodeTable[nIndex].nUnicode); - } - - m_bMapNumericCharNames = true; - m_bMapUnknownCharNames = false; - m_pCMapCache = new CMapCache(); - m_wsTempDirectory = L""; - } - GlobalParams::~GlobalParams() - { - if (m_pMacRomanReverseMap) - delete m_pMacRomanReverseMap; - - if (m_pNameToUnicode) - delete m_pNameToUnicode; - - if (m_pCMapCache) - delete m_pCMapCache; - } - bool GlobalParams::GetMapNumericCharNames() - { - return m_bMapNumericCharNames; - } - bool GlobalParams::GetMapUnknownCharNames() - { - return m_bMapUnknownCharNames; - } - void GlobalParams::SetMapNumericCharNames(bool bMap) - { - m_bMapNumericCharNames = bMap; - } - void GlobalParams::SetMapUnknownCharNames(bool bMap) - { - m_bMapUnknownCharNames = bMap; - } - CharCode GlobalParams::GetMacRomanCharCode(char* sCharName) - { - return m_pMacRomanReverseMap->Lookup(sCharName); - } - CharCodeToUnicode* GlobalParams::GetUnicodeToUnicode(StringExt* seFontName) - { - // TODO: Как только будем хранить отдельную папку с файлами Unicode to Unicode реализовать тут - return NULL; - } - CharCodeToUnicode* GlobalParams::GetCIDToUnicode(StringExt* seCollection) - { - // TODO: Как только будем хранить отдельную папку с файлами Cid to Unicode реализовать тут - return NULL; - } - Unicode GlobalParams::MapNameToUnicode(char* sCharName) - { - return m_pNameToUnicode->Lookup(sCharName); - } - CMap* GlobalParams::GetCMap(StringExt* seCollection, StringExt* seCMapName, wchar_t* wsFilePath) - { - return m_pCMapCache->GetCMap(seCollection, seCMapName, this, wsFilePath); - } - FILE* GlobalParams::FindToUnicodeFile(StringExt* seName) - { - // TODO: Как только будем хранить отдельную папку с файлами ToUnicode реализовать тут - return NULL; - } - FILE* GlobalParams::FindCMapFile(StringExt* seCollection, StringExt* seCMapName) - { - if (m_wsCMapDirectory != L"") - { - std::wstring wsFilePath = m_wsCMapDirectory + seCMapName->GetWString(); - return NSFile::CFileBinary::OpenFileNative(wsFilePath, L"rb"); - } - - return NULL; - } - FILE* GlobalParams::GetUnicodeMapFile(StringExt* seEncodingName) - { - // Как только будем работать с папкой UnicodeMap реализовать тут - return NULL; - } - std::wstring& GlobalParams::GetTempFolder() - { - return m_wsTempDirectory; - } - void GlobalParams::SetTempFolder(const wchar_t* wsTempFolder) - { - if (wsTempFolder) - { - m_wsTempDirectory = wsTempFolder; - - // В темповую директорию скидываем 14 стандартных шрифтов - for (int nIndex = 0; nIndex < 14; nIndex++) - { - std::wstring wsFontPath; - FILE* pFile = NULL; - if (!NSFile::CFileBinary::OpenTempFile(&wsFontPath, &pFile, L"wb", L".base", (wchar_t*)wsTempFolder, NULL)) - continue; - fclose(pFile); - - NSFile::CFileBinary oFile; - oFile.CreateFileW(wsFontPath); - oFile.WriteFile((BYTE*)c_arrBase14FontTable[nIndex].pT1Buffer, c_arrBase14FontTable[nIndex].unSize); - oFile.CloseFile(); - m_arrBuiltinFontsPath[nIndex] = wsFontPath; - } - } - else - m_wsTempDirectory = L""; - } - std::wstring GlobalParams::FindFontFile(StringExt* seFontName, wchar_t** pwsExts) - { - // TODO: Возможно стоит перенести сюда подбор шрифтов - return L""; - } - void GlobalParams::SetCMapFolder(const wchar_t* wsCMapDir) - { - if (wsCMapDir) - m_wsCMapDirectory = wsCMapDir; - else - m_wsCMapDirectory = L""; - } - void GlobalParams::SetFontManager(NSFonts::IFontManager* pFontManager) - { - m_pFontManager = pFontManager; - } - NSFonts::IFontManager* GlobalParams::GetFontManager() const - { - return m_pFontManager; - } - std::wstring GlobalParams::GetBuiltinFontPath(StringExt* seFontName) const - { - int nIndex = 0; - for (nIndex = 0; nIndex < 14; nIndex++) - { - if (0 == seFontName->Compare(c_arrBase14FontTable[nIndex].sName)) - break; - } - - if (nIndex < 14) - return m_arrBuiltinFontsPath[nIndex]; - - return L""; - } -} diff --git a/PdfReader/old/GlobalParams.h b/PdfReader/old/GlobalParams.h deleted file mode 100644 index 97450b3e4d..0000000000 --- a/PdfReader/old/GlobalParams.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_GLOBAL_PARAMS_H -#define _PDF_READER_GLOBAL_PARAMS_H - -#include -#include - -#include "CharTypes.h" - -#include "../../DesktopEditor/graphics/TemporaryCS.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" - -namespace PdfReader -{ - class StringExt; - class CList; - class CHash; - class NameToCharCode; - class CharCodeToUnicode; - class CharCodeToUnicodeCache; - class UnicodeMap; - class UnicodeMapCache; - class CMap; - class CMapCache; - class GlobalParams; - //------------------------------------------------------------------------------------------------------------------------------- - // GlobalParams - //------------------------------------------------------------------------------------------------------------------------------- - class GlobalParams - { - public: - - GlobalParams(); - ~GlobalParams(); - - bool GetMapNumericCharNames(); - bool GetMapUnknownCharNames(); - void SetMapNumericCharNames(bool bMap); - void SetMapUnknownCharNames(bool bMap); - CharCode GetMacRomanCharCode(char* sCharName); - CharCodeToUnicode* GetUnicodeToUnicode(StringExt* seFontName); - CharCodeToUnicode* GetCIDToUnicode(StringExt* seCollection); - Unicode MapNameToUnicode(char* sCharName); - CMap* GetCMap(StringExt* seCollection, StringExt* seCMapName, wchar_t* wsFilePath = NULL); - FILE* FindToUnicodeFile(StringExt* seName); - FILE* FindCMapFile(StringExt *seCollection, StringExt *seCMapName); - FILE* GetUnicodeMapFile(StringExt* seEncodingName); - std::wstring& GetTempFolder(); - void SetTempFolder(const wchar_t* wsTempFolder); - std::wstring FindFontFile(StringExt* seFontName, wchar_t** pwsExts); - void SetCMapFolder(const wchar_t* wsDir); - void SetFontManager(NSFonts::IFontManager* pFontManager); - NSFonts::IFontManager* GetFontManager() const; - std::wstring GetBuiltinFontPath(StringExt* seFontName) const; - - private: - - bool m_bMapNumericCharNames; // Map numeric char names (from font subsets)? - bool m_bMapUnknownCharNames; // Map unknown char names? - - NameToCharCode* m_pMacRomanReverseMap; // Char name -> MacRomanEncoding - NameToCharCode* m_pNameToUnicode; // Char name -> Unicode - - CMapCache* m_pCMapCache; - std::wstring m_wsCMapDirectory; // Путь к папке с CMap файлами - std::wstring m_wsTempDirectory; - - NSFonts::IFontManager* m_pFontManager; - std::wstring m_arrBuiltinFontsPath[14]; // Пути к стандартным 14 шрифтам - }; -} - -#endif // _PDF_READER_GLOBAL_PARAMS_H diff --git a/PdfReader/old/Graphics.cpp b/PdfReader/old/Graphics.cpp deleted file mode 100644 index 5593536108..0000000000 --- a/PdfReader/old/Graphics.cpp +++ /dev/null @@ -1,5147 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "GlobalParams.h" -#include "CharTypes.h" -#include "Object.h" -#include "Array.h" -#include "Dict.h" -#include "Stream.h" -#include "Lexer.h" -#include "Parser.h" -#include "GFont.h" -#include "GState.h" -#include "RendererOutputDev.h" -#include "OutputDevice.h" -#include "Page.h" -#include "Annot.h" -#include "Graphics.h" - -// Под виндой переопределяется -#ifdef GetObject -#undef GetObject -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -//------------------------------------------------------------------------------------------------------------------------------- -// Константы -//------------------------------------------------------------------------------------------------------------------------------- - -#define functionMaxDepth 6 - -#define functionColorDelta (DoubleToColor(1 / 256.0)) - -#define axialMaxSplits 256 - -#define axialColorDelta (DoubleToColor(1 / 256.0)) - -#define radialMaxSplits 256 - -#define radialColorDelta (DoubleToColor(1 / 256.0)) - -#define gouraudMaxDepth 1 - -#define gouraudColorDelta (DoubleToColor(1 / 256.0)) - -#define patchMaxDepth 6 - -#define patchColorDelta (DoubleToColor(1 / 256.0)) - -//------------------------------------------------------------------------------------------------------------------------------- -// Таблица графических операторов -//------------------------------------------------------------------------------------------------------------------------------- - -#ifdef WIN32 // this works around a bug in the VC7 compiler -# pragma optimize("",off) -#endif - -namespace PdfReader -{ - Operator Graphics::OperatorsTable[] = - { - { "\"", 3, { argNum, argNum, argString }, &Graphics::OperatorMoveSetShowText }, - { "'", 1, { argString }, &Graphics::OperatorMoveShowText }, - { "B", 0, { argNone }, &Graphics::OperatorFillStroke }, - { "B*", 0, { argNone }, &Graphics::OperatorEOFillStroke }, - { "BDC", 2, { argName, argProps }, &Graphics::OperatorBeginMarkedContent }, - { "BI", 0, { argNone }, &Graphics::OperatorBeginImage }, - { "BMC", 1, { argName }, &Graphics::OperatorBeginMarkedContent }, - { "BT", 0, { argNone }, &Graphics::OperatorBeginText }, - { "BX", 0, { argNone }, &Graphics::OperatorBeginIgnoreUndef }, - { "CS", 1, { argName }, &Graphics::OperatorSetStrokeColorSpace }, - { "DP", 2, { argName, argProps }, &Graphics::OperatorMarkPoint }, - { "Do", 1, { argName }, &Graphics::OperatorXObject }, - { "EI", 0, { argNone }, &Graphics::OperatorEndImage }, - { "EMC", 0, { argNone }, &Graphics::OperatorEndMarkedContent }, - { "ET", 0, { argNone }, &Graphics::OperatorEndText }, - { "EX", 0, { argNone }, &Graphics::OperatorEndIgnoreUndef }, - { "F", 0, { argNone }, &Graphics::OperatorFill }, - { "G", 1, { argNum }, &Graphics::OperatorSetStrokeGray }, - { "ID", 0, { argNone }, &Graphics::OperatorImageData }, - { "J", 1, { argInt }, &Graphics::OperatorSetLineCap }, - { "K", 4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorSetStrokeCMYKColor }, - { "M", 1, { argNum }, &Graphics::OperatorSetMiterLimit }, - { "MP", 1, { argName }, &Graphics::OperatorMarkPoint }, - { "Q", 0, { argNone }, &Graphics::OperatorRestore }, - { "RG", 3, { argNum, argNum, argNum }, &Graphics::OperatorSetStrokeRGBColor }, - { "S", 0, { argNone }, &Graphics::OperatorStroke }, - { "SC", -4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorSetStrokeColor }, - { "SCN", -33, { argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN }, &Graphics::OperatorSetStrokeColorN }, - { "T*", 0, { argNone }, &Graphics::OperatorTextNextLine }, - { "TD", 2, { argNum, argNum }, &Graphics::OperatorTextMoveSet }, - { "TJ", 1, { argArray }, &Graphics::OperatorShowSpaceText }, - { "TL", 1, { argNum }, &Graphics::OperatorSetTextLeading }, - { "Tc", 1, { argNum }, &Graphics::OperatorSetCharSpacing }, - { "Td", 2, { argNum, argNum }, &Graphics::OperatorTextMove }, - { "Tf", 2, { argName, argNum }, &Graphics::OperatorSetFont }, - { "Tj", 1, { argString }, &Graphics::OperatorShowText }, - { "Tm", 6, { argNum, argNum, argNum, argNum, argNum, argNum }, &Graphics::OperatorSetTextMatrix }, - { "Tr", 1, { argInt }, &Graphics::OperatorSetTextRender }, - { "Ts", 1, { argNum }, &Graphics::OperatorSetTextRise }, - { "Tw", 1, { argNum }, &Graphics::OperatorSetWordSpacing }, - { "Tz", 1, { argNum }, &Graphics::OperatorSetHorizScaling }, - { "W", 0, { argNone }, &Graphics::OperatorClip }, - { "W*", 0, { argNone }, &Graphics::OperatorEOClip }, - { "b", 0, { argNone }, &Graphics::OperatorCloseFillStroke }, - { "b*", 0, { argNone }, &Graphics::OperatorCloseEOFillStroke }, - { "c", 6, { argNum, argNum, argNum, argNum, argNum, argNum }, &Graphics::OperatorCurveTo }, - { "cm", 6, { argNum, argNum, argNum, argNum, argNum, argNum }, &Graphics::OperatorConcat }, - { "cs", 1, { argName }, &Graphics::OperatorSetFillColorSpace }, - { "d", 2, { argArray, argNum }, &Graphics::OperatorSetDash }, - { "d0", 2, { argNum, argNum }, &Graphics::OperatorSetCharWidth }, - { "d1", 6, { argNum, argNum, argNum, argNum, argNum, argNum }, &Graphics::OperatorSetCacheDevice }, - { "f", 0, { argNone }, &Graphics::OperatorFill }, - { "f*", 0, { argNone }, &Graphics::OperatorEOFill }, - { "g", 1, { argNum }, &Graphics::OperatorSetFillGray }, - { "gs", 1, { argName }, &Graphics::OperatorSetExtGState }, - { "h", 0, { argNone }, &Graphics::OperatorClosePath }, - { "i", 1, { argNum }, &Graphics::OperatorSetFlat }, - { "j", 1, { argInt }, &Graphics::OperatorSetLineJoin }, - { "k", 4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorSetFillCMYKColor }, - { "l", 2, { argNum, argNum }, &Graphics::OperatorLineTo }, - { "m", 2, { argNum, argNum }, &Graphics::OperatorMoveTo }, - { "n", 0, { argNone }, &Graphics::OperatorEndPath }, - { "q", 0, { argNone }, &Graphics::OperatorSave }, - { "re", 4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorRectangle }, - { "rg", 3, { argNum, argNum, argNum }, &Graphics::OperatorSetFillRGBColor }, - { "ri", 1, { argName }, &Graphics::OperatorSetRenderingIntent }, - { "s", 0, { argNone }, &Graphics::OperatorCloseStroke }, - { "sc", -4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorSetFillColor }, - { "scn", -33, { argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN, argSCN, argSCN, argSCN, - argSCN, argSCN, argSCN }, &Graphics::OperatorSetFillColorN }, - { "sh", 1, { argName }, &Graphics::OperatorShadingFill }, - { "v", 4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorCurveTo1 }, - { "w", 1, { argNum }, &Graphics::OperatorSetLineWidth }, - { "y", 4, { argNum, argNum, argNum, argNum }, &Graphics::OperatorCurveTo2 }, - }; - -#ifdef WIN32 // this works around a bug in the VC7 compiler -# pragma optimize("",on) -#endif - -#define OperatorsCount (sizeof(OperatorsTable) / sizeof(Operator)) - - //------------------------------------------------------------------------------------------------------------------------------- - // GrResources - //------------------------------------------------------------------------------------------------------------------------------- - - GrResources::GrResources(XRef *pXref, Dict *pResourcesDict, GrResources *pNext, GlobalParams *pGlobalParams) - { - m_pGlobalParams = pGlobalParams; - - if (pResourcesDict) - { - - // build font dictionary - m_pFonts = NULL; - Object oFont; - pResourcesDict->SearchAndCopy("Font", &oFont); - if (oFont.IsRef()) - { - Object oTemp; - oFont.Fetch(pXref, &oTemp); - if (oTemp.IsDict()) - { - Ref oRef = oFont.GetRef(); - m_pFonts = new GrFontDict(pXref, &oRef, oTemp.GetDict(), pGlobalParams); - } - oTemp.Free(); - } - else if (oFont.IsDict()) - { - m_pFonts = new GrFontDict(pXref, NULL, oFont.GetDict(), pGlobalParams); - } - oFont.Free(); - - //XObject - pResourcesDict->Search("XObject", &m_oXObjectDict); - - //ColorSpace - pResourcesDict->Search("ColorSpace", &m_oColorSpaceDict); - - //Pattern - pResourcesDict->Search("Pattern", &m_oPatternDict); - - //Shading - pResourcesDict->Search("Shading", &m_oShadingDict); - - //ExtGState - pResourcesDict->Search("ExtGState", &m_oExtGStateDict); - } - else - { - m_pFonts = NULL; - m_oXObjectDict.InitNull(); - m_oColorSpaceDict.InitNull(); - m_oPatternDict.InitNull(); - m_oShadingDict.InitNull(); - m_oExtGStateDict.InitNull(); - } - - m_pNext = pNext; - } - - GrResources::~GrResources() - { - if (m_pFonts) - { - delete m_pFonts; - } - m_oXObjectDict.Free(); - m_oColorSpaceDict.Free(); - m_oPatternDict.Free(); - m_oShadingDict.Free(); - m_oExtGStateDict.Free(); - } - - GrFont *GrResources::LookupFont(char *sName) - { - GrFont *pFont = NULL; - GrResources *pResources = NULL; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_pFonts) - { - if ((pFont = pResources->m_pFonts->Search(sName))) - return pFont; - } - } - // TO DO: Error "Unknown font tag" - return NULL; - } - - bool GrResources::LookupXObject(char *sName, Object *pObject) - { - GrResources *pResources = NULL; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oXObjectDict.IsDict()) - { - if (!pResources->m_oXObjectDict.DictLookup(sName, pObject)->IsNull()) - return true; - pObject->Free(); - } - } - // TO DO: Error "XObject is unknown" - return false; - } - - bool GrResources::LookupAndCopyXObject(char *sName, Object *pObject) - { - GrResources *pResources = NULL; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oXObjectDict.IsDict()) - { - if (!pResources->m_oXObjectDict.DictLookupAndCopy(sName, pObject)->IsNull()) - return true; - pObject->Free(); - } - } - // TO DO: Error "XObject is unknown" - return false; - } - - void GrResources::LookupColorSpace(char *sName, Object *pObject) - { - GrResources *pResources = NULL; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oColorSpaceDict.IsDict()) - { - if (!pResources->m_oColorSpaceDict.DictLookup(sName, pObject)->IsNull()) - { - return; - } - pObject->Free(); - } - } - pObject->InitNull(); - } - - GrPattern *GrResources::LookupPattern(char *sName) - { - GrResources *pResources = NULL; - GrPattern *pPattern = NULL; - Object oTemp; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oPatternDict.IsDict()) - { - if (!pResources->m_oPatternDict.DictLookup(sName, &oTemp)->IsNull()) - { - pPattern = GrPattern::Parse(&oTemp); - oTemp.Free(); - return pPattern; - } - oTemp.Free(); - } - } - // TO DO: Error "Unknown pattern" - return NULL; - } - - GrShading *GrResources::LookupShading(char *sName) - { - GrResources *pResources = NULL; - GrShading *pShading = NULL; - Object oTemp; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oShadingDict.IsDict()) - { - if (!pResources->m_oShadingDict.DictLookup(sName, &oTemp)->IsNull()) - { - pShading = GrShading::Parse(&oTemp); - oTemp.Free(); - return pShading; - } - oTemp.Free(); - } - } - // TO DO: Error "Unknown shading" - return NULL; - } - - bool GrResources::LookupExtGState(char *sName, Object *pObject) - { - GrResources *pResources = NULL; - - for (pResources = this; pResources; pResources = pResources->m_pNext) - { - if (pResources->m_oExtGStateDict.IsDict()) - { - if (!pResources->m_oExtGStateDict.DictLookup(sName, pObject)->IsNull()) - { - return true; - } - pObject->Free(); - } - } - // TO DO: Error "ExtGState is unknown" - return false; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Graphics - //------------------------------------------------------------------------------------------------------------------------------- - - Graphics::Graphics(GlobalParams *pGlobalParams, XRef *pXref, OutputDev *pOut, int nPageNumber, Dict *pResorcesDict, double dHorDPI, double dVerDPI, PDFRectangle *pBox, PDFRectangle *pCropBox, int nRotate, bool(*pAbortCheckCallBack)(void *pData), void *pAbortCheckData) - { -#ifdef _DEBUG - std::wstring wsFileName = L"D:\\Ilya\\Work\\Test\\PdfDump\\Dump" + std::to_wstring(nPageNumber) + L".bin"; - m_pDumpFile = NSFile::CFileBinary::OpenFileNative(wsFileName, L"wb"); -#endif - - m_pGlobalParams = pGlobalParams; - - m_pXref = pXref; - m_bSubPage = false; - - // Resource stack - m_pResources = new GrResources(m_pXref, pResorcesDict, NULL, m_pGlobalParams); - - // Initialize - m_pOut = pOut; - m_pGState = new GrState(dHorDPI, dVerDPI, pBox, nRotate, m_pOut->UpSideDown()); - m_bFontChanged = false; - m_eClip = clipNone; - m_nIgnoreUndef = 0; - m_pOut->StartPage(nPageNumber, m_pGState); - m_pOut->SetDefaultCTM(m_pGState->GetCTM()); - m_pOut->UpdateAll(m_pGState); - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrBaseMatrix[nIndex] = m_pGState->GetCTM()[nIndex]; - } - m_nFormDepth = 0; - m_pAbortCheckCallBack = pAbortCheckCallBack; - m_pAbortCheckData = pAbortCheckData; - - if (pCropBox) - { - m_pGState->MoveTo(pCropBox->m_dLeft, pCropBox->m_dBottom); - m_pGState->LineTo(pCropBox->m_dRight, pCropBox->m_dBottom); - m_pGState->LineTo(pCropBox->m_dRight, pCropBox->m_dTop); - m_pGState->LineTo(pCropBox->m_dLeft, pCropBox->m_dTop); - m_pGState->ClosePath(); - m_pGState->Clip(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - - m_pGState->ClearPath(); - } - } - - Graphics::Graphics(GlobalParams *pGlobalParams, XRef *pXref, OutputDev *pOut, Dict *pResorcesDict, PDFRectangle *pBox, PDFRectangle *pCropBox, bool(*pAbortCheckCallBack)(void *pData), void *pAbortCheckData) - { -#ifdef _DEBUG - m_pDumpFile = NULL; -#endif - - m_pGlobalParams = pGlobalParams; - - m_pXref = pXref; - m_bSubPage = true; - - // Resource stack - m_pResources = new GrResources(m_pXref, pResorcesDict, NULL, m_pGlobalParams); - - // Initialize - m_pOut = pOut; - m_pGState = new GrState(72, 72, pBox, 0, false); - m_bFontChanged = false; - m_eClip = clipNone; - m_nIgnoreUndef = 0; - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrBaseMatrix[nIndex] = m_pGState->GetCTM()[nIndex]; - } - - m_nFormDepth = 0; - m_pAbortCheckCallBack = pAbortCheckCallBack; - m_pAbortCheckData = pAbortCheckData; - - if (pCropBox) - { - m_pGState->MoveTo(pCropBox->m_dLeft, pCropBox->m_dBottom); - m_pGState->LineTo(pCropBox->m_dRight, pCropBox->m_dBottom); - m_pGState->LineTo(pCropBox->m_dRight, pCropBox->m_dTop); - m_pGState->LineTo(pCropBox->m_dLeft, pCropBox->m_dTop); - m_pGState->ClosePath(); - m_pGState->Clip(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - - m_pGState->ClearPath(); - } - } - - Graphics::~Graphics() - { -#ifdef _DEBUG - - if (m_pDumpFile) - ::fclose(m_pDumpFile); - -#endif - while (m_pGState->HasSaves()) - { - RestoreGState(); - } - if (!m_bSubPage) - { - m_pOut->EndPage(); - } - while (m_pResources) - { - PopResources(); - } - if (m_pGState) - { - delete m_pGState; - } - } - - void Graphics::Display(Object *pObject, bool bTopLevel) - { - if (pObject->IsArray()) - { - for (int nIndex = 0; nIndex < pObject->ArrayGetLength(); ++nIndex) - { - Object oTemp; - pObject->ArrayGet(nIndex, &oTemp); - if (!oTemp.IsStream()) - { - // TO DO: Error "Weird page contents" - oTemp.Free(); - return; - } - oTemp.Free(); - } - } - else if (!pObject->IsStream()) - { - // TO DO: Error "Weird page contents" - return; - } - m_pParser = new Parser(m_pXref, new Lexer(m_pXref, pObject), false); - if (NULL == m_pParser) - return; - StartParse(bTopLevel); - delete m_pParser; - m_pParser = NULL; - } - - void Graphics::StartParse(bool bTopLevel) - { - Object arrArguments[maxArgs]; - int nArgumentsCount = 0; - int nLastAbortCheck = 0; - - m_nUpdateLevel = 0; - - Object oTemp; - m_pParser->GetObject(&oTemp); - while (!oTemp.IsEOF()) - { - if (m_pOut && m_pOut->IsStopped()) - break; - - if (oTemp.IsCommand()) // Если получили команду, тогда выполняем ее - { - // Тут распечатываются посланные команды - -#ifdef _DEBUG - if (m_pDumpFile) - { - oTemp.Print(m_pDumpFile); - for (int nIndex = 0; nIndex < nArgumentsCount; nIndex++) - { - ::fprintf(m_pDumpFile, " "); - arrArguments[nIndex].Print(m_pDumpFile); - } - ::fprintf(m_pDumpFile, "\n"); - ::fflush(m_pDumpFile); - } -#endif - - ExecuteOperator(&oTemp, arrArguments, nArgumentsCount); - oTemp.Free(); - - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - arrArguments[nIndex].Free(); - nArgumentsCount = 0; - - // Производим переодические обновления того что выводим - if (++m_nUpdateLevel >= 20000) - { - m_pOut->Dump(); - m_nUpdateLevel = 0; - } - - // Проверяем отмену - if (m_pAbortCheckCallBack) - { - if (m_nUpdateLevel - nLastAbortCheck > 10) - { - if ((*m_pAbortCheckCallBack)(m_pAbortCheckData)) - { - break; - } - nLastAbortCheck = m_nUpdateLevel; - } - } - } - else if (nArgumentsCount < maxArgs) // Считываем аргумент - { - arrArguments[nArgumentsCount++] = oTemp; - } - else // Аргументов слишком много, значит что-то неправильно - { - // TO DO: Error "Too many args in content stream" -#ifdef _DEBUG - if (m_pDumpFile) - { - ::fprintf(m_pDumpFile, "throwing away arg: "); - oTemp.Print(m_pDumpFile); - ::fprintf(m_pDumpFile, "\n"); - ::fflush(m_pDumpFile); - } -#endif - oTemp.Free(); - } - - // Считываем следующий объект - m_pParser->GetObject(&oTemp); - } - oTemp.Free(); - - // args at end with no command - if (nArgumentsCount > 0) - { - // TO DO: Error "Leftover args in content stream" - -#ifdef _DEBUG - if (m_pDumpFile) - { - ::fprintf(m_pDumpFile, "%d leftovers:", nArgumentsCount); - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - { - ::fprintf(m_pDumpFile, " "); - arrArguments[nIndex].Print(m_pDumpFile); - } - ::fprintf(m_pDumpFile, "\n"); - ::fflush(m_pDumpFile); - } -#endif - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - arrArguments[nIndex].Free(); - } - - if (bTopLevel && m_nUpdateLevel > 0) - { - m_pOut->Dump(); - } - } - - void Graphics::ExecuteOperator(Object *pCommand, Object arrArguments[], int nArgumentsCount) - { - Operator *pOperator = NULL; - // Ищем оператор - char* sName = pCommand->GetCommand(); - if (!(pOperator = FindOperator(sName))) - { - if (m_nIgnoreUndef == 0) // Проверяем наличие незакрытого оператора BX - { - // TO DO: Error "Unknown operator" - } - return; - } - - // Проверяем количество аргументов - Object *pArguments = arrArguments; - if (pOperator->nArgumentsCount >= 0) - { - if (nArgumentsCount < pOperator->nArgumentsCount) - { - // TO DO: Error "Too few args in operator" - return; - } - if (nArgumentsCount > pOperator->nArgumentsCount) - { - // TO DO: Error "Too many args in operator" - - // Используем последние значения в качесте аргументов - pArguments += nArgumentsCount - pOperator->nArgumentsCount; - nArgumentsCount = pOperator->nArgumentsCount; - } - } - else - { - if (nArgumentsCount > -pOperator->nArgumentsCount) - { - // TO DO: Error "Too many args in operator" - return; - } - } - - // Проверяем типы аргументов - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - { - if (!CheckArgumentType(&pArguments[nIndex], pOperator->arrArguments[nIndex])) - { - // TO DO: Error "Some argument is wrong type" - return; - } - } - - // Выполняем сам оператор - (this->*pOperator->pFunction)(pArguments, nArgumentsCount); - } - Operator *Graphics::FindOperator(char *sName) - { - int nCompareRes = 0; - - int nStart = -1; - int nEnd = OperatorsCount; - // OperatorsTable[nStart] < sName < OperatorsTable[nEnd] - - while (nEnd - nStart > 1) - { - int nMiddle = (nStart + nEnd) / 2; - nCompareRes = strcmp(OperatorsTable[nMiddle].sName, sName); - if (nCompareRes < 0) - nStart = nMiddle; - else if (nCompareRes > 0) - nEnd = nMiddle; - else - nStart = nEnd = nMiddle; - } - if (nCompareRes != 0) - return NULL; - return &OperatorsTable[nStart]; - } - - bool Graphics::CheckArgumentType(Object *pArgument, ArgType eType) - { - switch (eType) - { - case argBool: return pArgument->IsBool(); - case argInt: return pArgument->IsInt(); - case argNum: return pArgument->IsNum(); - case argString: return pArgument->IsString(); - case argName: return pArgument->IsName(); - case argArray: return pArgument->IsArray(); - case argProps: return pArgument->IsDict() || pArgument->IsName(); - case argSCN: return pArgument->IsNum() || pArgument->IsName(); - case argNone: return false; - } - return false; - } - - int Graphics::GetPos() - { - return m_pParser ? m_pParser->GetPos() : -1; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Graphics state - //------------------------------------------------------------------------------------------------------------------------------- - - // q - void Graphics::OperatorSave(Object arrArguments[], int nArgumentsCount) - { - SaveGState(); - } - // Q - void Graphics::OperatorRestore(Object arrArguments[], int nArgumentsCount) - { - RestoreGState(); - } - // cm - void Graphics::OperatorConcat(Object arrArguments[], int nArgumentsCount) - { - m_pGState->ConcatCTM(arrArguments[0].GetNum(), arrArguments[1].GetNum(), arrArguments[2].GetNum(), arrArguments[3].GetNum(), arrArguments[4].GetNum(), arrArguments[5].GetNum()); - m_pOut->UpdateCTM(m_pGState, arrArguments[0].GetNum(), arrArguments[1].GetNum(), arrArguments[2].GetNum(), arrArguments[3].GetNum(), arrArguments[4].GetNum(), arrArguments[5].GetNum()); - m_bFontChanged = true; - } - // d - void Graphics::OperatorSetDash(Object arrArguments[], int nArgumentsCount) - { - double *pDash; - Array *pArray = arrArguments[0].GetArray(); - int nCount = pArray->GetCount(); - if (0 == nCount) - { - pDash = NULL; - } - else - { - pDash = (double *)MemUtilsMallocArray(nCount, sizeof(double)); - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - Object oTemp; - pDash[nIndex] = pArray->Get(nIndex, &oTemp)->GetNum(); - oTemp.Free(); - } - } - m_pGState->SetLineDash(pDash, nCount, arrArguments[1].GetNum()); - m_pOut->UpdateLineDash(m_pGState); - } - // i - void Graphics::OperatorSetFlat(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetFlatness((int)arrArguments[0].GetNum()); - m_pOut->UpdateFlatness(m_pGState); - } - // j - void Graphics::OperatorSetLineJoin(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetLineJoin(arrArguments[0].GetInt()); - m_pOut->UpdateLineJoin(m_pGState); - } - // J - void Graphics::OperatorSetLineCap(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetLineCap(arrArguments[0].GetInt()); - m_pOut->UpdateLineCap(m_pGState); - } - // M - void Graphics::OperatorSetMiterLimit(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetMiterLimit(arrArguments[0].GetNum()); - m_pOut->UpdateMiterLimit(m_pGState); - } - // w - void Graphics::OperatorSetLineWidth(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetLineWidth(arrArguments[0].GetNum()); - m_pOut->UpdateLineWidth(m_pGState); - } - // ri - void Graphics::OperatorSetRenderingIntent(Object arrArguments[], int nArgumentsCount) - { - } - // gs - void Graphics::OperatorSetExtGState(Object arrArguments[], int nArgumentsCount) - { - Object oDict; - if (!m_pResources->LookupExtGState(arrArguments[0].GetName(), &oDict)) - { - return; - } - if (!oDict.IsDict()) - { - // TO DO: Error "ExtGState is wrong type" - oDict.Free(); - return; - } - - // Прозрачность - Object oDictItem; - // BM (blend mode) - if (!oDict.DictLookup("BM", &oDictItem)->IsNull()) - { - GraphicsBlendMode eMode; - if (m_pGState->ParseBlendMode(&oDictItem, &eMode)) - { - m_pGState->SetBlendMode(eMode); - m_pOut->UpdateBlendMode(m_pGState); - } - else - { - // TO DO: Error "Invalid blend mode in ExtGState" - } - } - oDictItem.Free(); - - // ca (current alpha for filling) - if (oDict.DictLookup("ca", &oDictItem)->IsNum()) - { - m_pGState->SetFillOpacity(oDictItem.GetNum()); - m_pOut->UpdateFillOpacity(m_pGState); - } - oDictItem.Free(); - - // CA (current alpha for stroking) - if (oDict.DictLookup("CA", &oDictItem)->IsNum()) - { - m_pGState->SetStrokeOpacity(oDictItem.GetNum()); - m_pOut->UpdateStrokeOpacity(m_pGState); - } - oDictItem.Free(); - - // op (over print for filling) - bool bHaveFillOP; - if ((bHaveFillOP = (oDict.DictLookup("op", &oDictItem)->IsBool()))) - { - m_pGState->SetFillOverprint(oDictItem.GetBool()); - m_pOut->UpdateFillOverprint(m_pGState); - } - oDictItem.Free(); - - // OP (over print for stroking) - if (oDict.DictLookup("OP", &oDictItem)->IsBool()) - { - m_pGState->SetStrokeOverprint(oDictItem.GetBool()); - m_pOut->UpdateStrokeOverprint(m_pGState); - if (!bHaveFillOP) - { - m_pGState->SetFillOverprint(oDictItem.GetBool()); - m_pOut->UpdateFillOverprint(m_pGState); - } - } - oDictItem.Free(); - - // SA (stroke adjustment) - if (oDict.DictLookup("SA", &oDictItem)->IsBool()) - { - m_pGState->SetStrokeAdjust(oDictItem.GetBool()); - m_pOut->UpdateStrokeAdjust(m_pGState); - } - oDictItem.Free(); - - // TR2/TR (transfer function) - // приоритетной является TR2 - Function *ppFunctions[4]; - if (oDict.DictLookup("TR2", &oDictItem)->IsNull()) - { - oDictItem.Free(); - oDict.DictLookup("TR", &oDictItem); - } - if (oDictItem.IsName("Default") || oDictItem.IsName("Identity")) - { - ppFunctions[0] = ppFunctions[1] = ppFunctions[2] = ppFunctions[3] = NULL; - m_pGState->SetTransfer(ppFunctions); - m_pOut->UpdateTransfer(m_pGState); - } - else if (oDictItem.IsArray() && oDictItem.ArrayGetLength() == 4) - { - int nIndex = 0; - for (nIndex = 0; nIndex < 4; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - ppFunctions[nIndex] = Function::Parse(&oTemp); - oTemp.Free(); - if (!ppFunctions[nIndex]) - { - break; - } - } - if (4 == nIndex) // нормально ли все функции прочитались - { - m_pGState->SetTransfer(ppFunctions); - m_pOut->UpdateTransfer(m_pGState); - } - } - else if (oDictItem.IsName() || oDictItem.IsDict() || oDictItem.IsStream()) - { - if ((ppFunctions[0] = Function::Parse(&oDictItem))) - { - ppFunctions[1] = ppFunctions[2] = ppFunctions[3] = NULL; - m_pGState->SetTransfer(ppFunctions); - m_pOut->UpdateTransfer(m_pGState); - } - } - else if (!oDictItem.IsNull()) - { - // TO DO: Error "Invalid transfer function in ExtGState" - } - oDictItem.Free(); - - // SMask (soft mask) - if (!oDict.DictLookup("SMask", &oDictItem)->IsNull()) - { - if (oDictItem.IsName("None")) - { - m_pOut->ClearSoftMask(m_pGState); - } - else if (oDictItem.IsDict()) - { - Object oTemp; - bool bAlpha = false; - if (oDictItem.DictLookup("S", &oTemp)->IsName("Alpha")) - { - bAlpha = true; - } - else // "Luminosity" - { - bAlpha = false; - } - oTemp.Free(); - - ppFunctions[0] = NULL; - if (!oDictItem.DictLookup("TR", &oTemp)->IsNull()) - { - ppFunctions[0] = Function::Parse(&oTemp); - if (ppFunctions[0]->GetInputSize() != 1 || ppFunctions[0]->GetOutputSize() != 1) - { - // TO DO: Error "Invalid transfer function in soft mask in ExtGState" - if (ppFunctions[0]) - delete ppFunctions[0]; - ppFunctions[0] = NULL; - } - } - oTemp.Free(); - - bool bHaveBackDropColor = false; - GrColor oBackDropColor; - if ((bHaveBackDropColor = oDictItem.DictLookup("BC", &oTemp)->IsArray())) - { - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - oBackDropColor.arrComp[nIndex] = 0; - } - for (int nIndex = 0; nIndex < oTemp.ArrayGetLength() && nIndex < GrColorMaxComps; ++nIndex) - { - Object oArrayItem; - oTemp.ArrayGet(nIndex, &oArrayItem); - if (oArrayItem.IsNum()) - { - oBackDropColor.arrComp[nIndex] = DoubleToColor(oArrayItem.GetNum()); - } - oArrayItem.Free(); - } - } - oTemp.Free(); - - if (oDictItem.DictLookup("G", &oTemp)->IsStream()) - { - Object oDict2; - if (oTemp.StreamGetDict()->Search("Group", &oDict2)->IsDict()) - { - GrColorSpace *pBlendingColorSpace = NULL; - bool bIsolated = false, bKnockout = false; - Object oTemp2; - if (!oDict2.DictLookup("CS", &oTemp2)->IsNull()) - { - pBlendingColorSpace = GrColorSpace::Parse(&oTemp2); - } - oTemp2.Free(); - if (oDict2.DictLookup("I", &oTemp2)->IsBool()) - { - bIsolated = oTemp2.GetBool(); - } - oTemp2.Free(); - if (oDict2.DictLookup("K", &oTemp2)->IsBool()) - { - bKnockout = oTemp2.GetBool(); - } - oTemp2.Free(); - if (!bHaveBackDropColor) - { - if (pBlendingColorSpace) - { - pBlendingColorSpace->GetDefaultColor(&oBackDropColor); - } - else - { - for (int nIndex = 0; nIndex < GrColorMaxComps; ++nIndex) - { - oBackDropColor.arrComp[nIndex] = 0; - } - } - } - MakeSoftMask(&oTemp, bAlpha, pBlendingColorSpace, bIsolated, bKnockout, ppFunctions[0], &oBackDropColor); - if (ppFunctions[0]) - { - delete ppFunctions[0]; - } - } - else - { - // TO DO: Error "Invalid soft mask in ExtGState - missing group" - } - oDict2.Free(); - } - else - { - // TO DO: Error "Invalid soft mask in ExtGState - missing group" - } - oTemp.Free(); - } - else if (!oDictItem.IsNull()) - { - // TO DO: Error "Invalid soft mask in ExtGState" - } - } - oDictItem.Free(); - oDict.Free(); - } - - //------------------------------------------------------------------------------------------------------------------------------- - void Graphics::MakeSoftMask(Object *pStream, bool bAlpha, GrColorSpace *pBlendingColorSpace, bool bIsolated, bool bKnockout, Function *pTransferFunction, GrColor *pBackDropColor) - { - // Проверяем на чрезмерную рекурсию - if (m_nFormDepth > 20) - { - return; - } - - Dict *pDict = pStream->StreamGetDict(); - - // Form type - Object oDictItem; - pDict->Search("FormType", &oDictItem); - if (!(oDictItem.IsNull() || (oDictItem.IsInt() && oDictItem.GetInt() == 1))) - { - // TO DO: Error "Unknown form type" - } - oDictItem.Free(); - - // BBox - pDict->Search("BBox", &oDictItem); - if (!oDictItem.IsArray()) - { - oDictItem.Free(); - // TO DO: Error "Bad form bounding box" - return; - } - double arrBBox[4]; - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - arrBBox[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - oDictItem.Free(); - - // Matrix - double arrMatrix[6]; - pDict->Search("Matrix", &oDictItem); - if (oDictItem.IsArray()) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - Object oTemp; - oDictItem.ArrayGet(nIndex, &oTemp); - arrMatrix[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - arrMatrix[0] = 1; arrMatrix[1] = 0; - arrMatrix[2] = 0; arrMatrix[3] = 1; - arrMatrix[4] = 0; arrMatrix[5] = 0; - } - oDictItem.Free(); - - // Resources - pDict->Search("Resources", &oDictItem); - Dict *pResourcesDict = (oDictItem.IsDict() ? oDictItem.GetDict() : (Dict *)NULL); - - // Рисуем - ++m_nFormDepth; - DoForm(pStream, pResourcesDict, arrMatrix, arrBBox, true, true, pBlendingColorSpace, bIsolated, bKnockout, bAlpha, pTransferFunction, pBackDropColor); - --m_nFormDepth; - - if (pBlendingColorSpace) - { - delete pBlendingColorSpace; - } - oDictItem.Free(); - } - //------------------------------------------------------------------------------------------------------------------------------- - // Color and Color spaces - //------------------------------------------------------------------------------------------------------------------------------- - - // g - void Graphics::OperatorSetFillGray(Object arrArguments[], int nArgumentsCount) - { - GrColor oColor; - - m_pGState->SetFillPattern(NULL); - m_pGState->SetFillColorSpace(new GrDeviceGrayColorSpace()); - m_pOut->UpdateFillColorSpace(m_pGState); - oColor.arrComp[0] = DoubleToColor(arrArguments[0].GetNum()); - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - - // G - void Graphics::OperatorSetStrokeGray(Object arrArguments[], int nArgumentsCount) - { - GrColor oColor; - - m_pGState->SetStrokePattern(NULL); - m_pGState->SetStrokeColorSpace(new GrDeviceGrayColorSpace()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - oColor.arrComp[0] = DoubleToColor(arrArguments[0].GetNum()); - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - - // k - void Graphics::OperatorSetFillCMYKColor(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetFillPattern(NULL); - m_pGState->SetFillColorSpace(new GrDeviceCMYKColorSpace()); - m_pOut->UpdateFillColorSpace(m_pGState); - - GrColor oColor; - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - - // K - void Graphics::OperatorSetStrokeCMYKColor(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetStrokePattern(NULL); - m_pGState->SetStrokeColorSpace(new GrDeviceCMYKColorSpace()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - - GrColor oColor; - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - - // rg - void Graphics::OperatorSetFillRGBColor(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetFillPattern(NULL); - m_pGState->SetFillColorSpace(new GrDeviceRGBColorSpace()); - m_pOut->UpdateFillColorSpace(m_pGState); - - GrColor oColor; - for (int nIndex = 0; nIndex < 3; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - - // RG - void Graphics::OperatorSetStrokeRGBColor(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetStrokePattern(NULL); - m_pGState->SetStrokeColorSpace(new GrDeviceRGBColorSpace()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - - GrColor oColor; - for (int nIndex = 0; nIndex < 3; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - - // cs - void Graphics::OperatorSetFillColorSpace(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetFillPattern(NULL); - Object oTemp; - m_pResources->LookupColorSpace(arrArguments[0].GetName(), &oTemp); - GrColorSpace *pColorSpace = NULL; - if (oTemp.IsNull()) - { - pColorSpace = GrColorSpace::Parse(&arrArguments[0]); - } - else - { - pColorSpace = GrColorSpace::Parse(&oTemp); - } - oTemp.Free(); - - if (pColorSpace) - { - m_pGState->SetFillColorSpace(pColorSpace); - m_pOut->UpdateFillColorSpace(m_pGState); - GrColor oColor; - pColorSpace->GetDefaultColor(&oColor); - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - else - { - // TO DO: Error "Bad color space (fill)" - } - } - - // CS - void Graphics::OperatorSetStrokeColorSpace(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetStrokePattern(NULL); - Object oTemp; - m_pResources->LookupColorSpace(arrArguments[0].GetName(), &oTemp); - GrColorSpace *pColorSpace = NULL; - if (oTemp.IsNull()) - { - pColorSpace = GrColorSpace::Parse(&arrArguments[0]); - } - else - { - pColorSpace = GrColorSpace::Parse(&oTemp); - } - oTemp.Free(); - - if (pColorSpace) - { - m_pGState->SetStrokeColorSpace(pColorSpace); - m_pOut->UpdateStrokeColorSpace(m_pGState); - GrColor oColor; - pColorSpace->GetDefaultColor(&oColor); - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - else - { - // TO DO: Error "Bad color space (stroke)" - } - } - - // sc - void Graphics::OperatorSetFillColor(Object arrArguments[], int nArgumentsCount) - { - if (nArgumentsCount != m_pGState->GetFillColorSpace()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'sc' command" - return; - } - m_pGState->SetFillPattern(NULL); - - GrColor oColor; - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - - // SC - void Graphics::OperatorSetStrokeColor(Object arrArguments[], int nArgumentsCount) - { - if (nArgumentsCount != m_pGState->GetStrokeColorSpace()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'SC' command" - return; - } - m_pGState->SetStrokePattern(NULL); - - GrColor oColor; - for (int nIndex = 0; nIndex < nArgumentsCount; ++nIndex) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - - // scn - void Graphics::OperatorSetFillColorN(Object arrArguments[], int nArgumentsCount) - { - GrPattern *pPattern = NULL; - GrColor oColor; - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - if (nArgumentsCount > 1) - { - if (!((GrPatternColorSpace *)m_pGState->GetFillColorSpace())->GetUnder() || nArgumentsCount - 1 != ((GrPatternColorSpace *)m_pGState->GetFillColorSpace())->GetUnder()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'scn' command" - return; - } - for (int nIndex = 0; nIndex < nArgumentsCount - 1 && nIndex < GrColorMaxComps; ++nIndex) - { - if (arrArguments[nIndex].IsNum()) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - } - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - if (arrArguments[nArgumentsCount - 1].IsName() && (pPattern = m_pResources->LookupPattern(arrArguments[nArgumentsCount - 1].GetName()))) - { - m_pGState->SetFillPattern(pPattern); - } - } - else - { - if (nArgumentsCount != m_pGState->GetFillColorSpace()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'scn' command" - return; - } - m_pGState->SetFillPattern(NULL); - for (int nIndex = 0; nIndex < nArgumentsCount && nIndex < GrColorMaxComps; ++nIndex) - { - if (arrArguments[nIndex].IsNum()) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - } - m_pGState->SetFillColor(&oColor); - m_pOut->UpdateFillColor(m_pGState); - } - } - - // SCN - void Graphics::OperatorSetStrokeColorN(Object arrArguments[], int nArgumentsCount) - { - GrPattern *pPattern = NULL; - GrColor oColor; - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - if (nArgumentsCount > 1) - { - if (!((GrPatternColorSpace *)m_pGState->GetStrokeColorSpace())->GetUnder() || nArgumentsCount - 1 != ((GrPatternColorSpace *)m_pGState->GetStrokeColorSpace())->GetUnder()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'SCN' command" - return; - } - for (int nIndex = 0; nIndex < nArgumentsCount - 1 && nIndex < GrColorMaxComps; ++nIndex) - { - if (arrArguments[nIndex].IsNum()) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - } - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - if (arrArguments[nArgumentsCount - 1].IsName() && (pPattern = m_pResources->LookupPattern(arrArguments[nArgumentsCount - 1].GetName()))) - { - m_pGState->SetStrokePattern(pPattern); - } - } - else - { - if (nArgumentsCount != m_pGState->GetStrokeColorSpace()->GetComponentsCount()) - { - // TO DO: Error "Incorrect number of arguments in 'SCN' command" - return; - } - m_pGState->SetStrokePattern(NULL); - for (int nIndex = 0; nIndex < nArgumentsCount && nIndex < GrColorMaxComps; ++nIndex) - { - if (arrArguments[nIndex].IsNum()) - { - oColor.arrComp[nIndex] = DoubleToColor(arrArguments[nIndex].GetNum()); - } - } - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Path construction - //------------------------------------------------------------------------------------------------------------------------------- - - // m - void Graphics::OperatorMoveTo(Object arrArguments[], int nArgumentsCount) - { - m_pGState->MoveTo(arrArguments[0].GetNum(), arrArguments[1].GetNum()); - } - - // l - void Graphics::OperatorLineTo(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No current point in lineto" - return; - } - m_pGState->LineTo(arrArguments[0].GetNum(), arrArguments[1].GetNum()); - } - - // c - void Graphics::OperatorCurveTo(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No current point in curveto" - return; - } - m_pGState->CurveTo((double)arrArguments[0].GetNum(), (double)arrArguments[1].GetNum(), (double)arrArguments[2].GetNum(), (double)arrArguments[3].GetNum(), (double)arrArguments[4].GetNum(), (double)arrArguments[5].GetNum()); - } - - // v - void Graphics::OperatorCurveTo1(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No current point in curveto1" - return; - } - m_pGState->CurveTo(m_pGState->GetCurX(), m_pGState->GetCurY(), (double)arrArguments[0].GetNum(), (double)arrArguments[1].GetNum(), (double)arrArguments[2].GetNum(), (double)arrArguments[3].GetNum()); - } - - // y - void Graphics::OperatorCurveTo2(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No current point in curveto2" - return; - } - m_pGState->CurveTo((double)arrArguments[0].GetNum(), (double)arrArguments[1].GetNum(), (double)arrArguments[2].GetNum(), (double)arrArguments[3].GetNum(), (double)arrArguments[2].GetNum(), (double)arrArguments[3].GetNum()); - } - - // re - void Graphics::OperatorRectangle(Object arrArguments[], int nArgumentsCount) - { - double dX = arrArguments[0].GetNum(); - double dY = arrArguments[1].GetNum(); - double dWidth = arrArguments[2].GetNum(); - double dHeight = arrArguments[3].GetNum(); - m_pGState->MoveTo(dX, dY); - m_pGState->LineTo(dX + dWidth, dY); - m_pGState->LineTo(dX + dWidth, dY + dHeight); - m_pGState->LineTo(dX, dY + dHeight); - m_pGState->ClosePath(); - } - - // h - void Graphics::OperatorClosePath(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No current point in closepath" - return; - } - m_pGState->ClosePath(); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // path painting operators - //------------------------------------------------------------------------------------------------------------------------------- - - // n - void Graphics::OperatorEndPath(Object arrArguments[], int nArgumentsCount) - { - DoEndPath(); - } - - // S - void Graphics::OperatorStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - DoEndPath(); - } - - // s - void Graphics::OperatorCloseStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in closepath/stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - m_pGState->ClosePath(); - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - DoEndPath(); - } - - // f/F - void Graphics::OperatorFill(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in fill" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(false); - } - else - { - m_pOut->Fill(m_pGState); - } - } - DoEndPath(); - } - - // f* - void Graphics::OperatorEOFill(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in eofill" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(true); - } - else - { - m_pOut->EoFill(m_pGState); - } - } - DoEndPath(); - } - - // B - void Graphics::OperatorFillStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in fill/stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - if (!(m_pGState->GetFillColorSpace()->GetMode() == csPattern) && !(m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) && m_pOut->UseFillAndStroke()) - { - m_pOut->FillStroke(m_pGState); - } - else - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(false); - } - else - { - m_pOut->Fill(m_pGState); - } - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - } - DoEndPath(); - } - - // b - void Graphics::OperatorCloseFillStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in closepath/fill/stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - m_pGState->ClosePath(); - - if (!(m_pGState->GetFillColorSpace()->GetMode() == csPattern) && !(m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) && m_pOut->UseFillAndStroke()) - { - m_pOut->FillStroke(m_pGState); - } - else - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(false); - } - else - { - m_pOut->Fill(m_pGState); - } - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - } - DoEndPath(); - } - - // B* - void Graphics::OperatorEOFillStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in eofill/stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - if (!(m_pGState->GetFillColorSpace()->GetMode() == csPattern) && !(m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) && m_pOut->UseFillAndStroke()) - { - m_pOut->EoFillStroke(m_pGState); - } - else - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(true); - } - else - { - m_pOut->EoFill(m_pGState); - } - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - } - DoEndPath(); - } - - // b* - void Graphics::OperatorCloseEOFillStroke(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->IsCurPoint()) - { - // TO DO: Error "No path in closepath/eofill/stroke" - return; - } - if (m_pGState->IsPathNonEmpty()) - { - m_pGState->ClosePath(); - if (!(m_pGState->GetFillColorSpace()->GetMode() == csPattern) && !(m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) && m_pOut->UseFillAndStroke()) - { - m_pOut->EoFillStroke(m_pGState); - } - else - { - if (m_pGState->GetFillColorSpace()->GetMode() == csPattern) - { - DoPatternFill(true); - } - else - { - m_pOut->EoFill(m_pGState); - } - if (m_pGState->GetStrokeColorSpace()->GetMode() == csPattern) - { - DoPatternStroke(); - } - else - { - m_pOut->Stroke(m_pGState); - } - } - } - DoEndPath(); - } - - // sh - void Graphics::OperatorShadingFill(Object arrArguments[], int nArgumentsCount) - { - GrShading *pShading = NULL; - - if (!(pShading = m_pResources->LookupShading(arrArguments[0].GetName()))) - { - return; - } - - // Сохраняем текущий GState - GrPath *pSavedPath = m_pGState->GetPath()->Copy(); - SaveGState(); - - if (pShading->GetHasBBox()) - { - double dXMin, dYMin, dXMax, dYMax; - pShading->GetBBox(&dXMin, &dYMin, &dXMax, &dYMax); - m_pGState->MoveTo(dXMin, dYMin); - m_pGState->LineTo(dXMax, dYMin); - m_pGState->LineTo(dXMax, dYMax); - m_pGState->LineTo(dXMin, dYMax); - m_pGState->ClosePath(); - m_pGState->Clip(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - - m_pGState->ClearPath(); - } - - // Устанавливаем цветовое пространство - m_pGState->SetFillColorSpace(pShading->GetColorSpace()->Copy()); - m_pOut->UpdateFillColorSpace(m_pGState); - - bool bAntialias = m_pOut->GetVectorAntialias(); - if (bAntialias) - { - m_pOut->SetVectorAntialias(false); - } - - m_pOut->StartShadedFill(m_pGState); - - // Выполняем закраску, в зависимости от типа Shading - switch (pShading->GetType()) - { - case 1: - DoFunctionShadingFill((GrFunctionShading *)pShading); - break; - case 2: - DoAxialShadingFill((GrAxialShading *)pShading); - break; - case 3: - DoRadialShadingFill((GrRadialShading *)pShading); - break; - case 4: - case 5: - DoGouraudTriangleShadingFill((GrGouraudTriangleShading *)pShading); - break; - case 6: - case 7: - DoPatchMeshShadingFill((GrPatchMeshShading *)pShading); - break; - } - - m_pOut->EndShadedFill(); - - if (bAntialias) - { - m_pOut->SetVectorAntialias(true); - } - - // Восстанавливаем GState - RestoreGState(); - m_pGState->SetPath(pSavedPath); - - delete pShading; - } - - //------------------------------------------------------------------------------------------------------------------------------- - void Graphics::DoPatternFill(bool bEOFill) - { - // Пропускаем объект Patterns, если мы выводим только текст из PDF - if (!m_pOut->NeedNonText()) - { - return; - } - - GrPattern *pPattern = NULL; - if (!(pPattern = m_pGState->GetFillPattern())) - { - return; - } - switch (pPattern->GetType()) - { - case 1: - DoTilingPatternFill((GrTilingPattern *)pPattern, false, bEOFill); - break; - case 2: - DoShadingPatternFill((GrShadingPattern *)pPattern, false, bEOFill); - break; - default: - // TO DO: Error "Unimplemented pattern type in fill" - break; - } - } - - void Graphics::DoPatternStroke() - { - // Пропускаем объект Patterns, если мы выводим только текст из PDF - if (!m_pOut->NeedNonText()) - { - return; - } - - // TODO: Обводка по паттерну работает неправильно. Она не учитывает, ни пунктирность, ни тип соединения, - // ни тип окончания. Либо надо строить здесь внешний пат для обводки через заливку, либо - // ждать, когда будет реализация внутри Renderer - m_pOut->Stroke(m_pGState); - return; - - GrPattern *pPattern = NULL; - if (!(pPattern = m_pGState->GetStrokePattern())) - { - return; - } - switch (pPattern->GetType()) - { - case 1: - DoTilingPatternFill((GrTilingPattern *)pPattern, true, false); - break; - case 2: - DoShadingPatternFill((GrShadingPattern *)pPattern, true, false); - break; - default: - // TO DO: Error "Unimplemented pattern type in stroke" - break; - } - } - - void Graphics::DoTilingPatternFill(GrTilingPattern *pPattern, bool bStroke, bool bEOFill) - { - // Color space - GrPatternColorSpace *pPatternCS = (GrPatternColorSpace *)(bStroke ? m_pGState->GetStrokeColorSpace() : m_pGState->GetFillColorSpace()); - - // Строим матрицу преобразования (Pattern space) -> (Current space) - double *pCTM = m_pGState->GetCTM(); - double *pBaseMatrix = m_arrBaseMatrix; - double *pTilingMatrix = pPattern->GetMatrix(); - double dDet = 1 / (pCTM[0] * pCTM[3] - pCTM[1] * pCTM[2]); - // InvCTM = (CTM)^(-1) - double pInvCTM[6]; - pInvCTM[0] = pCTM[3] * dDet; - pInvCTM[1] = -pCTM[1] * dDet; - pInvCTM[2] = -pCTM[2] * dDet; - pInvCTM[3] = pCTM[0] * dDet; - pInvCTM[4] = (pCTM[2] * pCTM[5] - pCTM[3] * pCTM[4]) * dDet; - pInvCTM[5] = (pCTM[1] * pCTM[4] - pCTM[0] * pCTM[5]) * dDet; - // TempMatrix = TilingMatrix * BaseMatrix - double pTempMatrix[6]; - pTempMatrix[0] = pTilingMatrix[0] * pBaseMatrix[0] + pTilingMatrix[1] * pBaseMatrix[2]; - pTempMatrix[1] = pTilingMatrix[0] * pBaseMatrix[1] + pTilingMatrix[1] * pBaseMatrix[3]; - pTempMatrix[2] = pTilingMatrix[2] * pBaseMatrix[0] + pTilingMatrix[3] * pBaseMatrix[2]; - pTempMatrix[3] = pTilingMatrix[2] * pBaseMatrix[1] + pTilingMatrix[3] * pBaseMatrix[3]; - pTempMatrix[4] = pTilingMatrix[4] * pBaseMatrix[0] + pTilingMatrix[5] * pBaseMatrix[2] + pBaseMatrix[4]; - pTempMatrix[5] = pTilingMatrix[4] * pBaseMatrix[1] + pTilingMatrix[5] * pBaseMatrix[3] + pBaseMatrix[5]; - // Matrix = TempMatrix * InvCTM - double pMatrix[6]; - pMatrix[0] = pTempMatrix[0] * pInvCTM[0] + pTempMatrix[1] * pInvCTM[2]; - pMatrix[1] = pTempMatrix[0] * pInvCTM[1] + pTempMatrix[1] * pInvCTM[3]; - pMatrix[2] = pTempMatrix[2] * pInvCTM[0] + pTempMatrix[3] * pInvCTM[2]; - pMatrix[3] = pTempMatrix[2] * pInvCTM[1] + pTempMatrix[3] * pInvCTM[3]; - pMatrix[4] = pTempMatrix[4] * pInvCTM[0] + pTempMatrix[5] * pInvCTM[2] + pInvCTM[4]; - pMatrix[5] = pTempMatrix[4] * pInvCTM[1] + pTempMatrix[5] * pInvCTM[3] + pInvCTM[5]; - - // Строим матрицу преобразования (Device space) -> (Pattern space) - double pInvTemp[6]; - dDet = 1 / (pTempMatrix[0] * pTempMatrix[3] - pTempMatrix[1] * pTempMatrix[2]); - pInvTemp[0] = pTempMatrix[3] * dDet; - pInvTemp[1] = -pTempMatrix[1] * dDet; - pInvTemp[2] = -pTempMatrix[2] * dDet; - pInvTemp[3] = pTempMatrix[0] * dDet; - pInvTemp[4] = (pTempMatrix[2] * pTempMatrix[5] - pTempMatrix[3] * pTempMatrix[4]) * dDet; - pInvTemp[5] = (pTempMatrix[1] * pTempMatrix[4] - pTempMatrix[0] * pTempMatrix[5]) * dDet; - - // Сохраняем текущий GState - GrPath *pSavedPath = m_pGState->GetPath()->Copy(); - SaveGState(); - - // Устанавливаем цветовое пространство для подкладки (для не цветовых Tiling patterns); - // Устанавливаем разлиные параметры (цвет обводки, толщина линии) - GrColorSpace *pColorSpace = NULL; - if (pPattern->GetPaintType() == 2 && (pColorSpace = pPatternCS->GetUnder())) - { - m_pGState->SetFillColorSpace(pColorSpace->Copy()); - m_pOut->UpdateFillColorSpace(m_pGState); - m_pGState->SetStrokeColorSpace(pColorSpace->Copy()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - m_pGState->SetStrokeColor(m_pGState->GetFillColor()); - } - else - { - m_pGState->SetFillColorSpace(new GrDeviceGrayColorSpace()); - m_pOut->UpdateFillColorSpace(m_pGState); - m_pGState->SetStrokeColorSpace(new GrDeviceGrayColorSpace()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - } - m_pGState->SetFillPattern(NULL); - m_pOut->UpdateFillColor(m_pGState); - m_pGState->SetStrokePattern(NULL); - m_pOut->UpdateStrokeColor(m_pGState); - if (!bStroke) - { - m_pGState->SetLineWidth(0); - m_pOut->UpdateLineWidth(m_pGState); - } - - if (bStroke) - { - m_pGState->ClipToStrokePath(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->ClipToStrokePath(m_pGState); - } - else - { - m_pGState->Clip(); - if (bEOFill) - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), true); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), true); - else - m_pOut->EoClip(m_pGState); - } - else - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - } - } - m_pGState->ClearPath(); - - double dClipXMin, dClipYMin, dClipXMax, dClipYMax; - m_pGState->GetClipBBox(&dClipXMin, &dClipYMin, &dClipXMax, &dClipYMax); - if (dClipXMin > dClipXMax || dClipYMin > dClipYMax) - { - RestoreGState(); - m_pGState->SetPath(pSavedPath); - return; - } - - double dXMin, dYMin, dXMax, dYMax; - dXMin = dXMax = dClipXMin * pInvTemp[0] + dClipYMin * pInvTemp[2] + pInvTemp[4]; - dYMin = dYMax = dClipXMin * pInvTemp[1] + dClipYMin * pInvTemp[3] + pInvTemp[5]; - double dTempX = dClipXMin * pInvTemp[0] + dClipYMax * pInvTemp[2] + pInvTemp[4]; - double dTempY = dClipXMin * pInvTemp[1] + dClipYMax * pInvTemp[3] + pInvTemp[5]; - if (dTempX < dXMin) - { - dXMin = dTempX; - } - else if (dTempX > dXMax) - { - dXMax = dTempX; - } - if (dTempY < dYMin) - { - dYMin = dTempY; - } - else if (dTempY > dYMax) - { - dYMax = dTempY; - } - dTempX = dClipXMax * pInvTemp[0] + dClipYMin * pInvTemp[2] + pInvTemp[4]; - dTempY = dClipXMax * pInvTemp[1] + dClipYMin * pInvTemp[3] + pInvTemp[5]; - if (dTempX < dXMin) - { - dXMin = dTempX; - } - else if (dTempX > dXMax) - { - dXMax = dTempX; - } - if (dTempY < dYMin) - { - dYMin = dTempY; - } - else if (dTempY > dYMax) - { - dYMax = dTempY; - } - dTempX = dClipXMax * pInvTemp[0] + dClipYMax * pInvTemp[2] + pInvTemp[4]; - dTempY = dClipXMax * pInvTemp[1] + dClipYMax * pInvTemp[3] + pInvTemp[5]; - if (dTempX < dXMin) - { - dXMin = dTempX; - } - else if (dTempX > dXMax) - { - dXMax = dTempX; - } - if (dTempY < dYMin) - { - dYMin = dTempY; - } - else if (dTempY > dYMax) - { - dYMax = dTempY; - } - - double dStepX = fabs(pPattern->GetXStep()); - double dStepY = fabs(pPattern->GetYStep()); - int nX0 = (int)ceil((dXMin - pPattern->GetBBox()[2]) / dStepX); - int nX1 = (int)floor((dXMax - pPattern->GetBBox()[0]) / dStepX) + 1; - int nY0 = (int)ceil((dYMin - pPattern->GetBBox()[3]) / dStepY); - int nY1 = (int)floor((dYMax - pPattern->GetBBox()[1]) / dStepY) + 1; - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - pTempMatrix[nIndex] = pMatrix[nIndex]; - } - - m_pOut->StartTilingFill(m_pGState); - if (m_pOut->UseTilingPatternFill()) - { - pTempMatrix[4] = pMatrix[4]; - pTempMatrix[5] = pMatrix[5]; - m_pOut->TilingPatternFill(m_pGState, pPattern->GetContentStream(), pPattern->GetPaintType(), pPattern->GetResourcesDict(), pTempMatrix, pPattern->GetBBox(), nX0, nY0, nX1, nY1, dStepX, dStepY); - } - else - { - if (m_pOut->UseSimpleTilingPatternFill()) - { - m_pOut->StartSimpleTilingFill(m_pGState, nX0, nY0, nX1, nY1, dStepX, dStepY, dXMin, dYMin, dXMax, dYMax, pTempMatrix); - - for (int nY = nY0; nY < nY1; ++nY) - { - for (int nX = nX0; nX < nX1; ++nX) - { - double dX = nX * dStepX; - double dY = nY * dStepY; - pTempMatrix[4] = dX * pMatrix[0] + dY * pMatrix[2] + pMatrix[4]; - pTempMatrix[5] = dX * pMatrix[1] + dY * pMatrix[3] + pMatrix[5]; - DoForm(pPattern->GetContentStream(), pPattern->GetResourcesDict(), pTempMatrix, pPattern->GetBBox()); - } - } - - m_pOut->EndSimpleTilingFill(); - } - else - { - for (int nY = nY0; nY < nY1; ++nY) - { - for (int nX = nX0; nX < nX1; ++nX) - { - if (m_pOut->IsStopped()) - { - // Восстанавливаем GState - RestoreGState(); - m_pGState->SetPath(pSavedPath); - return; - } - - m_pOut->StartTilingFillIteration(); - - double dX = nX * dStepX; - double dY = nY * dStepY; - pTempMatrix[4] = dX * pMatrix[0] + dY * pMatrix[2] + pMatrix[4]; - pTempMatrix[5] = dX * pMatrix[1] + dY * pMatrix[3] + pMatrix[5]; - DoForm(pPattern->GetContentStream(), pPattern->GetResourcesDict(), pTempMatrix, pPattern->GetBBox()); - - m_pOut->EndTilingFillIteration(); - } - } - } - } - - m_pOut->EndTilingFill(); - - // Восстанавливаем GState - RestoreGState(); - m_pGState->SetPath(pSavedPath); - } - - void Graphics::DoShadingPatternFill(GrShadingPattern *pPattern, bool bStroke, bool bEOFill) - { - GrShading *pShading = pPattern->GetShading(); - - // Сохраняем текущий GState - GrPath *pSavedPath = m_pGState->GetPath()->Copy(); - SaveGState(); - - if (pShading->GetHasBBox()) - { - double dXMin, dYMin, dXMax, dYMax; - pShading->GetBBox(&dXMin, &dYMin, &dXMax, &dYMax); - m_pGState->MoveTo(dXMin, dYMin); - m_pGState->LineTo(dXMax, dYMin); - m_pGState->LineTo(dXMax, dYMax); - m_pGState->LineTo(dXMin, dYMax); - m_pGState->ClosePath(); - m_pGState->Clip(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - - m_pGState->SetPath(pSavedPath->Copy()); - } - - if (bStroke) - { - m_pGState->ClipToStrokePath(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->ClipToStrokePath(m_pGState); - } - else - { - m_pGState->Clip(); - if (bEOFill) - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), true); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), true); - else - m_pOut->EoClip(m_pGState); - } - else - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - } - } - - // Устанавливаем цветовое пространство - m_pGState->SetFillColorSpace(pShading->GetColorSpace()->Copy()); - m_pOut->UpdateFillColorSpace(m_pGState); - - // Задний фон - if (pShading->GetHasBackground()) - { - m_pGState->SetFillColor(pShading->GetBackground()); - m_pOut->UpdateFillColor(m_pGState); - m_pOut->Fill(m_pGState); - } - m_pGState->ClearPath(); - - // Строим матрицу преобразования (Pattern space) -> (Current space) - double *pCTM = m_pGState->GetCTM(); - double *pBaseMatrix = m_arrBaseMatrix; - double *pPatternMatrix = pPattern->GetMatrix(); - - // InvCTM = (CTM)^(-1) - double pInvCTM[6]; - double dDet = 1 / (pCTM[0] * pCTM[3] - pCTM[1] * pCTM[2]); - pInvCTM[0] = pCTM[3] * dDet; - pInvCTM[1] = -pCTM[1] * dDet; - pInvCTM[2] = -pCTM[2] * dDet; - pInvCTM[3] = pCTM[0] * dDet; - pInvCTM[4] = (pCTM[2] * pCTM[5] - pCTM[3] * pCTM[4]) * dDet; - pInvCTM[5] = (pCTM[1] * pCTM[4] - pCTM[0] * pCTM[5]) * dDet; - // TempMatrix = PatternMatrix * BaseMatrix - double pTempMatrix[6]; - pTempMatrix[0] = pPatternMatrix[0] * pBaseMatrix[0] + pPatternMatrix[1] * pBaseMatrix[2]; - pTempMatrix[1] = pPatternMatrix[0] * pBaseMatrix[1] + pPatternMatrix[1] * pBaseMatrix[3]; - pTempMatrix[2] = pPatternMatrix[2] * pBaseMatrix[0] + pPatternMatrix[3] * pBaseMatrix[2]; - pTempMatrix[3] = pPatternMatrix[2] * pBaseMatrix[1] + pPatternMatrix[3] * pBaseMatrix[3]; - pTempMatrix[4] = pPatternMatrix[4] * pBaseMatrix[0] + pPatternMatrix[5] * pBaseMatrix[2] + pBaseMatrix[4]; - pTempMatrix[5] = pPatternMatrix[4] * pBaseMatrix[1] + pPatternMatrix[5] * pBaseMatrix[3] + pBaseMatrix[5]; - // Matrix = TempMatrix * InvCTM - double pMatrix[6]; - pMatrix[0] = pTempMatrix[0] * pInvCTM[0] + pTempMatrix[1] * pInvCTM[2]; - pMatrix[1] = pTempMatrix[0] * pInvCTM[1] + pTempMatrix[1] * pInvCTM[3]; - pMatrix[2] = pTempMatrix[2] * pInvCTM[0] + pTempMatrix[3] * pInvCTM[2]; - pMatrix[3] = pTempMatrix[2] * pInvCTM[1] + pTempMatrix[3] * pInvCTM[3]; - pMatrix[4] = pTempMatrix[4] * pInvCTM[0] + pTempMatrix[5] * pInvCTM[2] + pInvCTM[4]; - pMatrix[5] = pTempMatrix[4] * pInvCTM[1] + pTempMatrix[5] * pInvCTM[3] + pInvCTM[5]; - - // Устанавливаем новую матрицу - m_pGState->ConcatCTM(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], pMatrix[4], pMatrix[5]); - m_pOut->UpdateCTM(m_pGState, pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], pMatrix[4], pMatrix[5]); - - bool bAntialias = m_pOut->GetVectorAntialias(); - if (bAntialias) - { - m_pOut->SetVectorAntialias(false); - } - - m_pOut->StartShadedFill(m_pGState); - - // Выполняем закраску, в зависимости от типа Shading - switch (pShading->GetType()) - { - case 1: - DoFunctionShadingFill((GrFunctionShading *)pShading); - break; - case 2: - DoAxialShadingFill((GrAxialShading *)pShading); - break; - case 3: - DoRadialShadingFill((GrRadialShading *)pShading); - break; - case 4: - case 5: - DoGouraudTriangleShadingFill((GrGouraudTriangleShading *)pShading); - break; - case 6: - case 7: - DoPatchMeshShadingFill((GrPatchMeshShading *)pShading); - break; - } - - m_pOut->EndShadedFill(); - - if (bAntialias) - { - m_pOut->SetVectorAntialias(true); - } - - // Восстанавливаем GState - RestoreGState(); - m_pGState->SetPath(pSavedPath); - } - - void Graphics::DoFunctionShadingFill(GrFunctionShading *pShading) - { - // Если Output Device не поддерживает данный ShadingType, тогда делаем его сами - // с помощью GrPath. - double dMinX, dMinY, dMaxX, dMaxY; - GrColor arrColors[4]; - - pShading->GetDomain(&dMinX, &dMinY, &dMaxX, &dMaxY); - pShading->GetColor(dMinX, dMinY, &arrColors[0]); - pShading->GetColor(dMinX, dMaxY, &arrColors[1]); - pShading->GetColor(dMaxX, dMinY, &arrColors[2]); - pShading->GetColor(dMaxX, dMaxY, &arrColors[3]); - - // Сначала предоставляем возможность OuputDevice самому сделать Shading - if (m_pOut->UseFunctionalShadedFills()) - { - double *pMatrix = pShading->GetMatrix(); - m_pGState->MoveTo(dMinX * pMatrix[0] + dMinY * pMatrix[2] + pMatrix[4], dMinX * pMatrix[1] + dMinY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMaxX * pMatrix[0] + dMinY * pMatrix[2] + pMatrix[4], dMaxX * pMatrix[1] + dMinY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMaxX * pMatrix[0] + dMaxY * pMatrix[2] + pMatrix[4], dMaxX * pMatrix[1] + dMaxY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMinX * pMatrix[0] + dMaxY * pMatrix[2] + pMatrix[4], dMinX * pMatrix[1] + dMaxY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMinX * pMatrix[0] + dMinY * pMatrix[2] + pMatrix[4], dMinX * pMatrix[1] + dMinY * pMatrix[3] + pMatrix[5]); - m_pGState->ClosePath(); - - m_pOut->FunctionShadedFill(m_pGState, pShading); - - m_pGState->ClearPath(); - return; - } - - DoFunctionShadingFill(pShading, dMinX, dMinY, dMaxX, dMaxY, arrColors, 0); - } - - void Graphics::DoFunctionShadingFill(GrFunctionShading *pShading, double dMinX, double dMinY, double dMaxX, double dMaxY, GrColor *pColors, int nDepth) - { - if (m_pOut->IsStopped()) - return; - - int nComponentsCount = pShading->GetColorSpace()->GetComponentsCount(); - - // Сравниваем цвета в углах - int nColorIndex = 0; - for (nColorIndex = 0; nColorIndex < 4; ++nColorIndex) - { - int nComponentIndex; - for (nComponentIndex = 0; nComponentIndex < nComponentsCount; ++nComponentIndex) - { - if (abs(pColors[nColorIndex].arrComp[nComponentIndex] - pColors[(nColorIndex + 1) & 3].arrComp[nComponentIndex]) > functionColorDelta) - { - break; - } - } - if (nComponentIndex < nComponentsCount) - { - break; - } - } - - double dCenterX = 0.5 * (dMinX + dMaxX); - double dCenterY = 0.5 * (dMinY + dMaxY); - - // Угловые вершины прямоугольников достаточно близки (или мы достигли предела количетсву иттераций) - // Заливаем прямоугольник. Даже если изначально вершины близки проводим одну иттерацию деления, чтобы - // случая, когда все 4 вершины имеют одинаковый цвет. - if ((nColorIndex == 4 && nDepth > 0) || nDepth == functionMaxDepth) - { - // Используем цвет центра прямоугольника - GrColor oFillColor; - pShading->GetColor(dCenterX, dCenterY, &oFillColor); - m_pGState->SetFillColor(&oFillColor); - m_pOut->UpdateFillColor(m_pGState); - - double *pMatrix = pShading->GetMatrix(); - // Заливка прямоугольника - m_pGState->MoveTo(dMinX * pMatrix[0] + dMinY * pMatrix[2] + pMatrix[4], dMinX * pMatrix[1] + dMinY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMaxX * pMatrix[0] + dMinY * pMatrix[2] + pMatrix[4], dMaxX * pMatrix[1] + dMinY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMaxX * pMatrix[0] + dMaxY * pMatrix[2] + pMatrix[4], dMaxX * pMatrix[1] + dMaxY * pMatrix[3] + pMatrix[5]); - m_pGState->LineTo(dMinX * pMatrix[0] + dMaxY * pMatrix[2] + pMatrix[4], dMinX * pMatrix[1] + dMaxY * pMatrix[3] + pMatrix[5]); - m_pGState->ClosePath(); - m_pOut->Fill(m_pGState); - m_pGState->ClearPath(); - } - else // 4 угловые вершины не достаточно близки, делим дальше на прямоугольники - { - - // pColors[0] oColorCT pColors[2] - // (dMinX,dMinY) (dCenterX,dMinY) (dMaxX,dMinY) - // +---------------------+---------------------+ - // | | | - // | Top Left | Top Right | - // oColorLC | oColorCC| | oColorRC - // +---------------------+---------------------+ - // (dMinX,dCenterY) (dCenterX,dCenterY) (dMaxX,dCenterY) - // | Bottom Left | Bottom Right | - // | | | - // +---------------------+---------------------+ - // (dMinX,dMaxY) (dCenterX,dMaxY) (dMaxX,dMaxY) - // pColors[1] oColorCB pColors[3] - - GrColor oColorLC, oColorRC, oColorCT, oColorCB, oColorCC, arrSubColors[4]; - pShading->GetColor(dMinX, dCenterY, &oColorLC); - pShading->GetColor(dMaxX, dCenterY, &oColorRC); - pShading->GetColor(dCenterX, dMinY, &oColorCT); - pShading->GetColor(dCenterX, dMaxY, &oColorCB); - pShading->GetColor(dCenterX, dCenterY, &oColorCC); - - // Верхний левый прямоугольник - arrSubColors[0] = pColors[0]; - arrSubColors[1] = oColorLC; - arrSubColors[2] = oColorCT; - arrSubColors[3] = oColorCC; - DoFunctionShadingFill(pShading, dMinX, dMinY, dCenterX, dCenterY, arrSubColors, nDepth + 1); - - // Левый нижний прямоугольник - arrSubColors[0] = oColorLC; - arrSubColors[1] = pColors[1]; - arrSubColors[2] = oColorCC; - arrSubColors[3] = oColorCB; - DoFunctionShadingFill(pShading, dMinX, dCenterY, dCenterX, dMaxY, arrSubColors, nDepth + 1); - - // Правый верхний прямоугольник - arrSubColors[0] = oColorCT; - arrSubColors[1] = oColorCC; - arrSubColors[2] = pColors[2]; - arrSubColors[3] = oColorRC; - DoFunctionShadingFill(pShading, dCenterX, dMinY, dMaxX, dCenterY, arrSubColors, nDepth + 1); - - // Правый нижний прямоугольник - arrSubColors[0] = oColorCC; - arrSubColors[1] = oColorCB; - arrSubColors[2] = oColorRC; - arrSubColors[3] = pColors[3]; - DoFunctionShadingFill(pShading, dCenterX, dCenterY, dMaxX, dMaxY, arrSubColors, nDepth + 1); - } - } - - void Graphics::DoAxialShadingFill(GrAxialShading *pShading) - { - int nJ, nK, nKK; - // Сначала предоставляем возможность OuputDevice самому сделать Shading - if (m_pOut->UseAxialShadedFills()) - { - double xmin, ymin, xmax, ymax; - m_pGState->GetUserClipBBox(&xmin, &ymin, &xmax, &ymax); - m_pGState->MoveTo(xmin, ymin); - m_pGState->LineTo(xmin, ymax); - m_pGState->LineTo(xmax, ymax); - m_pGState->LineTo(xmax, ymin); - m_pGState->LineTo(xmin, ymin); - m_pGState->ClosePath(); - - m_pOut->AxialShadedFill(m_pGState, pShading); - - m_pGState->ClearPath(); - return; - } - - // get the clip region bbox - double dMinX, dMinY, dMaxX, dMaxY; - m_pGState->GetUserClipBBox(&dMinX, &dMinY, &dMaxX, &dMaxY); - - // Вычисляем макимальное и минимальное значения параметра T - double dTmin, dTmax; - double dX0, dY0, dX1, dY1; - pShading->GetCoords(&dX0, &dY0, &dX1, &dY1); - double dDx = dX1 - dX0; - double dDy = dY1 - dY0; - bool bDxZero = fabs(dDx) < 0.01; - bool bDyZero = fabs(dDy) < 0.01; - - if (bDxZero && bDyZero) - { - dTmin = dTmax = 0; - } - else - { - double dMult = 1 / (dDx * dDx + dDy * dDy); - dTmin = dTmax = ((dMinX - dX0) * dDx + (dMinY - dY0) * dDy) * dMult; - double dTemp = ((dMinX - dX0) * dDx + (dMaxY - dY0) * dDy) * dMult; - if (dTemp < dTmin) - { - dTmin = dTemp; - } - else if (dTemp > dTmax) - { - dTmax = dTemp; - } - dTemp = ((dMaxX - dX0) * dDx + (dMinY - dY0) * dDy) * dMult; - if (dTemp < dTmin) - { - dTmin = dTemp; - } - else if (dTemp > dTmax) - { - dTmax = dTemp; - } - dTemp = ((dMaxX - dX0) * dDx + (dMaxY - dY0) * dDy) * dMult; - if (dTemp < dTmin) - { - dTmin = dTemp; - } - else if (dTemp > dTmax) - { - dTmax = dTemp; - } - if (dTmin < 0 && !pShading->GetExtendStart()) - { - dTmin = 0; - } - if (dTmax > 1 && !pShading->GetExtendEnd()) - { - dTmax = 1; - } - } - - // Считываем пределы параметра T - double dT0 = pShading->GetDomain0(); - double dT1 = pShading->GetDomain1(); - - // Для каждой точки (Tx, Ty) оси, рассмотрим линию ,проходяющую через данную точку перпендикулярно оси: - // - // x(s) = Tx + s * -dDy --> s = (x - Tx) / -dDy - // y(s) = Ty + s * dDx --> s = (y - Ty) / dDx - // - // Рассмотрим точки пересечения данной линии с внешним ректом(в котором все рисуем Bbox). В общем случае - // мы имеем 4 точки пересечения: - // - // s0 = (dMinX - Tx) / -dDy - // s1 = (dMaxX - Tx) / -dDy - // s2 = (dMinY - Ty) / dDx - // s3 = (dMaxY - Ty) / dDx - // - // нас интересуют два средних значения s. - // - // В случае, когда dDx = 0, возьмем s0 и s1; в случае, когда dDy = 0, возьмем s2 и s3. - // - // Далее каждый полигон, который мы будем заполнять будет ограничен двумя такими линиями, перпендикулярными оси. - // - // Делим ось таким образом до тех пор, пока разница цветов между двумя соседними линиями не станет достаточно - // малой. Далее кажды отдельный полигон закрашиваем одним цветом. - - // Делаем как минимум одну такую иттерацию, чтобы избежать проблем в случае, когда оба конца оси имеют - // одинаковый цвет. - - int nComponentsCount = pShading->GetColorSpace()->GetComponentsCount(); - double arrTa[axialMaxSplits + 1]; - arrTa[0] = dTmin; - int arrNext[axialMaxSplits + 1]; - arrNext[0] = axialMaxSplits / 2; - arrTa[axialMaxSplits / 2] = 0.5 * (dTmin + dTmax); - arrNext[axialMaxSplits / 2] = axialMaxSplits; - arrTa[axialMaxSplits] = dTmax; - - // Вычисляем значение цвета при t = dTmin - double dTt = 0; - if (dTmin < 0) - { - dTt = dT0; - } - else if (dTmin > 1) - { - dTt = dT1; - } - else - { - dTt = dT0 + (dT1 - dT0) * dTmin; - } - GrColor oColor0, oColor1; - pShading->GetColor(dTt, &oColor0); - - // Вычисляем координаты точки, лежаще на оси, при значении параметра t = dTmin; - // после этого вычисляем координаты точек пересечения для линии при t = dTmin. - double dTx = dX0 + dTmin * dDx; - double dTy = dY0 + dTmin * dDy; - double arrS[4]; - - double dSmin, dSmax; - - if (bDxZero && bDyZero) - { - dSmin = dSmax = 0; - } - else if (bDxZero) - { - dSmin = (dMinX - dTx) / -dDy; - dSmax = (dMaxX - dTx) / -dDy; - if (dSmin > dSmax) - { - double dTemp = dSmin; - dSmin = dSmax; - dSmax = dTemp; - } - } - else if (bDyZero) - { - dSmin = (dMinY - dTy) / dDx; - dSmax = (dMaxY - dTy) / dDx; - if (dSmin > dSmax) - { - double dTemp = dSmin; - dSmin = dSmax; - dSmax = dTemp; - } - } - else - { - arrS[0] = (dMinY - dTy) / dDx; - arrS[1] = (dMaxY - dTy) / dDx; - arrS[2] = (dMinX - dTx) / -dDy; - arrS[3] = (dMaxX - dTx) / -dDy; - for (nJ = 0; nJ < 3; ++nJ) - { - nKK = nJ; - for (nK = nJ + 1; nK < 4; ++nK) - { - if (arrS[nK] < arrS[nKK]) - { - nKK = nK; - } - } - double dTemp = arrS[nJ]; - arrS[nJ] = arrS[nKK]; - arrS[nKK] = dTemp; - } - dSmin = arrS[1]; - dSmax = arrS[2]; - } - double dStartX0 = dTx - dSmin * dDy; - double dStartY0 = dTy + dSmin * dDx; - double dEndX0 = dTx - dSmax * dDy; - double dEndY0 = dTy + dSmax * dDx; - - int nSplitsCount = 0; - while (nSplitsCount < axialMaxSplits) - { - if (m_pOut->IsStopped()) - return; - - // Делим пока разница цветов не станет достаточной маленькой или пока мы не достигнем предела количеству иттераций - nJ = arrNext[nSplitsCount]; - while (nJ > nSplitsCount + 1) - { - if (m_pOut->IsStopped()) - return; - - if (arrTa[nJ] < 0) - { - dTt = dT0; - } - else if (arrTa[nJ] > 1) - { - dTt = dT1; - } - else - { - dTt = dT0 + (dT1 - dT0) * arrTa[nJ]; - } - pShading->GetColor(dTt, &oColor1); - for (nK = 0; nK < nComponentsCount; ++nK) - { - if (abs(oColor1.arrComp[nK] - oColor0.arrComp[nK]) > axialColorDelta) - { - break; - } - } - if (nK == nComponentsCount) - { - break; - } - nK = (nSplitsCount + nJ) / 2; - arrTa[nK] = 0.5 * (arrTa[nSplitsCount] + arrTa[nJ]); - arrNext[nSplitsCount] = nK; - arrNext[nK] = nJ; - nJ = nK; - } - - // Используем среднее значение цвета - for (nK = 0; nK < nComponentsCount; ++nK) - { - oColor0.arrComp[nK] = (oColor0.arrComp[nK] + oColor1.arrComp[nK]) / 2; - } - - // Вычисляем координаты точки, лежаще на оси, при данном значении параметра t; - // после этого вычисляем координаты точек пересечения для линии данном t. - dTx = dX0 + arrTa[nJ] * dDx; - dTy = dY0 + arrTa[nJ] * dDy; - if (bDxZero && bDyZero) - { - dSmin = dSmax = 0; - } - else if (bDxZero) - { - dSmin = (dMinX - dTx) / -dDy; - dSmax = (dMaxX - dTx) / -dDy; - if (dSmin > dSmax) - { - double dTemp = dSmin; - dSmin = dSmax; - dSmax = dTemp; - } - } - else if (bDyZero) - { - dSmin = (dMinY - dTy) / dDx; - dSmax = (dMaxY - dTy) / dDx; - if (dSmin > dSmax) - { - double dTemp = dSmin; - dSmin = dSmax; - dSmax = dTemp; - } - } - else - { - arrS[0] = (dMinY - dTy) / dDx; - arrS[1] = (dMaxY - dTy) / dDx; - arrS[2] = (dMinX - dTx) / -dDy; - arrS[3] = (dMaxX - dTx) / -dDy; - for (nJ = 0; nJ < 3; ++nJ) - { - nKK = nJ; - for (nK = nJ + 1; nK < 4; ++nK) - { - if (arrS[nK] < arrS[nKK]) - { - nKK = nK; - } - } - double dTemp = arrS[nJ]; - arrS[nJ] = arrS[nKK]; - arrS[nKK] = dTemp; - } - dSmin = arrS[1]; - dSmax = arrS[2]; - } - double dStartX1 = dTx - dSmin * dDy; - double dStartY1 = dTy + dSmin * dDx; - double dEndX1 = dTx - dSmax * dDy; - double dEndY1 = dTy + dSmax * dDx; - - // Устанавливаем цвет - m_pGState->SetFillColor(&oColor0); - m_pOut->UpdateFillColor(m_pGState); - - // Закрашиваем - m_pGState->MoveTo(dStartX0, dStartY0); - m_pGState->LineTo(dEndX0, dEndY0); - m_pGState->LineTo(dEndX1, dEndY1); - m_pGState->LineTo(dStartX1, dStartY1); - m_pGState->ClosePath(); - m_pOut->Fill(m_pGState); - - m_pGState->ClearPath(); - - // Начальные значения для следующего полигона - dStartX0 = dStartX1; - dStartY0 = dStartY1; - dEndX0 = dEndX1; - dEndY0 = dEndY1; - oColor0 = oColor1; - nSplitsCount = arrNext[nSplitsCount]; - } - } - - void Graphics::DoRadialShadingFill(GrRadialShading *pShading) - { - // Сначала предоставляем возможность OuputDevice самому сделать Shading - if (m_pOut->UseRadialShadedFills()) - { - double xmin, ymin, xmax, ymax; - m_pGState->GetUserClipBBox(&xmin, &ymin, &xmax, &ymax); - m_pGState->MoveTo(xmin, ymin); - m_pGState->LineTo(xmin, ymax); - m_pGState->LineTo(xmax, ymax); - m_pGState->LineTo(xmax, ymin); - m_pGState->LineTo(xmin, ymin); - m_pGState->ClosePath(); - - m_pOut->RadialShadedFill(m_pGState, pShading); - - m_pGState->ClearPath(); - return; - } - // Если Output Device не поддерживает данный ShadingType, тогда делаем его сами - // с помощью GrPath. - - double dFirstX, dFirstY, dFirstRad, dSecondX, dSecondY, dSecondRad; - pShading->GetCoords(&dFirstX, &dFirstY, &dFirstRad, &dSecondX, &dSecondY, &dSecondRad); - double dT0 = pShading->GetDomain0(); - double dT1 = pShading->GetDomain1(); - int nComponentsCount = pShading->GetColorSpace()->GetComponentsCount(); - - // Вычисляем точку, в которой r(s) = 0; проверяме вложенность окружностей; и - // вычисляем углы тангенциальных линий - bool bEnclosed = false; - double dTheta = 0, dAlpha = 0;; - double dZeroS = 0; - if (dFirstX == dSecondX && dFirstY == dSecondY) - { - bEnclosed = true; - dTheta = 0; - dZeroS = 0; - } - else if (dFirstRad == dSecondRad) - { - bEnclosed = false; - dTheta = 0; - dZeroS = 0; - } - else - { - dZeroS = -dFirstRad / (dSecondRad - dFirstRad); - double dZeroX = dFirstX + dZeroS * (dSecondX - dFirstX); - double dZeroY = dFirstY + dZeroS * (dSecondY - dFirstY); - bEnclosed = ((dZeroX - dFirstX) * (dZeroX - dFirstX) + (dZeroY - dFirstY) * (dZeroY - dFirstY) <= dFirstRad * dFirstRad); - dTheta = asin(dFirstRad / sqrt((dFirstX - dZeroX) * (dFirstX - dZeroX) + (dFirstY - dZeroY) * (dFirstY - dZeroY))); - if (dFirstRad > dSecondRad) - { - dTheta = -dTheta; - } - } - if (bEnclosed) - { - dAlpha = 0; - } - else - { - dAlpha = atan2(dSecondY - dFirstY, dSecondX - dFirstX); - } - - double dXMin, dYMin, dXMax, dYMax; - m_pGState->GetUserClipBBox(&dXMin, &dYMin, &dXMax, &dYMax); - - double dSmin, dSmax; - if (bEnclosed) - { - dSmin = 0; - dSmax = 1; - } - else - { - dSmin = 1; - dSmax = 0; - // x(s) + r(s) = dXMin - if ((dSecondX + dSecondRad) - (dFirstX + dFirstRad) != 0) - { - double dTempS = (dXMin - (dFirstX + dFirstRad)) / ((dSecondX + dSecondRad) - (dFirstX + dFirstRad)); - if (dTempS < dSmin) - { - dSmin = dTempS; - } - else if (dTempS > dSmax) - { - dSmax = dTempS; - } - } - // x(s) - r(s) = dXMax - if ((dSecondX - dSecondRad) - (dFirstX - dFirstRad) != 0) - { - double dTempS = (dXMax - (dFirstX - dFirstRad)) / ((dSecondX - dSecondRad) - (dFirstX - dFirstRad)); - if (dTempS < dSmin) - { - dSmin = dTempS; - } - else if (dTempS > dSmax) - { - dSmax = dTempS; - } - } - // y(s) + r(s) = dYMin - if ((dSecondY + dSecondRad) - (dFirstY + dFirstRad) != 0) - { - double dTempS = (dYMin - (dFirstY + dFirstRad)) / ((dSecondY + dSecondRad) - (dFirstY + dFirstRad)); - if (dTempS < dSmin) - { - dSmin = dTempS; - } - else if (dTempS > dSmax) - { - dSmax = dTempS; - } - } - // y(s) - r(s) = dYMax - if ((dSecondY - dSecondRad) - (dFirstY - dFirstRad) != 0) - { - double dTempS = (dYMax - (dFirstY - dFirstRad)) / ((dSecondY - dSecondRad) - (dFirstY - dFirstRad)); - if (dTempS < dSmin) - { - dSmin = dTempS; - } - else if (dTempS > dSmax) - { - dSmax = dTempS; - } - } - - // Проверяем относительно dZeroS - if (dFirstRad < dSecondRad) - { - if (dSmin < dZeroS) - { - dSmin = dZeroS; - } - } - else if (dFirstRad > dSecondRad) - { - if (dSmax > dZeroS) - { - dSmax = dZeroS; - } - } - - if (!pShading->GetExtendFirst() && dSmin < 0) - { - dSmin = 0; - } - if (!pShading->GetExtendSecond() && dSmax > 1) - { - dSmax = 1; - } - } - - double *pCTM = m_pGState->GetCTM(); - double dTemp = fabs(pCTM[0]); - if (fabs(pCTM[1]) > dTemp) - { - dTemp = fabs(pCTM[1]); - } - if (fabs(pCTM[2]) > dTemp) - { - dTemp = fabs(pCTM[2]); - } - if (fabs(pCTM[3]) > dTemp) - { - dTemp = fabs(pCTM[3]); - } - if (dFirstRad > dSecondRad) - { - dTemp *= dFirstRad; - } - else - { - dTemp *= dSecondRad; - } - int nStepsCount = 0; - if (dTemp < 1) - { - nStepsCount = 3; - } - else - { - nStepsCount = (int)(M_PI / acos(1 - 0.1 / dTemp)); - if (nStepsCount < 3) - { - nStepsCount = 3; - } - else if (nStepsCount > 200) - { - nStepsCount = 200; - } - } - - // Везде далее A - первая окружность, B - вторая - int nIndexA = 0; - double dSA = dSmin; - double dTA = dT0 + dSA * (dT1 - dT0); - double dXA = dFirstX + dSA * (dSecondX - dFirstX); - double dYA = dFirstY + dSA * (dSecondY - dFirstY); - double dRadA = dFirstRad + dSA * (dSecondRad - dFirstRad); - double dAngle = 0; - int nCounter = 0; - GrColor oColorA; - if (dTA < dT0) - { - pShading->GetColor(dT0, &oColorA); - } - else if (dTA > dT1) - { - pShading->GetColor(dT1, &oColorA); - } - else - { - pShading->GetColor(dTA, &oColorA); - } - - while (nIndexA < radialMaxSplits) - { - if (m_pOut->IsStopped()) - return; - - int nIndexB = radialMaxSplits; - double dSB = dSmax; - double dTB = dT0 + dSB * (dT1 - dT0); - GrColor oColorB; - if (dTB < dT0) - { - pShading->GetColor(dT0, &oColorB); - } - else if (dTB > dT1) - { - pShading->GetColor(dT1, &oColorB); - } - else - { - pShading->GetColor(dTB, &oColorB); - } - - while (nIndexB - nIndexA > 1) - { - if (m_pOut->IsStopped()) - return; - - for (nCounter = 0; nCounter < nComponentsCount; ++nCounter) - { - if (abs(oColorB.arrComp[nCounter] - oColorA.arrComp[nCounter]) > radialColorDelta) - { - break; - } - } - if (nCounter == nComponentsCount && nIndexB < radialMaxSplits) - { - break; - } - nIndexB = (nIndexA + nIndexB) / 2; - dSB = dSmin + ((double)nIndexB / (double)radialMaxSplits) * (dSmax - dSmin); - dTB = dT0 + dSB * (dT1 - dT0); - if (dTB < dT0) - { - pShading->GetColor(dT0, &oColorB); - } - else if (dTB > dT1) - { - pShading->GetColor(dT1, &oColorB); - } - else - { - pShading->GetColor(dTB, &oColorB); - } - } - - // Вычислим центр и радиус окружности - double dXB = dFirstX + dSB * (dSecondX - dFirstX); - double dYB = dFirstY + dSB * (dSecondY - dFirstY); - double dRadB = dFirstRad + dSB * (dSecondRad - dFirstRad); - - // Используем среднее значение цвета двух окружностей - for (nCounter = 0; nCounter < nComponentsCount; ++nCounter) - { - oColorA.arrComp[nCounter] = (oColorA.arrComp[nCounter] + oColorB.arrComp[nCounter]) / 2; - } - m_pGState->SetFillColor(&oColorA); - m_pOut->UpdateFillColor(m_pGState); - - if (bEnclosed) - { - - // Строим Path для первой окружности (против часовой) - m_pGState->MoveTo(dXA + dRadA, dYA); - for (nCounter = 1; nCounter < nStepsCount; ++nCounter) - { - dAngle = ((double)nCounter / (double)nStepsCount) * 2 * M_PI; - m_pGState->LineTo(dXA + dRadA * cos(dAngle), dYA + dRadA * sin(dAngle)); - } - m_pGState->ClosePath(); - - // Строим Path для второй окружности (по часовой) - m_pGState->MoveTo(dXB + dRadB, dYB); - for (nCounter = 1; nCounter < nStepsCount; ++nCounter) - { - dAngle = -((double)nCounter / (double)nStepsCount) * 2 * M_PI; - m_pGState->LineTo(dXB + dRadB * cos(dAngle), dYB + dRadB * sin(dAngle)); - } - m_pGState->ClosePath(); - - } - else - { - - // Строим первый subpath (по часовой) - m_pGState->MoveTo(dXA + dRadA * cos(dAlpha + dTheta + 0.5 * M_PI), dYA + dRadA * sin(dAlpha + dTheta + 0.5 * M_PI)); - for (nCounter = 0; nCounter < nStepsCount; ++nCounter) - { - dAngle = dAlpha + dTheta + 0.5 * M_PI - ((double)nCounter / (double)nStepsCount) * (2 * dTheta + M_PI); - m_pGState->LineTo(dXB + dRadB * cos(dAngle), dYB + dRadB * sin(dAngle)); - } - for (nCounter = 0; nCounter < nStepsCount; ++nCounter) - { - dAngle = dAlpha - dTheta - 0.5 * M_PI + ((double)nCounter / (double)nStepsCount) * (2 * dTheta - M_PI); - m_pGState->LineTo(dXA + dRadA * cos(dAngle), dYA + dRadA * sin(dAngle)); - } - m_pGState->ClosePath(); - - // Строим второй subpath (против часовой) - m_pGState->MoveTo(dXA + dRadA * cos(dAlpha + dTheta + 0.5 * M_PI), dYA + dRadA * sin(dAlpha + dTheta + 0.5 * M_PI)); - for (nCounter = 0; nCounter < nStepsCount; ++nCounter) - { - dAngle = dAlpha + dTheta + 0.5 * M_PI + ((double)nCounter / (double)nStepsCount) * (-2 * dTheta + M_PI); - m_pGState->LineTo(dXB + dRadB * cos(dAngle), dYB + dRadB * sin(dAngle)); - } - for (nCounter = 0; nCounter < nStepsCount; ++nCounter) - { - dAngle = dAlpha - dTheta - 0.5 * M_PI + ((double)nCounter / (double)nStepsCount) * (2 * dTheta + M_PI); - m_pGState->LineTo(dXA + dRadA * cos(dAngle), dYA + dRadA * sin(dAngle)); - } - m_pGState->ClosePath(); - } - - // Закрашиваем - m_pOut->Fill(m_pGState); - m_pGState->ClearPath(); - - // Начальные данные для следующего шага - nIndexA = nIndexB; - dSA = dSB; - dTA = dTB; - dXA = dXB; - dYA = dYB; - dRadA = dRadB; - oColorA = oColorB; - } - - // Если выставлены флаги продолжать рисовать за пределами двух окружностей - if (bEnclosed) - { - // Продолжаем за меньшую окружность - if ((pShading->GetExtendFirst() && dFirstRad <= dSecondRad) || (pShading->GetExtendSecond() && dSecondRad < dFirstRad)) - { - if (dFirstRad <= dSecondRad) - { - dTA = dT0; - dRadA = dFirstRad; - dXA = dFirstX; - dYA = dFirstY; - } - else - { - dTA = dT1; - dRadA = dSecondRad; - dXA = dSecondX; - dYA = dSecondY; - } - pShading->GetColor(dTA, &oColorA); - m_pGState->SetFillColor(&oColorA); - m_pOut->UpdateFillColor(m_pGState); - m_pGState->MoveTo(dXA + dRadA, dYA); - for (nCounter = 1; nCounter < nStepsCount; ++nCounter) - { - dAngle = ((double)nCounter / (double)nStepsCount) * 2 * M_PI; - m_pGState->LineTo(dXA + dRadA * cos(dAngle), dYA + dRadA * sin(dAngle)); - } - m_pGState->ClosePath(); - m_pOut->Fill(m_pGState); - m_pGState->ClearPath(); - } - - // Продолжаем за большую окружность - if ((pShading->GetExtendFirst() && dFirstRad > dSecondRad) || (pShading->GetExtendSecond() && dSecondRad >= dFirstRad)) - { - if (dFirstRad > dSecondRad) - { - dTA = dT0; - dRadA = dFirstRad; - dXA = dFirstX; - dYA = dFirstY; - } - else - { - dTA = dT1; - dRadA = dSecondRad; - dXA = dSecondX; - dYA = dSecondY; - } - pShading->GetColor(dTA, &oColorA); - m_pGState->SetFillColor(&oColorA); - m_pOut->UpdateFillColor(m_pGState); - m_pGState->MoveTo(dXMin, dYMin); - m_pGState->LineTo(dXMin, dYMax); - m_pGState->LineTo(dXMax, dYMax); - m_pGState->LineTo(dXMax, dYMin); - m_pGState->ClosePath(); - m_pGState->MoveTo(dXA + dRadA, dYA); - for (nCounter = 1; nCounter < nStepsCount; ++nCounter) - { - dAngle = ((double)nCounter / (double)nStepsCount) * 2 * M_PI; - m_pGState->LineTo(dXA + dRadA * cos(dAngle), dYA + dRadA * sin(dAngle)); - } - m_pGState->ClosePath(); - m_pOut->Fill(m_pGState); - m_pGState->ClearPath(); - } - } - } - - void Graphics::DoGouraudTriangleShadingFill(GrGouraudTriangleShading *pShading) - { - double dAx, dAy, dBx, dBy, dCx, dCy; - GrColor oColorA, oColorB, oColorC; - for (int nIndex = 0; nIndex < pShading->GetTrianglesCount(); ++nIndex) - { - pShading->GetTriangle(nIndex, &dAx, &dAy, &oColorA, &dBx, &dBy, &oColorB, &dCx, &dCy, &oColorC); - GouraudFillTriangle(dAx, dAy, &oColorA, dBx, dBy, &oColorB, dCx, dCy, &oColorC, pShading->GetColorSpace()->GetComponentsCount(), 0); - } - } - - void Graphics::GouraudFillTriangle(double dAx, double dAy, GrColor *pColorA, double dBx, double dBy, GrColor *pColorB, double dCx, double dCy, GrColor *pColorC, int nComponentsCount, int nDepth) - { - if (m_pOut->IsStopped()) - return; - - double dABx, dABy, dBCx, dBCy, dACx, dACy; - GrColor oColorAB, oColorBC, oColorAC; - int nIndex; - if (m_pOut->UseGouraundTriangleFills()) - { - double xmin = std::min(dAx, std::min(dBx, dCx)) - 1; - double ymin = std::min(dAy, std::min(dBy, dCy)) - 1; - double xmax = std::max(dAx, std::max(dBx, dCx)) + 1; - double ymax = std::max(dAy, std::max(dBy, dCy)) + 1; - - // m_pGState->MoveTo(dAx, dAy); - // m_pGState->LineTo(dBx, dBy); - // m_pGState->LineTo(dCx, dCy); - m_pGState->MoveTo(xmin, ymin); - m_pGState->LineTo(xmin, ymax); - m_pGState->LineTo(xmax, ymax); - m_pGState->LineTo(xmax, ymin); - m_pGState->LineTo(xmin, ymin); - m_pGState->ClosePath(); - m_pOut->GouraundTriangleFill(m_pGState, {pColorA, pColorB, pColorC}, {{dAx, dAy}, {dBx, dBy}, {dCx, dCy}}); - m_pGState->ClearPath(); - return; - } - - for (nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - if (abs(pColorA->arrComp[nIndex] - pColorB->arrComp[nIndex]) > gouraudColorDelta || abs(pColorB->arrComp[nIndex] - pColorC->arrComp[nIndex]) > gouraudColorDelta) - { - break; - } - } - if (nIndex == nComponentsCount || nDepth == gouraudMaxDepth) - { - m_pGState->SetFillColor(pColorA); - m_pOut->UpdateFillColor(m_pGState); - m_pGState->MoveTo(dAx, dAy); - m_pGState->LineTo(dBx, dBy); - m_pGState->LineTo(dCx, dCy); - m_pGState->ClosePath(); - m_pOut->Fill(m_pGState); - m_pGState->ClearPath(); - } - else - { - dABx = 0.5 * (dAx + dBx); - dABy = 0.5 * (dAy + dBy); - dBCx = 0.5 * (dBx + dCx); - dBCy = 0.5 * (dBy + dCy); - dACx = 0.5 * (dCx + dAx); - dACy = 0.5 * (dCy + dAy); - for (nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - oColorAB.arrComp[nIndex] = (pColorA->arrComp[nIndex] + pColorB->arrComp[nIndex]) / 2; - oColorBC.arrComp[nIndex] = (pColorB->arrComp[nIndex] + pColorC->arrComp[nIndex]) / 2; - oColorAC.arrComp[nIndex] = (pColorC->arrComp[nIndex] + pColorA->arrComp[nIndex]) / 2; - } - GouraudFillTriangle(dAx, dAy, pColorA, dABx, dABy, &oColorAB, dACx, dACy, &oColorAC, nComponentsCount, nDepth + 1); - GouraudFillTriangle(dABx, dABy, &oColorAB, dBx, dBy, pColorB, dBCx, dBCy, &oColorBC, nComponentsCount, nDepth + 1); - GouraudFillTriangle(dABx, dABy, &oColorAB, dBCx, dBCy, &oColorBC, dACx, dACy, &oColorAC, nComponentsCount, nDepth + 1); - GouraudFillTriangle(dACx, dACy, &oColorAC, dBCx, dBCy, &oColorBC, dCx, dCy, pColorC, nComponentsCount, nDepth + 1); - } - } - - void Graphics::DoPatchMeshShadingFill(GrPatchMeshShading *pShading) - { - // Устанавливаем цветовое пространство - m_pGState->SetStrokeColorSpace(pShading->GetColorSpace()->Copy()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - - int nStart; - - if (pShading->GetPatchesCount() > 128) - { - nStart = 3; - } - else if (pShading->GetPatchesCount() > 64) - { - nStart = 2; - } - else if (pShading->GetPatchesCount() > 16) - { - nStart = 1; - } - else - { - nStart = 0; - } - for (int nIndex = 0; nIndex < pShading->GetPatchesCount(); ++nIndex) - { - MeshFillPatch(pShading->GetPatch(nIndex), pShading->GetColorSpace()->GetComponentsCount(), nStart); - } - } - - void Graphics::MeshFillPatch(GrPatch *pPatch, int nComponentsCount, int nDepth) - { - if (m_pOut->IsStopped()) - return; - - if (m_pOut->UsePatchMeshFills()) - { - //m_pGState->SetFillColor(&pPatch->arrColor[0][0]); - //m_pGState->SetStrokeColor(&pPatch->arrColor[0][0]); - float xmin = pPatch->arrX[0][0], ymin = pPatch->arrY[0][0], xmax = pPatch->arrX[0][0], ymax = pPatch->arrY[0][0]; - - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - if (pPatch->arrX[i][j] > xmax) - { - xmax = pPatch->arrX[i][j]; - } - if (pPatch->arrX[i][j] < xmin) - { - xmin = pPatch->arrX[i][j]; - } - if (pPatch->arrY[i][j] > ymax) - { - ymax = pPatch->arrY[i][j]; - } - if (pPatch->arrY[i][j] < ymin) - { - ymin = pPatch->arrY[i][j]; - } - } - } - // m_pGState->MoveTo(pPatch->arrX[0][0], pPatch->arrY[0][0]); - // m_pGState->CurveTo(pPatch->arrX[0][1], pPatch->arrY[0][1], pPatch->arrX[0][2], pPatch->arrY[0][2], pPatch->arrX[0][3], pPatch->arrY[0][3]); - // m_pGState->CurveTo(pPatch->arrX[1][3], pPatch->arrY[1][3], pPatch->arrX[2][3], pPatch->arrY[2][3], pPatch->arrX[3][3], pPatch->arrY[3][3]); - // m_pGState->CurveTo(pPatch->arrX[3][2], pPatch->arrY[3][2], pPatch->arrX[3][1], pPatch->arrY[3][1], pPatch->arrX[3][0], pPatch->arrY[3][0]); - // m_pGState->CurveTo(pPatch->arrX[2][0], pPatch->arrY[2][0], pPatch->arrX[1][0], pPatch->arrY[1][0], pPatch->arrX[0][0], pPatch->arrY[0][0]); - xmax +=0.1; - ymax +=0.1; - xmin -=0.1; - ymin -=0.1; - - - m_pGState->MoveTo(xmin, ymin); - m_pGState->LineTo(xmin, ymax); - m_pGState->LineTo(xmax, ymax); - m_pGState->LineTo(xmax, ymin); - m_pGState->LineTo(xmin, ymin); - - m_pGState->ClosePath(); - - m_pOut->PatchMeshFill(m_pGState, pPatch); - - m_pGState->ClearPath() ; - return; - } - - GrPatch oPatch00, oPatch01, oPatch10, oPatch11; - double arrX[4][8], arrY[4][8]; - double dMidX, dMidY; - int nIndex; - - for (nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - if (abs(pPatch->arrColor[0][0].arrComp[nIndex] - pPatch->arrColor[0][1].arrComp[nIndex]) > patchColorDelta || - abs(pPatch->arrColor[0][1].arrComp[nIndex] - pPatch->arrColor[1][1].arrComp[nIndex]) > patchColorDelta || - abs(pPatch->arrColor[1][1].arrComp[nIndex] - pPatch->arrColor[1][0].arrComp[nIndex]) > patchColorDelta || - abs(pPatch->arrColor[1][0].arrComp[nIndex] - pPatch->arrColor[0][0].arrComp[nIndex]) > patchColorDelta - ) - { - break; - } - } - if (nIndex == nComponentsCount || nDepth == patchMaxDepth) - { - m_pGState->SetFillColor(&pPatch->arrColor[0][0]); - m_pGState->SetStrokeColor(&pPatch->arrColor[0][0]); - m_pOut->UpdateFillColor(m_pGState); - m_pOut->UpdateStrokeColor(m_pGState); - m_pGState->MoveTo(pPatch->arrX[0][0], pPatch->arrY[0][0]); - m_pGState->CurveTo(pPatch->arrX[0][1], pPatch->arrY[0][1], pPatch->arrX[0][2], pPatch->arrY[0][2], pPatch->arrX[0][3], pPatch->arrY[0][3]); - m_pGState->CurveTo(pPatch->arrX[1][3], pPatch->arrY[1][3], pPatch->arrX[2][3], pPatch->arrY[2][3], pPatch->arrX[3][3], pPatch->arrY[3][3]); - m_pGState->CurveTo(pPatch->arrX[3][2], pPatch->arrY[3][2], pPatch->arrX[3][1], pPatch->arrY[3][1], pPatch->arrX[3][0], pPatch->arrY[3][0]); - m_pGState->CurveTo(pPatch->arrX[2][0], pPatch->arrY[2][0], pPatch->arrX[1][0], pPatch->arrY[1][0], pPatch->arrX[0][0], pPatch->arrY[0][0]); - m_pGState->ClosePath(); - m_pOut->FillStroke(m_pGState); - m_pGState->ClearPath(); - } - else - { - for (nIndex = 0; nIndex < 4; ++nIndex) - { - arrX[nIndex][0] = pPatch->arrX[nIndex][0]; - arrY[nIndex][0] = pPatch->arrY[nIndex][0]; - arrX[nIndex][1] = 0.5 * (pPatch->arrX[nIndex][0] + pPatch->arrX[nIndex][1]); - arrY[nIndex][1] = 0.5 * (pPatch->arrY[nIndex][0] + pPatch->arrY[nIndex][1]); - dMidX = 0.5 * (pPatch->arrX[nIndex][1] + pPatch->arrX[nIndex][2]); - dMidY = 0.5 * (pPatch->arrY[nIndex][1] + pPatch->arrY[nIndex][2]); - arrX[nIndex][6] = 0.5 * (pPatch->arrX[nIndex][2] + pPatch->arrX[nIndex][3]); - arrY[nIndex][6] = 0.5 * (pPatch->arrY[nIndex][2] + pPatch->arrY[nIndex][3]); - arrX[nIndex][2] = 0.5 * (arrX[nIndex][1] + dMidX); - arrY[nIndex][2] = 0.5 * (arrY[nIndex][1] + dMidY); - arrX[nIndex][5] = 0.5 * (dMidX + arrX[nIndex][6]); - arrY[nIndex][5] = 0.5 * (dMidY + arrY[nIndex][6]); - arrX[nIndex][3] = arrX[nIndex][4] = 0.5 * (arrX[nIndex][2] + arrX[nIndex][5]); - arrY[nIndex][3] = arrY[nIndex][4] = 0.5 * (arrY[nIndex][2] + arrY[nIndex][5]); - arrX[nIndex][7] = pPatch->arrX[nIndex][3]; - arrY[nIndex][7] = pPatch->arrY[nIndex][3]; - } - for (nIndex = 0; nIndex < 4; ++nIndex) - { - oPatch00.arrX[0][nIndex] = arrX[0][nIndex]; - oPatch00.arrY[0][nIndex] = arrY[0][nIndex]; - oPatch00.arrX[1][nIndex] = 0.5 * (arrX[0][nIndex] + arrX[1][nIndex]); - oPatch00.arrY[1][nIndex] = 0.5 * (arrY[0][nIndex] + arrY[1][nIndex]); - dMidX = 0.5 * (arrX[1][nIndex] + arrX[2][nIndex]); - dMidY = 0.5 * (arrY[1][nIndex] + arrY[2][nIndex]); - oPatch10.arrX[2][nIndex] = 0.5 * (arrX[2][nIndex] + arrX[3][nIndex]); - oPatch10.arrY[2][nIndex] = 0.5 * (arrY[2][nIndex] + arrY[3][nIndex]); - oPatch00.arrX[2][nIndex] = 0.5 * (oPatch00.arrX[1][nIndex] + dMidX); - oPatch00.arrY[2][nIndex] = 0.5 * (oPatch00.arrY[1][nIndex] + dMidY); - oPatch10.arrX[1][nIndex] = 0.5 * (dMidX + oPatch10.arrX[2][nIndex]); - oPatch10.arrY[1][nIndex] = 0.5 * (dMidY + oPatch10.arrY[2][nIndex]); - oPatch00.arrX[3][nIndex] = 0.5 * (oPatch00.arrX[2][nIndex] + oPatch10.arrX[1][nIndex]); - oPatch00.arrY[3][nIndex] = 0.5 * (oPatch00.arrY[2][nIndex] + oPatch10.arrY[1][nIndex]); - oPatch10.arrX[0][nIndex] = oPatch00.arrX[3][nIndex]; - oPatch10.arrY[0][nIndex] = oPatch00.arrY[3][nIndex]; - oPatch10.arrX[3][nIndex] = arrX[3][nIndex]; - oPatch10.arrY[3][nIndex] = arrY[3][nIndex]; - } - for (nIndex = 4; nIndex < 8; ++nIndex) - { - oPatch01.arrX[0][nIndex - 4] = arrX[0][nIndex]; - oPatch01.arrY[0][nIndex - 4] = arrY[0][nIndex]; - oPatch01.arrX[1][nIndex - 4] = 0.5 * (arrX[0][nIndex] + arrX[1][nIndex]); - oPatch01.arrY[1][nIndex - 4] = 0.5 * (arrY[0][nIndex] + arrY[1][nIndex]); - dMidX = 0.5 * (arrX[1][nIndex] + arrX[2][nIndex]); - dMidY = 0.5 * (arrY[1][nIndex] + arrY[2][nIndex]); - oPatch11.arrX[2][nIndex - 4] = 0.5 * (arrX[2][nIndex] + arrX[3][nIndex]); - oPatch11.arrY[2][nIndex - 4] = 0.5 * (arrY[2][nIndex] + arrY[3][nIndex]); - oPatch01.arrX[2][nIndex - 4] = 0.5 * (oPatch01.arrX[1][nIndex - 4] + dMidX); - oPatch01.arrY[2][nIndex - 4] = 0.5 * (oPatch01.arrY[1][nIndex - 4] + dMidY); - oPatch11.arrX[1][nIndex - 4] = 0.5 * (dMidX + oPatch11.arrX[2][nIndex - 4]); - oPatch11.arrY[1][nIndex - 4] = 0.5 * (dMidY + oPatch11.arrY[2][nIndex - 4]); - oPatch01.arrX[3][nIndex - 4] = 0.5 * (oPatch01.arrX[2][nIndex - 4] + oPatch11.arrX[1][nIndex - 4]); - oPatch01.arrY[3][nIndex - 4] = 0.5 * (oPatch01.arrY[2][nIndex - 4] + oPatch11.arrY[1][nIndex - 4]); - oPatch11.arrX[0][nIndex - 4] = oPatch01.arrX[3][nIndex - 4]; - oPatch11.arrY[0][nIndex - 4] = oPatch01.arrY[3][nIndex - 4]; - oPatch11.arrX[3][nIndex - 4] = arrX[3][nIndex]; - oPatch11.arrY[3][nIndex - 4] = arrY[3][nIndex]; - } - for (nIndex = 0; nIndex < nComponentsCount; ++nIndex) - { - oPatch00.arrColor[0][0].arrComp[nIndex] = pPatch->arrColor[0][0].arrComp[nIndex]; - oPatch00.arrColor[0][1].arrComp[nIndex] = (pPatch->arrColor[0][0].arrComp[nIndex] + pPatch->arrColor[0][1].arrComp[nIndex]) / 2; - oPatch01.arrColor[0][0].arrComp[nIndex] = oPatch00.arrColor[0][1].arrComp[nIndex]; - oPatch01.arrColor[0][1].arrComp[nIndex] = pPatch->arrColor[0][1].arrComp[nIndex]; - oPatch01.arrColor[1][1].arrComp[nIndex] = (pPatch->arrColor[0][1].arrComp[nIndex] + pPatch->arrColor[1][1].arrComp[nIndex]) / 2; - oPatch11.arrColor[0][1].arrComp[nIndex] = oPatch01.arrColor[1][1].arrComp[nIndex]; - oPatch11.arrColor[1][1].arrComp[nIndex] = pPatch->arrColor[1][1].arrComp[nIndex]; - oPatch11.arrColor[1][0].arrComp[nIndex] = (pPatch->arrColor[1][1].arrComp[nIndex] + pPatch->arrColor[1][0].arrComp[nIndex]) / 2; - oPatch10.arrColor[1][1].arrComp[nIndex] = oPatch11.arrColor[1][0].arrComp[nIndex]; - oPatch10.arrColor[1][0].arrComp[nIndex] = pPatch->arrColor[1][0].arrComp[nIndex]; - oPatch10.arrColor[0][0].arrComp[nIndex] = (pPatch->arrColor[1][0].arrComp[nIndex] + pPatch->arrColor[0][0].arrComp[nIndex]) / 2; - oPatch00.arrColor[1][0].arrComp[nIndex] = oPatch10.arrColor[0][0].arrComp[nIndex]; - oPatch00.arrColor[1][1].arrComp[nIndex] = (oPatch00.arrColor[1][0].arrComp[nIndex] + oPatch01.arrColor[1][1].arrComp[nIndex]) / 2; - oPatch01.arrColor[1][0].arrComp[nIndex] = oPatch00.arrColor[1][1].arrComp[nIndex]; - oPatch11.arrColor[0][0].arrComp[nIndex] = oPatch00.arrColor[1][1].arrComp[nIndex]; - oPatch10.arrColor[0][1].arrComp[nIndex] = oPatch00.arrColor[1][1].arrComp[nIndex]; - } - MeshFillPatch(&oPatch00, nComponentsCount, nDepth + 1); - MeshFillPatch(&oPatch10, nComponentsCount, nDepth + 1); - MeshFillPatch(&oPatch01, nComponentsCount, nDepth + 1); - MeshFillPatch(&oPatch11, nComponentsCount, nDepth + 1); - } - } - - void Graphics::DoEndPath() - { - if (m_pGState->IsCurPoint() && m_eClip != clipNone) - { - m_pGState->Clip(); - if (m_eClip == clipNormal) - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - } - else - { - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), true); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), true); - else - m_pOut->EoClip(m_pGState); - } - } - m_eClip = clipNone; - m_pGState->ClearPath(); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Clipping paths - //------------------------------------------------------------------------------------------------------------------------------- - - // W - void Graphics::OperatorClip(Object arrArguments[], int nArgumentsCount) - { - m_eClip = clipNormal; - } - - // W* - void Graphics::OperatorEOClip(Object arrArguments[], int nArgumentsCount) - { - m_eClip = clipEO; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Text objects - //------------------------------------------------------------------------------------------------------------------------------- - - // BT - void Graphics::OperatorBeginText(Object arrArguments[], int nArgumentsCount) - { - m_pOut->BegintTextObject(m_pGState); - m_pGState->SetTextMatrix(1, 0, 0, 1, 0, 0); - m_pGState->TextMoveTo(0, 0); - m_pOut->UpdateTextMatrix(m_pGState); - m_pOut->UpdateTextPos(m_pGState); - m_bFontChanged = true; - } - - // ET - void Graphics::OperatorEndText(Object arrArguments[], int nArgumentsCount) - { - m_pOut->EndTextObject(m_pGState); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Text state - //------------------------------------------------------------------------------------------------------------------------------- - - // Tc - void Graphics::OperatorSetCharSpacing(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetCharSpace(arrArguments[0].GetNum()); - m_pOut->UpdateCharSpace(m_pGState); - } - - // Tf - void Graphics::OperatorSetFont(Object arrArguments[], int nArgumentsCount) - { - GrFont *pFont = NULL; - - if (!(pFont = m_pResources->LookupFont(arrArguments[0].GetName()))) - { - return; - } -#ifdef _DEBUG - if (m_pDumpFile) - { - ::fprintf(m_pDumpFile, " Font:\n"); - ::fprintf(m_pDumpFile, " Tag = %s\n", pFont->GetTag()->GetBuffer()); - ::fprintf(m_pDumpFile, " Name = %s\n", pFont->GetBaseName() ? pFont->GetBaseName()->GetBuffer() : "???"); - ::fprintf(m_pDumpFile, " %g\n", arrArguments[1].GetNum()); - ::fflush(m_pDumpFile); - } -#endif - m_pGState->SetFont(pFont, arrArguments[1].GetNum()); - m_bFontChanged = true; - } - - // TL - void Graphics::OperatorSetTextLeading(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetLeading(arrArguments[0].GetNum()); - } - - // Tr - void Graphics::OperatorSetTextRender(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetRenderMode(arrArguments[0].GetInt()); - m_pOut->UpdateRender(m_pGState); - } - - // Ts - void Graphics::OperatorSetTextRise(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetRise(arrArguments[0].GetNum()); - m_pOut->UpdateRise(m_pGState); - } - - // Tw - void Graphics::OperatorSetWordSpacing(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetWordSpace(arrArguments[0].GetNum()); - m_pOut->UpdateWordSpace(m_pGState); - } - - // Tz - void Graphics::OperatorSetHorizScaling(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetHorizScaling(arrArguments[0].GetNum()); - m_pOut->UpdateHorizScaling(m_pGState); - m_bFontChanged = true; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Text positioning - //------------------------------------------------------------------------------------------------------------------------------- - - // Td - void Graphics::OperatorTextMove(Object arrArguments[], int nArgumentsCount) - { - double dDX = m_pGState->GetTextLineX() + arrArguments[0].GetNum(); - double dDy = m_pGState->GetTextLineY() + arrArguments[1].GetNum(); - m_pGState->TextMoveTo(dDX, dDy); - m_pOut->UpdateTextPos(m_pGState); - } - - // TD - void Graphics::OperatorTextMoveSet(Object arrArguments[], int nArgumentsCount) - { - double dDx = m_pGState->GetTextLineX() + arrArguments[0].GetNum(); - double dDy = arrArguments[1].GetNum(); - m_pGState->SetLeading(-dDy); - dDy += m_pGState->GetTextLineY(); - m_pGState->TextMoveTo(dDx, dDy); - m_pOut->UpdateTextPos(m_pGState); - } - - // Tm - void Graphics::OperatorSetTextMatrix(Object arrArguments[], int nArgumentsCount) - { - m_pGState->SetTextMatrix(arrArguments[0].GetNum(), arrArguments[1].GetNum(), arrArguments[2].GetNum(), arrArguments[3].GetNum(), arrArguments[4].GetNum(), arrArguments[5].GetNum()); - m_pGState->TextMoveTo(0, 0); - m_pOut->UpdateTextMatrix(m_pGState); - m_pOut->UpdateTextPos(m_pGState); - m_bFontChanged = true; - } - - // T* - void Graphics::OperatorTextNextLine(Object arrArguments[], int nArgumentsCount) - { - double dDx = m_pGState->GetTextLineX(); - double dDy = m_pGState->GetTextLineY() - m_pGState->GetLeading(); - m_pGState->TextMoveTo(dDx, dDy); - m_pOut->UpdateTextPos(m_pGState); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Text showing - //------------------------------------------------------------------------------------------------------------------------------- - - // Tj - void Graphics::OperatorShowText(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->GetFont()) - { - // TO DO: Error "No font in show") - return; - } - if (m_bFontChanged) - { - m_pOut->UpdateFont(m_pGState); - m_bFontChanged = false; - } - m_pOut->BeginStringOperator(m_pGState); - DoShowText(arrArguments[0].GetString()); - m_pOut->EndStringOperator(m_pGState); - } - - // ' - void Graphics::OperatorMoveShowText(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->GetFont()) - { - // TO DO: Error "No font in move/show" - return; - } - if (m_bFontChanged) - { - m_pOut->UpdateFont(m_pGState); - m_bFontChanged = false; - } - double dDx = m_pGState->GetTextLineX(); - double dDy = m_pGState->GetTextLineY() - m_pGState->GetLeading(); - m_pGState->TextMoveTo(dDx, dDy); - m_pOut->UpdateTextPos(m_pGState); - m_pOut->BeginStringOperator(m_pGState); - DoShowText(arrArguments[0].GetString()); - m_pOut->EndStringOperator(m_pGState); - } - - // '\' - void Graphics::OperatorMoveSetShowText(Object arrArguments[], int nArgumentsCount) - { - if (m_pGState->GetFont()) - { - // TO DO: Error "No font in move/set/show" - return; - } - if (m_bFontChanged) - { - m_pOut->UpdateFont(m_pGState); - m_bFontChanged = false; - } - m_pGState->SetWordSpace(arrArguments[0].GetNum()); - m_pGState->SetCharSpace(arrArguments[1].GetNum()); - - double dDx = m_pGState->GetTextLineX(); - double dDy = m_pGState->GetTextLineY() - m_pGState->GetLeading(); - - m_pGState->TextMoveTo(dDx, dDy); - m_pOut->UpdateWordSpace(m_pGState); - m_pOut->UpdateCharSpace(m_pGState); - m_pOut->UpdateTextPos(m_pGState); - m_pOut->BeginStringOperator(m_pGState); - DoShowText(arrArguments[2].GetString()); - m_pOut->EndStringOperator(m_pGState); - } - - // TJ - void Graphics::OperatorShowSpaceText(Object arrArguments[], int nArgumentsCount) - { - if (!m_pGState->GetFont()) - { - // TO DO: Error "No font in show/space" - return; - } - if (m_bFontChanged) - { - m_pOut->UpdateFont(m_pGState); - m_bFontChanged = false; - } - m_pOut->BeginStringOperator(m_pGState); - int nWMode = m_pGState->GetFont()->GetWMode(); - Array *pArray = arrArguments[0].GetArray(); - - for (int nIndex = 0; nIndex < pArray->GetCount(); ++nIndex) - { - Object oTemp; - pArray->Get(nIndex, &oTemp); - if (oTemp.IsNum()) - { - if (nWMode) - { - m_pGState->TextShift(0, -oTemp.GetNum() * 0.001 * fabs(m_pGState->GetFontSize())); - } - else - { - m_pGState->TextShift(-oTemp.GetNum() * 0.001 * fabs(m_pGState->GetFontSize()), 0); - } - m_pOut->UpdateTextShift(m_pGState, oTemp.GetNum()); - } - else if (oTemp.IsString()) - { - DoShowText(oTemp.GetString()); - } - else - { - // TO DO: Error "Element of show/space array must be number or string" - } - oTemp.Free(); - } - m_pOut->EndStringOperator(m_pGState); - } - - //------------------------------------------------------------------------------------------------------------------------------- - void Graphics::DoShowText(StringExt *seString) - { - CharCode nCode; - Unicode arrUnicode[8]; - double x, y, dx, dy, dx2, dy2, tdx, tdy; - double originX, originY, tOriginX, tOriginY; - - char *pBuffer; - int nLen, nCurLen, uLen; - - GrFont *pFont = m_pGState->GetFont(); - int nWMode = pFont->GetWMode(); - - if (m_pOut->UseDrawChar()) - { - m_pOut->BeginString(m_pGState, seString); - } - - // Обработка шрифта Type 3 - if (pFont->GetType() == fontType3 && m_pOut->InterpretType3Chars()) - { - double *pMatrix = m_pGState->GetCTM(); - double pOldCTM[6], pNewCTM[6]; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - pOldCTM[nIndex] = pMatrix[nIndex]; - } - pMatrix = m_pGState->GetTextMatrix(); - pNewCTM[0] = pMatrix[0] * pOldCTM[0] + pMatrix[1] * pOldCTM[2]; - pNewCTM[1] = pMatrix[0] * pOldCTM[1] + pMatrix[1] * pOldCTM[3]; - pNewCTM[2] = pMatrix[2] * pOldCTM[0] + pMatrix[3] * pOldCTM[2]; - pNewCTM[3] = pMatrix[2] * pOldCTM[1] + pMatrix[3] * pOldCTM[3]; - - pMatrix = pFont->GetFontMatrix(); - pNewCTM[0] = pMatrix[0] * pNewCTM[0] + pMatrix[1] * pNewCTM[2]; - pNewCTM[1] = pMatrix[0] * pNewCTM[1] + pMatrix[1] * pNewCTM[3]; - pNewCTM[2] = pMatrix[2] * pNewCTM[0] + pMatrix[3] * pNewCTM[2]; - pNewCTM[3] = pMatrix[2] * pNewCTM[1] + pMatrix[3] * pNewCTM[3]; - - pNewCTM[0] *= m_pGState->GetFontSize(); - pNewCTM[1] *= m_pGState->GetFontSize(); - pNewCTM[2] *= m_pGState->GetFontSize(); - pNewCTM[3] *= m_pGState->GetFontSize(); - pNewCTM[0] *= m_pGState->GetHorizScaling(); - pNewCTM[2] *= m_pGState->GetHorizScaling(); - - double dRiseX, dRiseY; - m_pGState->TextTransformDelta(0, m_pGState->GetRise(), &dRiseX, &dRiseY); - double dCurX = m_pGState->GetCurX(); - double dCurY = m_pGState->GetCurY(); - double dLineX = m_pGState->GetTextLineX(); - double dLineY = m_pGState->GetTextLineY(); - Parser *pOldParser = m_pParser; - pBuffer = seString->GetBuffer(); - nLen = seString->GetLength(); - while (nLen > 0) - { - nCurLen = pFont->GetNextChar(pBuffer, nLen, &nCode, arrUnicode, (int)(sizeof(arrUnicode) / sizeof(Unicode)), &uLen, &dx, &dy, &originX, &originY); - dx = dx * m_pGState->GetFontSize() + m_pGState->GetCharSpace(); - if (nCurLen == 1 && *pBuffer == ' ') - { - dx += m_pGState->GetWordSpace(); - } - dx *= m_pGState->GetHorizScaling(); - dy *= m_pGState->GetFontSize(); - m_pGState->TextTransformDelta(dx, dy, &tdx, &tdy); - m_pGState->Transform(dCurX + dRiseX, dCurY + dRiseY, &x, &y); - SaveGState(); - m_pGState->SetCTM(pNewCTM[0], pNewCTM[1], pNewCTM[2], pNewCTM[3], x, y); - //Значения CTM concat здесь неправильные (но они никогда не используются) - m_pOut->UpdateCTM(m_pGState, 1, 0, 0, 1, 0, 0); - if (!m_pOut->BeginType3Char(m_pGState, dCurX + dRiseX, dCurY + dRiseY, tdx, tdy, nCode, arrUnicode, uLen)) - { - Object oCharProc; - ((Gr8BitFont *)pFont)->GetCharProc(nCode, &oCharProc); - Dict *pResourcesDict; - if ((pResourcesDict = ((Gr8BitFont *)pFont)->GetResources())) - { - PushResources(pResourcesDict); - } - if (oCharProc.IsStream()) - { - Display(&oCharProc, false); - } - else - { - // TO DO: Error "Missing or bad Type3 CharProc entry" - } - m_pOut->EndType3Char(m_pGState); - if (pResourcesDict) - { - PopResources(); - } - oCharProc.Free(); - } - RestoreGState(); - // Поскольку функция RestoreGState() не восстанавливает текущей позиции, - // поэтому нам нужно сохранять и восстанавливать ее самим - dCurX += tdx; - dCurY += tdy; - m_pGState->MoveTo(dCurX, dCurY); - m_pGState->TextSetPos(dLineX, dLineY); - pBuffer += nCurLen; - nLen -= nCurLen; - } - m_pParser = pOldParser; - } - else if (m_pOut->UseDrawChar()) - { - double dRiseX, dRiseY; - m_pGState->TextTransformDelta(0, m_pGState->GetRise(), &dRiseX, &dRiseY); - pBuffer = seString->GetBuffer(); - nLen = seString->GetLength(); - while (nLen > 0) - { - nCurLen = pFont->GetNextChar(pBuffer, nLen, &nCode, arrUnicode, (int)(sizeof(arrUnicode) / sizeof(Unicode)), &uLen, &dx, &dy, &originX, &originY); - if (nWMode) - { - dx *= m_pGState->GetFontSize(); - dy = dy * m_pGState->GetFontSize() + m_pGState->GetCharSpace(); - if (nCurLen == 1 && *pBuffer == ' ') - { - dy += m_pGState->GetWordSpace(); - } - } - else - { - dx = dx * m_pGState->GetFontSize() + m_pGState->GetCharSpace(); - if (nCurLen == 1 && *pBuffer == ' ') - { - dx += m_pGState->GetWordSpace(); - } - dx *= m_pGState->GetHorizScaling(); - dy *= m_pGState->GetFontSize(); - } - m_pGState->TextTransformDelta(dx, dy, &tdx, &tdy); - originX *= m_pGState->GetFontSize(); - originY *= m_pGState->GetFontSize(); - m_pGState->TextTransformDelta(originX, originY, &tOriginX, &tOriginY); - m_pOut->DrawChar(m_pGState, m_pGState->GetCurX() + dRiseX, m_pGState->GetCurY() + dRiseY, tdx, tdy, tOriginX, tOriginY, nCode, nCurLen, arrUnicode, uLen); - m_pGState->Shift(tdx, tdy); - pBuffer += nCurLen; - nLen -= nCurLen; - } - } - else - { - dx = dy = 0; - pBuffer = seString->GetBuffer(); - nLen = seString->GetLength(); - int nCharsCount = 0, nSpacesCount = 0; - while (nLen > 0) - { - nCurLen = pFont->GetNextChar(pBuffer, nLen, &nCode, arrUnicode, (int)(sizeof(arrUnicode) / sizeof(Unicode)), &uLen, &dx2, &dy2, &originX, &originY); - dx += dx2; - dy += dy2; - if (nCurLen == 1 && *pBuffer == ' ') - { - ++nSpacesCount; - } - ++nCharsCount; - pBuffer += nCurLen; - nLen -= nCurLen; - } - if (nWMode) - { - dx *= m_pGState->GetFontSize(); - dy = dy * m_pGState->GetFontSize() + nCharsCount * m_pGState->GetCharSpace() + nSpacesCount * m_pGState->GetWordSpace(); - } - else - { - dx = dx * m_pGState->GetFontSize() + nCharsCount * m_pGState->GetCharSpace() + nSpacesCount * m_pGState->GetWordSpace(); - dx *= m_pGState->GetHorizScaling(); - dy *= m_pGState->GetFontSize(); - } - m_pGState->TextTransformDelta(dx, dy, &tdx, &tdy); - m_pOut->DrawString(m_pGState, seString); - m_pGState->Shift(tdx, tdy); - } - - if (m_pOut->UseDrawChar()) - { - m_pOut->EndString(m_pGState); - } - - m_nUpdateLevel += 10 * seString->GetLength(); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // XObjects - //------------------------------------------------------------------------------------------------------------------------------- - - // Do - void Graphics::OperatorXObject(Object arrArguments[], int nArgumentsCount) - { - char *sName = arrArguments[0].GetName(); - Object oXObject; - if (!m_pResources->LookupXObject(sName, &oXObject)) - { - return; - } - if (!oXObject.IsStream()) - { - // TO DO: Error "XObject is wrong type" - oXObject.Free(); - return; - } -#if OPI_SUPPORT - Object oOPI; - oXObject.streamGetDict()->lookup("OPI", &oOPI); - if ( oOPI.IsDict() ) - { - m_pOut->opiBegin( state, oOPI.GetDict() ); - } -#endif - Object oSub; - oXObject.StreamGetDict()->Search("Subtype", &oSub); - if (oSub.IsName("Image")) - { - if (m_pOut->NeedNonText()) - { - Object oRef; - m_pResources->LookupAndCopyXObject(sName, &oRef); - DoImage(&oRef, oXObject.GetStream(), false); - oRef.Free(); - } - } - else if (oSub.IsName("Form")) - { - Object oRef; - m_pResources->LookupAndCopyXObject(sName, &oRef); - if (m_pOut->UseDrawForm() && oRef.IsRef()) - { - m_pOut->DrawForm(oRef.GetRef()); - } - else - { - DoForm(&oXObject); - } - oRef.Free(); - } - else if (oSub.IsName("PS")) - { - Object oLevel; - oXObject.StreamGetDict()->Search("Level1", &oLevel); - m_pOut->PSXObject(oXObject.GetStream(), oLevel.IsStream() ? oLevel.GetStream() : (Stream *)NULL); - // Добавленно - oLevel.Free(); - } - else if (oSub.IsName()) - { - // TO DO: Error "Unknown XObject subtype" - } - else - { - // TO DO: Error "XObject subtype is missing or wrong type" - } - oSub.Free(); -#if OPI_SUPPORT - if ( oOPI.IsDict() ) - { - m_pOut->opiEnd( state, oOPI.GetDict() ); - } - oOPI.Free(); -#endif - oXObject.Free(); - } - - void Graphics::DoImage(Object *pRef, Stream *pStream, bool bInlineImage) - { - // Считываем информацию из потока - int nBitsPerComponent = 0; - StreamColorSpaceMode eCSMode = streamCSNone; - pStream->GetImageParams(&nBitsPerComponent, &eCSMode); - - Dict *pDict = pStream->GetDict(); - - // Width - Object oDictItem; - pDict->Search("Width", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("W", &oDictItem); - } - - int nWidth = 0; - if (!oDictItem.IsInt()) - { - if (oDictItem.IsNum()) - { - nWidth = (int)oDictItem.GetNum(); - } - else - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - } - else - { - nWidth = oDictItem.GetInt(); - } - oDictItem.Free(); - - // Height - pDict->Search("Height", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("H", &oDictItem); - } - - int nHeight = 0; - if (!oDictItem.IsInt()) - { - if (oDictItem.IsNum()) - { - nHeight = (int)oDictItem.GetNum(); - } - else - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - } - else - { - nHeight = oDictItem.GetInt(); - } - oDictItem.Free(); - - // Проверяем: может быть это маска? - pDict->Search("ImageMask", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("IM", &oDictItem); - } - bool bMask = false; - if (oDictItem.IsBool()) - { - bMask = oDictItem.GetBool(); - } - else if (!oDictItem.IsNull()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - oDictItem.Free(); - - // BitsPerComponent - if (nBitsPerComponent == 0) - { - pDict->Search("BitsPerComponent", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("BPC", &oDictItem); - } - if (oDictItem.IsInt()) - { - nBitsPerComponent = oDictItem.GetInt(); - } - else if (bMask) - { - nBitsPerComponent = 1; - } - else - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - oDictItem.Free(); - } - - if (bMask) - { - // У маски это значение nBitsPerComponent должно быть 1 - if (nBitsPerComponent != 1) - { - // TO DO: Error "Bad image parameters" - return; - } - bool bInvert = false; - pDict->Search("Decode", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("D", &oDictItem); - } - if (oDictItem.IsArray()) - { - Object oTemp; - oDictItem.ArrayGet(0, &oTemp); - if (oTemp.IsInt() && oTemp.GetInt() == 1) - bInvert = true; - oTemp.Free(); - } - else if (!oDictItem.IsNull()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - oDictItem.Free(); - - // Рисуем маску - m_pOut->DrawImageMask(m_pGState, pRef, pStream, nWidth, nHeight, bInvert, bInlineImage); - } - else - { - // ColorSpace - pDict->Search("ColorSpace", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("CS", &oDictItem); - } - if (oDictItem.IsName()) - { - Object oTemp; - m_pResources->LookupColorSpace(oDictItem.GetName(), &oTemp); - if (!oTemp.IsNull()) - { - oDictItem.Free(); - oDictItem = oTemp; - } - else - { - oTemp.Free(); - } - } - GrColorSpace *pColorSpace; - if (!oDictItem.IsNull()) - { - pColorSpace = GrColorSpace::Parse(&oDictItem); - } - else if (eCSMode == streamCSDeviceGray) - { - pColorSpace = new GrDeviceGrayColorSpace(); - } - else if (eCSMode == streamCSDeviceRGB) - { - pColorSpace = new GrDeviceRGBColorSpace(); - } - else if (eCSMode == streamCSDeviceCMYK) - { - pColorSpace = new GrDeviceCMYKColorSpace(); - } - else - { - pColorSpace = NULL; - } - oDictItem.Free(); - if (!pColorSpace) - { - // TO DO: Error "Bad image parameters" - return; - } - - // Decode - pDict->Search("Decode", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pDict->Search("D", &oDictItem); - } - GrImageColorMap *pColorMap = new GrImageColorMap(nBitsPerComponent, &oDictItem, pColorSpace); - oDictItem.Free(); - if (!pColorMap->IsValid()) - { - delete pColorMap; - // TO DO: Error "Bad image parameters" - return; - } - - // Mask/SMask - bool bHaveColorKeyMask = false, bHaveExplicitMask = false, bHaveSoftMask = false; - Stream *pMaskStream = NULL; - int nMaskWidth = 0, nMaskHeight = 0; - bool bMaskInvert = false; - GrImageColorMap *pMaskColorMap = NULL; - int arrMaskColors[2 * GrColorMaxComps]; - unsigned char arrMatteColor[GrColorMaxComps]; - bool bMatte = false; - - - Object oMask, oSMask; - pDict->Search("Mask", &oMask); - pDict->Search("SMask", &oSMask); - - Dict *pMaskDict = NULL; - - if (oSMask.IsStream()) - { - if (bInlineImage) - { - // Тут наверное нужно освободить память oMask, oSMask - // TO DO: Error "Bad image parameters" - return; - } - pMaskStream = oSMask.GetStream(); - pMaskDict = oSMask.StreamGetDict(); - - // Width - pMaskDict->Search("Width", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("W", &oDictItem); - } - - if (!oDictItem.IsInt()) - { - if (oDictItem.IsNum()) - { - nMaskWidth = (int)oDictItem.GetNum(); - } - else - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - } - else - { - nMaskWidth = oDictItem.GetInt(); - } - oDictItem.Free(); - - // Height - pMaskDict->Search("Height", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("H", &oDictItem); - } - - if (!oDictItem.IsInt()) - { - if (oDictItem.IsNum()) - { - nMaskHeight = (int)oDictItem.GetNum(); - } - else - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - } - else - { - nMaskHeight = oDictItem.GetInt(); - } - oDictItem.Free(); - - // BitsPerComponent - pMaskDict->Search("BitsPerComponent", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("BPC", &oDictItem); - } - if (!oDictItem.IsInt()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - int nMaskBitsPerComponent = oDictItem.GetInt(); - oDictItem.Free(); - - // ColorSpace - pMaskDict->Search("ColorSpace", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("CS", &oDictItem); - } - if (oDictItem.IsName()) - { - Object oTemp; - m_pResources->LookupColorSpace(oDictItem.GetName(), &oTemp); - if (!oTemp.IsNull()) - { - oDictItem.Free(); - oDictItem = oTemp; - } - else - { - oTemp.Free(); - } - } - GrColorSpace *pMaskColorSpace = GrColorSpace::Parse(&oDictItem); - oDictItem.Free(); - if (!pMaskColorSpace || pMaskColorSpace->GetMode() != csDeviceGray) - { - // TO DO: Error "Bad image parameters" - return; - } - - // Decode - pMaskDict->Search("Decode", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("D", &oDictItem); - } - pMaskColorMap = new GrImageColorMap(nMaskBitsPerComponent, &oDictItem, pMaskColorSpace); - oDictItem.Free(); - if (!pMaskColorMap->IsValid()) - { - delete pMaskColorMap; - // TO DO: Error "Bad image parameters" - return; - } - - pMaskDict->Search("Matte", &oDictItem); - if (oDictItem.IsArray()) - { - bMatte = true; - for (int nMatteIndex = 0, nMatteCount = oDictItem.ArrayGetLength(); nMatteIndex < nMatteCount; ++nMatteIndex) - { - Object oTemp; - oDictItem.ArrayGet(nMatteIndex, &oTemp); - arrMatteColor[nMatteIndex] = fmin(255, fmax(0, (int)(oTemp.GetNum() * 255))); - oTemp.Free(); - } - } - - bHaveSoftMask = true; - } - else if (oMask.IsArray()) - { - for (int nIndex = 0; nIndex < oMask.ArrayGetLength() && nIndex < 2 * GrColorMaxComps; ++nIndex) - { - Object oTemp; - oMask.ArrayGet(nIndex, &oTemp); - arrMaskColors[nIndex] = oTemp.GetInt(); - oTemp.Free(); - } - bHaveColorKeyMask = true; - } - else if (oMask.IsStream()) - { - if (bInlineImage) - { - // TO DO: Error "Bad image parameters" - return; - } - pMaskStream = oMask.GetStream(); - pMaskDict = oMask.StreamGetDict(); - - // Width - pMaskDict->Search("Width", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("W", &oDictItem); - } - if (!oDictItem.IsInt()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - nMaskWidth = oDictItem.GetInt(); - oDictItem.Free(); - - // Height - pMaskDict->Search("Height", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("H", &oDictItem); - } - if (!oDictItem.IsInt()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - nMaskHeight = oDictItem.GetInt(); - oDictItem.Free(); - - // ImageMask - pMaskDict->Search("ImageMask", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("IM", &oDictItem); - } - if (!oDictItem.IsBool() || !oDictItem.GetBool()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - oDictItem.Free(); - - // Decode - bMaskInvert = false; - pMaskDict->Search("Decode", &oDictItem); - if (oDictItem.IsNull()) - { - oDictItem.Free(); - pMaskDict->Search("D", &oDictItem); - } - if (oDictItem.IsArray()) - { - Object oTemp; - oDictItem.ArrayGet(0, &oTemp); - if (oTemp.IsInt() && oTemp.GetInt() == 1) - { - bMaskInvert = true; - } - oTemp.Free(); - } - else if (!oDictItem.IsNull()) - { - oDictItem.Free(); - // TO DO: Error "Bad image parameters" - return; - } - oDictItem.Free(); - bHaveExplicitMask = true; - } - - // Рисуем - if (bHaveSoftMask) - { - m_pOut->DrawSoftMaskedImage(m_pGState, pRef, pStream, nWidth, nHeight, pColorMap, pMaskStream, nMaskWidth, nMaskHeight, pMaskColorMap, bMatte ? arrMatteColor : NULL); - delete pMaskColorMap; - } - else if (bHaveExplicitMask) - { - m_pOut->DrawMaskedImage(m_pGState, pRef, pStream, nWidth, nHeight, pColorMap, pMaskStream, nMaskWidth, nMaskHeight, bMaskInvert); - } - else - { - m_pOut->DrawImage(m_pGState, pRef, pStream, nWidth, nHeight, pColorMap, bHaveColorKeyMask ? arrMaskColors : (int *)NULL, bInlineImage); - } - delete pColorMap; - - oMask.Free(); - oSMask.Free(); - } - - - int nUpdater = 0; - if ((nUpdater = nWidth * nHeight) > 1000) - { - nUpdater = 1000; - } - m_nUpdateLevel += nUpdater; - - return; - } - - void Graphics::DoForm(Object *pStream) - { - double arrMatrix[6], arrBBox[4]; - - // Проверяем глубину рекурсии - if (m_nFormDepth > 20) - { - return; - } - - Dict *pDict = pStream->StreamGetDict(); - Object oDictItem; - - // FormType - pDict->Search("FormType", &oDictItem); - if (!(oDictItem.IsNull() || (oDictItem.IsInt() && oDictItem.GetInt() == 1))) - { - // TO DO: Error "Unknown form type" - } - oDictItem.Free(); - - // BBox - Object oBBox; - pDict->Search("BBox", &oBBox); - if (!oBBox.IsArray()) - { - oBBox.Free(); - // TO DO: Error "Bad form bounding box" - return; - } - - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - Object oTemp; - oBBox.ArrayGet(nIndex, &oTemp); - arrBBox[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - oBBox.Free(); - - // Matrix - Object oMatrix; - pDict->Search("Matrix", &oMatrix); - if (oMatrix.IsArray()) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - Object oTemp; - oMatrix.ArrayGet(nIndex, &oTemp); - arrMatrix[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - arrMatrix[0] = 1; arrMatrix[1] = 0; - arrMatrix[2] = 0; arrMatrix[3] = 1; - arrMatrix[4] = 0; arrMatrix[5] = 0; - } - oMatrix.Free(); - - // Resources - Object oResources; - pDict->Search("Resources", &oResources); - Dict *pResourcesDict = oResources.IsDict() ? oResources.GetDict() : (Dict *)NULL; - - // Transparency Group - bool bTranspGroup = false, bIsolated = false, bKnockout = false; - GrColorSpace *pBlendingColorSpace = NULL; - if (pDict->Search("Group", &oDictItem)->IsDict()) - { - Object oTransp; - if (oDictItem.DictLookup("S", &oTransp)->IsName("Transparency")) - { - bTranspGroup = true; - Object oTemp; - if (!oDictItem.DictLookup("CS", &oTemp)->IsNull()) - { - pBlendingColorSpace = GrColorSpace::Parse(&oTemp); - } - oTemp.Free(); - if (oDictItem.DictLookup("I", &oTemp)->IsBool()) - { - bIsolated = oTemp.GetBool(); - } - oTemp.Free(); - if (oDictItem.DictLookup("K", &oTemp)->IsBool()) - { - bKnockout = oTemp.GetBool(); - } - oTemp.Free(); - } - oTransp.Free(); - } - oDictItem.Free(); - - // Рисуем - ++m_nFormDepth; - DoForm(pStream, pResourcesDict, arrMatrix, arrBBox, bTranspGroup, false, pBlendingColorSpace, bIsolated, bKnockout); - --m_nFormDepth; - - if (pBlendingColorSpace) - { - delete pBlendingColorSpace; - } - oResources.Free(); - } - - void Graphics::DoForm(Object *pStream, Dict *pResourcesDict, double *pMatrix, double *pBBox, bool bTranspGroup, bool bSMask, GrColorSpace *pBlendingColorSpace, bool bIsolated, bool bKnockout, bool bAlpha, Function *pTransferFunctions, GrColor *pBackdropColor) - { - // Записываем текущую директорию ресурсов в стек - PushResources(pResourcesDict); - - // Сохраняем текущий GState - SaveGState(); - - // Очищаем Path(если там что-то было) - m_pGState->ClearPath(); - - // Сохраняем текущий парсер - Parser *pOldParser = m_pParser; - - // CTM - m_pGState->ConcatCTM(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], pMatrix[4], pMatrix[5]); - m_pOut->UpdateCTM(m_pGState, pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], pMatrix[4], pMatrix[5]); - - // BBox - m_pGState->MoveTo(pBBox[0], pBBox[1]); - m_pGState->LineTo(pBBox[2], pBBox[1]); - m_pGState->LineTo(pBBox[2], pBBox[3]); - m_pGState->LineTo(pBBox[0], pBBox[3]); - m_pGState->ClosePath(); - m_pGState->Clip(); - m_pGState->GetClip()->ClipToPath(m_pGState->GetPath()->Copy(), m_pGState->GetCTM(), false); - - if (m_pOut->UseClipTo()) - m_pOut->ClipToPath(m_pGState, m_pGState->GetPath(), m_pGState->GetCTM(), false); - else - m_pOut->Clip(m_pGState); - - m_pGState->ClearPath(); - - if (bSMask || bTranspGroup) - { - if (m_pGState->GetBlendMode() != grBlendNormal) - { - m_pGState->SetBlendMode(grBlendNormal); - m_pOut->UpdateBlendMode(m_pGState); - } - if (!m_pOut->UseSimpleTransparentGroup()) - { - if (m_pGState->GetFillOpacity() != 1) - { - m_pGState->SetFillOpacity(1); - m_pOut->UpdateFillOpacity(m_pGState); - } - if (m_pGState->GetStrokeOpacity() != 1) - { - m_pGState->SetStrokeOpacity(1); - m_pOut->UpdateStrokeOpacity(m_pGState); - } - } - m_pOut->ClearSoftMask(m_pGState); - m_pOut->BeginTransparencyGroup(m_pGState, pBBox, pBlendingColorSpace, bIsolated, bKnockout, bSMask); - } - - double arrOldBaseMatrix[6]; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - arrOldBaseMatrix[nIndex] = m_arrBaseMatrix[nIndex]; - m_arrBaseMatrix[nIndex] = m_pGState->GetCTM()[nIndex]; - } - - // Рисуем саму форму - Display(pStream, false); - - if (bSMask || bTranspGroup) - { - m_pOut->EndTransparencyGroup(m_pGState); - } - - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrBaseMatrix[nIndex] = arrOldBaseMatrix[nIndex]; - } - - - // Восстанавливаем начальные данные - m_pParser = pOldParser; - RestoreGState(); - PopResources(); - - if (bSMask) - { - m_pOut->SetSoftMask(m_pGState, pBBox, bAlpha, pTransferFunctions, pBackdropColor); - } - else if (bTranspGroup) - { - m_pOut->PaintTransparencyGroup(m_pGState, pBBox); - } - - return; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Inline images - //------------------------------------------------------------------------------------------------------------------------------- - - // BI - void Graphics::OperatorBeginImage(Object arrArguments[], int nArgumentsCount) - { - Stream *pStream = BuildImageStream(); - - if (pStream) - { - DoImage(NULL, pStream, true); - - // Ищем оператор EI - int nChar1 = pStream->GetUndecodedStream()->GetChar(); - int nChar2 = pStream->GetUndecodedStream()->GetChar(); - - while (!(nChar1 == 'E' && nChar2 == 'I') && nChar2 != EOF) - { - nChar1 = nChar2; - nChar2 = pStream->GetUndecodedStream()->GetChar(); - } - delete pStream; - } - } - - // ID - void Graphics::OperatorImageData(Object arrArguments[], int nArgumentsCount) - { - // TO DO: Error "Internal: got 'ID' operator" - } - - // EI - void Graphics::OperatorEndImage(Object arrArguments[], int nArgumentsCount) - { - // TO DO: Error "Internal: got 'EI' operator" - } - - //------------------------------------------------------------------------------------------------------------------------------- - Stream *Graphics::BuildImageStream() - { - Object oDict; - oDict.InitDict(m_pXref); - Object oObject; - m_pParser->GetObject(&oObject); - - while (!oObject.IsCommand("ID") && !oObject.IsEOF()) - { - if (!oObject.IsName()) - { - // TO DO: Error "Inline image dictionary key must be a name object" - oObject.Free(); - } - else - { - char* sKey = CopyString(oObject.GetName()); - oObject.Free(); - m_pParser->GetObject(&oObject); - if (oObject.IsEOF() || oObject.IsError()) - { - MemUtilsFree(sKey); - break; - } - oDict.DictAdd(sKey, &oObject); - } - m_pParser->GetObject(&oObject); - } - if (oObject.IsEOF()) - { - // TO DO: Error "End of file in inline image" - oObject.Free(); - oDict.Free(); - return NULL; - } - oObject.Free(); - - Stream *pStream = new EmbedStream(m_pParser->GetStream(), &oDict, false, 0); - pStream = pStream->AddFilters(&oDict); - - return pStream; - } - - - //------------------------------------------------------------------------------------------------------------------------------- - // Type 3 fonts - //------------------------------------------------------------------------------------------------------------------------------- - - // d0 - void Graphics::OperatorSetCharWidth(Object arrArguments[], int nArgumentsCount) - { - m_pOut->Type3D0(m_pGState, arrArguments[0].GetNum(), arrArguments[1].GetNum()); - } - - // d1 - void Graphics::OperatorSetCacheDevice(Object arrArguments[], int nArgumentsCount) - { - m_pOut->Type3D1(m_pGState, arrArguments[0].GetNum(), arrArguments[1].GetNum(), arrArguments[2].GetNum(), arrArguments[3].GetNum(), arrArguments[4].GetNum(), arrArguments[5].GetNum()); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Compatibility - //------------------------------------------------------------------------------------------------------------------------------- - - // BX - void Graphics::OperatorBeginIgnoreUndef(Object arrArguments[], int nArgumentsCount) - { - ++m_nIgnoreUndef; - } - - // EX - void Graphics::OperatorEndIgnoreUndef(Object arrArguments[], int nArgumentsCount) - { - if (m_nIgnoreUndef > 0) - --m_nIgnoreUndef; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Marked content - //------------------------------------------------------------------------------------------------------------------------------- - - // BDC/BMC - void Graphics::OperatorBeginMarkedContent(Object arrArguments[], int nArgumentsCount) - { - } - - // EMC - void Graphics::OperatorEndMarkedContent(Object arrArguments[], int nArgumentsCount) - { - } - - // DP/MP - void Graphics::OperatorMarkPoint(Object arrArguments[], int nArgumentsCount) - { - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Дополнительные функции - //------------------------------------------------------------------------------------------------------------------------------- - - void Graphics::DrawAnnotation(Object *pStream, AnnotBorderStyle *pBorderStyle, double dMinX, double dMinY, double dMaxX, double dMaxY) - { - double dX, dY; - - // Преобразовываем Annotation BBox из стандартного пользовательского пространства в - // текущее пользовательское пространство: (BBox * BaseMatrix) * InvCTM - double *pCTM = m_pGState->GetCTM(); - double dDet = 1 / (pCTM[0] * pCTM[3] - pCTM[1] * pCTM[2]); - double arrInvCTM[6]; - arrInvCTM[0] = pCTM[3] * dDet; - arrInvCTM[1] = -pCTM[1] * dDet; - arrInvCTM[2] = -pCTM[2] * dDet; - arrInvCTM[3] = pCTM[0] * dDet; - arrInvCTM[4] = (pCTM[2] * pCTM[5] - pCTM[3] * pCTM[4]) * dDet; - arrInvCTM[5] = (pCTM[1] * pCTM[4] - pCTM[0] * pCTM[5]) * dDet; - - dX = m_arrBaseMatrix[0] * dMinX + m_arrBaseMatrix[2] * dMinY + m_arrBaseMatrix[4]; - dY = m_arrBaseMatrix[1] * dMinX + m_arrBaseMatrix[3] * dMinY + m_arrBaseMatrix[5]; - double dAnnotX0 = arrInvCTM[0] * dX + arrInvCTM[2] * dY + arrInvCTM[4]; - double dAnnotY0 = arrInvCTM[1] * dX + arrInvCTM[3] * dY + arrInvCTM[5]; - - dX = m_arrBaseMatrix[0] * dMaxX + m_arrBaseMatrix[2] * dMaxY + m_arrBaseMatrix[4]; - dY = m_arrBaseMatrix[1] * dMaxX + m_arrBaseMatrix[3] * dMaxY + m_arrBaseMatrix[5]; - double dAnnotX1 = arrInvCTM[0] * dX + arrInvCTM[2] * dY + arrInvCTM[4]; - double dAnnotY1 = arrInvCTM[1] * dX + arrInvCTM[3] * dY + arrInvCTM[5]; - - if (dAnnotX0 > dAnnotX1) - { - dX = dAnnotX0; - dAnnotX0 = dAnnotX1; - dAnnotX1 = dX; - } - if (dAnnotY0 > dAnnotY1) - { - dY = dAnnotY0; - dAnnotY0 = dAnnotY1; - dAnnotY1 = dY; - } - - if (pStream->IsStream()) - { - Dict *pDict = pStream->StreamGetDict(); - - // BBox - Object oBBox; - pDict->Search("BBox", &oBBox); - double arrBBox[4]; - if (!oBBox.IsArray()) - { - oBBox.Free(); - // TO DO: Error "Bad form bounding box" - return; - } - for (int nIndex = 0; nIndex < 4; ++nIndex) - { - Object oTemp; - oBBox.ArrayGet(nIndex, &oTemp); - arrBBox[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - oBBox.Free(); - - // Matrix - Object oMatrix; - pDict->Search("Matrix", &oMatrix); - double arrMatrix[6]; - if (oMatrix.IsArray()) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - Object oTemp; - oMatrix.ArrayGet(nIndex, &oTemp); - arrMatrix[nIndex] = oTemp.GetNum(); - oTemp.Free(); - } - } - else - { - arrMatrix[0] = 1; arrMatrix[1] = 0; - arrMatrix[2] = 0; arrMatrix[3] = 1; - arrMatrix[4] = 0; arrMatrix[5] = 0; - } - oMatrix.Free(); - - double dFormX0 = arrBBox[0] * arrMatrix[0] + arrBBox[1] * arrMatrix[2] + arrMatrix[4]; - double dFormY0 = arrBBox[0] * arrMatrix[1] + arrBBox[1] * arrMatrix[3] + arrMatrix[5]; - double dFormX1 = arrBBox[2] * arrMatrix[0] + arrBBox[3] * arrMatrix[2] + arrMatrix[4]; - double dFormY1 = arrBBox[2] * arrMatrix[1] + arrBBox[3] * arrMatrix[3] + arrMatrix[5]; - - if (dFormX0 > dFormX1) - { - dX = dFormX0; - dFormX0 = dFormX1; - dFormX1 = dX; - } - if (dFormY0 > dFormY1) - { - dY = dFormY0; - dFormY0 = dFormY1; - dFormY1 = dY; - } - - // Растягиваем до размеров Annotation BBox - double dScaleX, dScaleY; - if (dFormX1 == dFormX0) - { - // Такого не должно быть - dScaleX = 1; - } - else - { - dScaleX = (dAnnotX1 - dAnnotX0) / (dFormX1 - dFormX0); - } - if (dFormY1 == dFormY0) - { - // Такого не должно быть - dScaleY = 1; - } - else - { - dScaleY = (dAnnotY1 - dAnnotY0) / (dFormY1 - dFormY0); - } - - arrMatrix[0] *= dScaleX; - arrMatrix[2] *= dScaleX; - arrMatrix[4] = (arrMatrix[4] - dFormX0) * dScaleX + dAnnotX0; - arrMatrix[1] *= dScaleY; - arrMatrix[3] *= dScaleY; - arrMatrix[5] = (arrMatrix[5] - dFormY0) * dScaleY + dAnnotY0; - - // Resources - Object oResources; - pDict->Search("Resources", &oResources); - Dict *pResourcesDict = oResources.IsDict() ? oResources.GetDict() : (Dict *)NULL; - - // Рисуем - DoForm(pStream, pResourcesDict, arrMatrix, arrBBox); - - oResources.Free(); - } - - // Рисуем рамку - if (pBorderStyle && pBorderStyle->GetWidth() > 0) - { - if (m_pGState->GetStrokeColorSpace()->GetMode() != csDeviceRGB) - { - m_pGState->SetStrokePattern(NULL); - m_pGState->SetStrokeColorSpace(new GrDeviceRGBColorSpace()); - m_pOut->UpdateStrokeColorSpace(m_pGState); - } - double dR, dG, dB; - pBorderStyle->GetColor(&dR, &dG, &dB); - GrColor oColor; - oColor.arrComp[0] = DoubleToColor(dR); - oColor.arrComp[1] = DoubleToColor(dG); - oColor.arrComp[2] = DoubleToColor(dB); - m_pGState->SetStrokeColor(&oColor); - m_pOut->UpdateStrokeColor(m_pGState); - - dX = (m_arrBaseMatrix[0] + m_arrBaseMatrix[2]) * arrInvCTM[0] + (m_arrBaseMatrix[1] + m_arrBaseMatrix[3]) * arrInvCTM[2]; - dY = (m_arrBaseMatrix[0] + m_arrBaseMatrix[2]) * arrInvCTM[1] + (m_arrBaseMatrix[1] + m_arrBaseMatrix[3]) * arrInvCTM[3]; - dX = sqrt(0.5 * (dX * dX + dY * dY)); - m_pGState->SetLineWidth(dX * pBorderStyle->GetWidth()); - m_pOut->UpdateLineWidth(m_pGState); - - double *pDash; - int nDashLength; - - pBorderStyle->GetDash(&pDash, &nDashLength); - - if (pBorderStyle->GetType() == annotBorderDashed && nDashLength > 0) - { - double *pDashNew = (double *)MemUtilsMallocArray(nDashLength, sizeof(double)); - for (int nIndex = 0; nIndex < nDashLength; ++nIndex) - { - pDashNew[nIndex] = dX * pDash[nIndex]; - } - m_pGState->SetLineDash(pDashNew, nDashLength, 0); - m_pOut->UpdateLineDash(m_pGState); - } - - m_pGState->ClearPath(); - m_pGState->MoveTo(dAnnotX0, m_pOut->UpSideDown() ? dAnnotY1 : dAnnotY0); - m_pGState->LineTo(dAnnotX1, m_pOut->UpSideDown() ? dAnnotY1 : dAnnotY0); - if (pBorderStyle->GetType() != annotBorderUnderlined) - { - m_pGState->LineTo(dAnnotX1, m_pOut->UpSideDown() ? dAnnotY0 : dAnnotY1); - m_pGState->LineTo(dAnnotX0, m_pOut->UpSideDown() ? dAnnotY0 : dAnnotY1); - m_pGState->ClosePath(); - } - m_pOut->Stroke(m_pGState); - } - } - //------------------------------------------------------------------------------------------------------------------------------- - // Работаем со стеками GState и ResourcesDict - //------------------------------------------------------------------------------------------------------------------------------- - void Graphics::SaveGState() - { - m_pOut->SaveGState(m_pGState); - m_pGState = m_pGState->Save(); - } - - void Graphics::RestoreGState() - { - m_pGState = m_pGState->Restore(); - m_pOut->RestoreGState(m_pGState); - } - - void Graphics::PushResources(Dict *pResourcesDict) - { - m_pResources = new GrResources(m_pXref, pResourcesDict, m_pResources, m_pGlobalParams); - } - - void Graphics::PopResources() - { - if (m_pResources) - { - GrResources *pResourcesNext = m_pResources->GetNext(); - delete m_pResources; - m_pResources = pResourcesNext; - } - else - m_pResources = NULL; - } -} diff --git a/PdfReader/old/Graphics.h b/PdfReader/old/Graphics.h deleted file mode 100644 index 28001a9b7f..0000000000 --- a/PdfReader/old/Graphics.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_GRAPHICS_H -#define _PDF_READER_GRAPHICS_H - -#include "GlobalParams.h" - -namespace PdfReader -{ - class StringExt; - class XRef; - class Array; - class Stream; - class Parser; - class Dict; - class Function; - class OutputDev; - class GrFontDict; - class GrFont; - class GrPattern; - class GrTilingPattern; - class GrShadingPattern; - class GrShading; - class GrFunctionShading; - class GrAxialShading; - class GrRadialShading; - class GrGouraudTriangleShading; - class GrPatchMeshShading; - struct GrPatch; - class GrState; - struct GrColor; - class GrColorSpace; - class Graphics; - class PDFRectangle; - class AnnotBorderStyle; - - //------------------------------------------------------------------------------------------------------------------------------- - - enum GrClipType - { - clipNone, - clipNormal, - clipEO - }; - - enum ArgType - { - argBool, // Boolean - argInt, // Integer - argNum, // Number (integer or real) - argString, // String - argName, // Name - argArray, // Array - argProps, // Properties (Dictionary или Name) - argSCN, // scn/SCN - argNone // используется, чтобы избежать пустых полей при инициализации - }; - -#define maxArgs 33 - - struct Operator - { - char sName[4]; - int nArgumentsCount; - ArgType arrArguments[maxArgs]; - void (Graphics::*pFunction)(Object pArgs[], int nArgsCount); - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // GrResources - //------------------------------------------------------------------------------------------------------------------------------- - - class GrResources - { - public: - - GrResources(XRef *pXref, Dict *pResourcesDict, GrResources *pNext, GlobalParams *pGlobalParams); - ~GrResources(); - - GrFont *LookupFont(char *sName); - bool LookupXObject(char *sName, Object *pObject); - bool LookupAndCopyXObject(char *sName, Object *pObject); - void LookupColorSpace(char *sName, Object *pObject); - GrPattern *LookupPattern(char *sName); - GrShading *LookupShading(char *sName); - bool LookupExtGState(char *sName, Object *pObject); - - GrResources *GetNext() - { - return m_pNext; - } - - private: - - GrFontDict *m_pFonts; - Object m_oXObjectDict; - Object m_oColorSpaceDict; - Object m_oPatternDict; - Object m_oShadingDict; - Object m_oExtGStateDict; - GrResources *m_pNext; - - GlobalParams *m_pGlobalParams; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Graphics - //------------------------------------------------------------------------------------------------------------------------------- - - class Graphics - { - public: - - Graphics(GlobalParams *pGlobalParams, XRef *pXref, OutputDev *pOut, int nPageNumber, Dict *pResourcesDict, double dHorDPI, double dVerDPI, PDFRectangle *pBox, PDFRectangle *pCropBox, int nRotate, bool(*pAbortCheckCallBack)(void *pData) = NULL, void *pAbortCheckData = NULL); - - Graphics(GlobalParams *pGlobalParams, XRef *pXref, OutputDev *pOut, Dict *pResourcesDict, PDFRectangle *pBox, PDFRectangle *pCropBox, bool(*pAbortCheckCallBack)(void *pData) = NULL, void *pAbortCheckData = NULL); - - ~Graphics(); - - // Инициализируем Парсер по pObject, предварительно проводим проверку: Является ли pObject потоком или массивом потоков. - void Display(Object *pObject, bool bTopLevel = true); - - // Рисуем annotation - void DrawAnnotation(Object *pStream, AnnotBorderStyle *pBorderStyle, double dMinX, double dMinY, double dMaxX, double dMaxY); - - // Сохраняем GState. - void SaveGState(); - - // Восстанавливаем предыдущий GState. - void RestoreGState(); - - // Считываем текущий GState. - GrState *GetGState() - { - return m_pGState; - } - - private: - - void StartParse(bool bTopLevel); - void ExecuteOperator(Object *pCommand, Object arrArguments[], int nArgumentsCount); - Operator *FindOperator(char *sName); - bool CheckArgumentType(Object *pArgument, ArgType eType); - int GetPos(); - - // Graphics state - void OperatorSave(Object arrArguments[], int nArgumentsCount); - void OperatorRestore(Object arrArguments[], int nArgumentsCount); - void OperatorConcat(Object arrArguments[], int nArgumentsCount); - void OperatorSetDash(Object arrArguments[], int nArgumentsCount); - void OperatorSetFlat(Object arrArguments[], int nArgumentsCount); - void OperatorSetLineJoin(Object arrArguments[], int nArgumentsCount); - void OperatorSetLineCap(Object arrArguments[], int nArgumentsCount); - void OperatorSetMiterLimit(Object arrArguments[], int nArgumentsCount); - void OperatorSetLineWidth(Object arrArguments[], int nArgumentsCount); - void OperatorSetRenderingIntent(Object arrArguments[], int nArgumentsCount); - void OperatorSetExtGState(Object arrArguments[], int nArgumentsCount); - void MakeSoftMask(Object *pStream, bool bAlpha, GrColorSpace *pBlendingColorSpace, bool bIsolated, bool bKnockout, Function *pTransferFunc, GrColor *pBackdropColor); - - // Colour spaces - void OperatorSetFillGray(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeGray(Object arrArguments[], int nArgumentsCount); - void OperatorSetFillCMYKColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeCMYKColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetFillRGBColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeRGBColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetFillColorSpace(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeColorSpace(Object arrArguments[], int nArgumentsCount); - void OperatorSetFillColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeColor(Object arrArguments[], int nArgumentsCount); - void OperatorSetFillColorN(Object arrArguments[], int nArgumentsCount); - void OperatorSetStrokeColorN(Object arrArguments[], int nArgumentsCount); - - // Path construction - void OperatorMoveTo(Object arrArguments[], int nArgumentsCount); - void OperatorLineTo(Object arrArguments[], int nArgumentsCount); - void OperatorCurveTo(Object arrArguments[], int nArgumentsCount); - void OperatorCurveTo1(Object arrArguments[], int nArgumentsCount); - void OperatorCurveTo2(Object arrArguments[], int nArgumentsCount); - void OperatorRectangle(Object arrArguments[], int nArgumentsCount); - void OperatorClosePath(Object arrArguments[], int nArgumentsCount); - - // Path-painting - void OperatorEndPath(Object arrArguments[], int nArgumentsCount); - void OperatorStroke(Object arrArguments[], int nArgumentsCount); - void OperatorCloseStroke(Object arrArguments[], int nArgumentsCount); - void OperatorFill(Object arrArguments[], int nArgumentsCount); - void OperatorEOFill(Object arrArguments[], int nArgumentsCount); - void OperatorFillStroke(Object arrArguments[], int nArgumentsCount); - void OperatorCloseFillStroke(Object arrArguments[], int nArgumentsCount); - void OperatorEOFillStroke(Object arrArguments[], int nArgumentsCount); - void OperatorCloseEOFillStroke(Object arrArguments[], int nArgumentsCount); - void OperatorShadingFill(Object arrArguments[], int nArgumentsCount); - void DoPatternFill(bool bEOFill); - void DoPatternStroke(); - void DoTilingPatternFill(GrTilingPattern *pPattern, bool bStroke, bool bEOFill); - void DoShadingPatternFill(GrShadingPattern *pPattern, bool bStroke, bool bEOFill); - void DoFunctionShadingFill(GrFunctionShading *pShading); - void DoFunctionShadingFill(GrFunctionShading *pShading, double dMinX, double dMinY, double dMaxX, double dMaxY, GrColor *pColors, int nDepth); - void DoAxialShadingFill(GrAxialShading *pShading); - void DoRadialShadingFill(GrRadialShading *pShading); - void DoGouraudTriangleShadingFill(GrGouraudTriangleShading *pShading); - void GouraudFillTriangle(double dAx, double dAy, GrColor *pColorA, double dBx, double dBy, GrColor *pColorB, double dCx, double dCy, GrColor *pColorC, int nComponentsCount, int nDepth); - void DoPatchMeshShadingFill(GrPatchMeshShading *pShading); - void MeshFillPatch(GrPatch *pPatch, int nComponentsCount, int nDepth); - void DoEndPath(); - - // Clipping paths - void OperatorClip(Object arrArguments[], int nArgumentsCount); - void OperatorEOClip(Object arrArguments[], int nArgumentsCount); - - // Text objects - void OperatorBeginText(Object arrArguments[], int nArgumentsCount); - void OperatorEndText(Object arrArguments[], int nArgumentsCount); - - // Text state - void OperatorSetCharSpacing(Object arrArguments[], int nArgumentsCount); - void OperatorSetFont(Object arrArguments[], int nArgumentsCount); - void OperatorSetTextLeading(Object arrArguments[], int nArgumentsCount); - void OperatorSetTextRender(Object arrArguments[], int nArgumentsCount); - void OperatorSetTextRise(Object arrArguments[], int nArgumentsCount); - void OperatorSetWordSpacing(Object arrArguments[], int nArgumentsCount); - void OperatorSetHorizScaling(Object arrArguments[], int nArgumentsCount); - - // Text positioning - void OperatorTextMove(Object arrArguments[], int nArgumentsCount); - void OperatorTextMoveSet(Object arrArguments[], int nArgumentsCount); - void OperatorSetTextMatrix(Object arrArguments[], int nArgumentsCount); - void OperatorTextNextLine(Object arrArguments[], int nArgumentsCount); - - // Text showing - void OperatorShowText(Object arrArguments[], int nArgumentsCount); - void OperatorMoveShowText(Object arrArguments[], int nArgumentsCount); - void OperatorMoveSetShowText(Object arrArguments[], int nArgumentsCount); - void OperatorShowSpaceText(Object arrArguments[], int nArgumentsCount); - void DoShowText(StringExt *seString); - - // XObjects - void OperatorXObject(Object arrArguments[], int nArgumentsCount); - void DoImage(Object *pRef, Stream *pStream, bool bInlineImage); - void DoForm(Object *pStream); - void DoForm(Object *pStream, Dict *pResourcesDict, double *pMatrix, double *pBBox, bool bTranspGroup = false, bool bSoftMask = false, GrColorSpace *pBlendingColorSpace = NULL, bool bIsolated = false, bool bKnockout = false, bool bAlpha = false, Function *pTransferFunctions = NULL, GrColor *pBackdropColor = NULL); - - // Inline images - void OperatorBeginImage(Object arrArguments[], int nArgumentsCount); - void OperatorImageData(Object arrArguments[], int nArgumentsCount); - void OperatorEndImage(Object arrArguments[], int nArgumentsCount); - Stream *BuildImageStream(); - - // Type 3 fonts - void OperatorSetCharWidth(Object arrArguments[], int nArgumentsCount); - void OperatorSetCacheDevice(Object arrArguments[], int nArgumentsCount); - - // Compatibility - void OperatorBeginIgnoreUndef(Object arrArguments[], int nArgumentsCount); - void OperatorEndIgnoreUndef(Object arrArguments[], int nArgumentsCount); - - // Marked content - void OperatorBeginMarkedContent(Object arrArguments[], int nArgumentsCount); - void OperatorEndMarkedContent(Object arrArguments[], int nArgumentsCount); - void OperatorMarkPoint(Object arrArguments[], int nArgumentsCount); - - void PushResources(Dict *pResourcesDict); - void PopResources(); - - private: - - XRef *m_pXref; // Таблица Xref для данного PDF - документа - OutputDev *m_pOut; // Output device - bool m_bSubPage; // Sub-page object? - GrResources *m_pResources; // Resources - int m_nUpdateLevel; - - GrState *m_pGState; // Текущий GState - bool m_bFontChanged; // True, если шрифт или текстовая матрица изменились - GrClipType m_eClip; // Clip type - int m_nIgnoreUndef; // Текущий уровень вложенности для BX/EX - double m_arrBaseMatrix[6]; // Стандартная матрица для последних объектов Page/Form/Pattern - int m_nFormDepth; - - Parser *m_pParser; // Парсер для содержимого страницы - - bool(*m_pAbortCheckCallBack)(void *pData); // Проверка на отмену - void *m_pAbortCheckData; - - static Operator OperatorsTable[]; // Таблица графических операторов - -#ifdef _DEBUG - FILE *m_pDumpFile; // Файл для распечатки команд, записанных в PDF -#endif - - GlobalParams *m_pGlobalParams; - }; -} -#endif // _PDF_READER_GRAPHICS_H diff --git a/PdfReader/old/Hash.cpp b/PdfReader/old/Hash.cpp deleted file mode 100644 index 4e841b8be3..0000000000 --- a/PdfReader/old/Hash.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "MemoryUtils.h" -#include "StringExt.h" -#include "Hash.h" - -namespace PdfReader -{ - struct THashBucket - { - StringExt *seKey; - union - { - void *p; - int i; - } uValue; - THashBucket *pNext; - }; - - struct THashIter - { - int nHashIndex; - THashBucket *pBucket; - }; - - //------------------------------------------------------------------------ - - CHash::CHash(bool bDeleteKeys) - { - m_bDeleteKeys = bDeleteKeys; - m_nBucketsCount = 7; - m_ppTable = (THashBucket **)MemUtilsMallocArray(m_nBucketsCount, sizeof(THashBucket *)); - for (int nHashIndex = 0; nHashIndex < m_nBucketsCount; ++nHashIndex) - m_ppTable[nHashIndex] = NULL; - m_nLength = 0; - } - - CHash::~CHash() - { - THashBucket *pBucket = NULL; - - for (int nHashIndex = 0; nHashIndex < m_nBucketsCount; ++nHashIndex) - { - while (m_ppTable[nHashIndex]) - { - pBucket = m_ppTable[nHashIndex]; - m_ppTable[nHashIndex] = pBucket->pNext; - if (m_bDeleteKeys) - { - delete pBucket->seKey; - } - delete pBucket; - } - } - MemUtilsFree(m_ppTable); - } - - void CHash::Add(StringExt *seKey, void *pValue) - { - if (m_nLength >= m_nBucketsCount) - Expand(); - - THashBucket *pBucket = new THashBucket; - pBucket->seKey = seKey; - pBucket->uValue.p = pValue; - int nHashIndex = Hash(seKey); - pBucket->pNext = m_ppTable[nHashIndex]; - m_ppTable[nHashIndex] = pBucket; - ++m_nLength; - } - - void CHash::Add(StringExt *seKey, int nValue) - { - if (m_nLength >= m_nBucketsCount) - Expand(); - - THashBucket *pBucket = new THashBucket; - pBucket->seKey = seKey; - pBucket->uValue.i = nValue; - int nHashIndex = Hash(seKey); - pBucket->pNext = m_ppTable[nHashIndex]; - m_ppTable[nHashIndex] = pBucket; - ++m_nLength; - } - - void CHash::Replace(StringExt *seKey, void *pValue) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if ((pBucket = Find(seKey, &nHashIndex))) - { - pBucket->uValue.p = pValue; - delete seKey; - } - else - Add(seKey, pValue); - } - - void CHash::Replace(StringExt *seKey, int nValue) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if ((pBucket = Find(seKey, &nHashIndex))) - { - pBucket->uValue.i = nValue; - delete seKey; - } - else - Add(seKey, nValue); - } - - void *CHash::Lookup(StringExt *seKey) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if (!(pBucket = Find(seKey, &nHashIndex))) - return NULL; - return pBucket->uValue.p; - } - - int CHash::LookupInt(StringExt *seKey) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if (!(pBucket = Find(seKey, &nHashIndex))) - return 0; - - return pBucket->uValue.i; - } - - void *CHash::Lookup(char *sKey) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if (!(pBucket = Find(sKey, &nHashIndex))) - return NULL; - return pBucket->uValue.p; - } - - int CHash::LookupInt(char *sKey) - { - THashBucket *pBucket = NULL; - int nHashIndex = 0; - - if (!(pBucket = Find(sKey, &nHashIndex))) - return 0; - - return pBucket->uValue.i; - } - - void *CHash::Remove(StringExt *seKey) - { - THashBucket *pBucket; - THashBucket **ppBucket; - int nHashIndex = 0; - - if (!(pBucket = Find(seKey, &nHashIndex))) - return NULL; - - ppBucket = &m_ppTable[nHashIndex]; - while (*ppBucket != pBucket) - ppBucket = &((*ppBucket)->pNext); - - *ppBucket = pBucket->pNext; - if (m_bDeleteKeys) - delete pBucket->seKey; - void *pValue = pBucket->uValue.p; - delete pBucket; - --m_nLength; - return pValue; - } - - int CHash::RemoveInt(StringExt *seKey) - { - THashBucket *pBucket; - THashBucket **ppBucket; - int nHashIndex = 0; - - if (!(pBucket = Find(seKey, &nHashIndex))) - return 0; - - ppBucket = &m_ppTable[nHashIndex]; - while (*ppBucket != pBucket) - ppBucket = &((*ppBucket)->pNext); - - *ppBucket = pBucket->pNext; - if (m_bDeleteKeys) - delete pBucket->seKey; - - int nValue = pBucket->uValue.i; - delete pBucket; - --m_nLength; - return nValue; - } - - void *CHash::Remove(char *sKey) - { - THashBucket *pBucket; - THashBucket **ppBucket; - int nHashIndex = 0; - - if (!(pBucket = Find(sKey, &nHashIndex))) - return NULL; - ppBucket = &m_ppTable[nHashIndex]; - while (*ppBucket != pBucket) - ppBucket = &((*ppBucket)->pNext); - - *ppBucket = pBucket->pNext; - - if (m_bDeleteKeys) - delete pBucket->pNext; - - void *pValue = pBucket->uValue.p; - delete pBucket; - --m_nLength; - return pValue; - } - - int CHash::RemoveInt(char *sKey) - { - THashBucket *pBucket; - THashBucket **ppBucket; - int nHashIndex = 0; - - if (!(pBucket = Find(sKey, &nHashIndex))) - return 0; - - ppBucket = &m_ppTable[nHashIndex]; - while (*ppBucket != pBucket) - ppBucket = &((*ppBucket)->pNext); - - *ppBucket = pBucket->pNext; - if (m_bDeleteKeys) - delete pBucket->seKey; - - int nValue = pBucket->uValue.i; - delete pBucket; - --m_nLength; - return nValue; - } - - void CHash::StartIter(THashIter **ppIter) - { - *ppIter = new THashIter; - (*ppIter)->nHashIndex = -1; - (*ppIter)->pBucket = NULL; - } - - bool CHash::GetNext(THashIter **ppIter, StringExt **pseKey, void **ppValue) - { - if (!*ppIter) - return false; - - if ((*ppIter)->pBucket) - (*ppIter)->pBucket = (*ppIter)->pBucket->pNext; - - while (!(*ppIter)->pBucket) - { - if (++(*ppIter)->nHashIndex == m_nBucketsCount) - { - delete *ppIter; - *ppIter = NULL; - return false; - } - (*ppIter)->pBucket = m_ppTable[(*ppIter)->nHashIndex]; - } - *pseKey = (*ppIter)->pBucket->seKey; - *ppValue = (*ppIter)->pBucket->uValue.p; - return true; - } - - bool CHash::GetNext(THashIter **ppIter, StringExt **pseKey, int *pnValue) - { - if (!*ppIter) - return false; - - if ((*ppIter)->pBucket) - (*ppIter)->pBucket = (*ppIter)->pBucket->pNext; - - while (!(*ppIter)->pBucket) - { - if (++(*ppIter)->nHashIndex == m_nBucketsCount) - { - delete *ppIter; - *ppIter = NULL; - return false; - } - (*ppIter)->pBucket = m_ppTable[(*ppIter)->nHashIndex]; - } - *pseKey = (*ppIter)->pBucket->seKey; - *pnValue = (*ppIter)->pBucket->uValue.i; - return true; - } - - void CHash::DeleteIter(THashIter **ppIter) - { - delete *ppIter; - *ppIter = NULL; - } - - void CHash::Expand() - { - int nHashIndex = 0; - - int nOldSize = m_nBucketsCount; - THashBucket **ppOldTab = m_ppTable; - m_nBucketsCount = 2 * m_nBucketsCount + 1; - m_ppTable = (THashBucket **)MemUtilsMallocArray(m_nBucketsCount, sizeof(THashBucket *)); - for (nHashIndex = 0; nHashIndex < m_nBucketsCount; ++nHashIndex) - m_ppTable[nHashIndex] = NULL; - - for (int nIndex = 0; nIndex < nOldSize; ++nIndex) - { - while (ppOldTab[nIndex]) - { - THashBucket *pBucket = ppOldTab[nIndex]; - ppOldTab[nIndex] = ppOldTab[nIndex]->pNext; - nHashIndex = Hash(pBucket->seKey); - pBucket->pNext = m_ppTable[nHashIndex]; - m_ppTable[nHashIndex] = pBucket; - } - } - MemUtilsFree(ppOldTab); - } - - THashBucket *CHash::Find(StringExt *seKey, int *pnHashIndex) - { - THashBucket *pBucket; - - *pnHashIndex = Hash(seKey); - for (pBucket = m_ppTable[*pnHashIndex]; pBucket; pBucket = pBucket->pNext) - { - if (!pBucket->seKey->Compare(seKey)) - return pBucket; - } - return NULL; - } - THashBucket *CHash::Find(char *sKey, int *pnHashIndex) - { - THashBucket *pBucket; - - *pnHashIndex = Hash(sKey); - for (pBucket = m_ppTable[*pnHashIndex]; pBucket; pBucket = pBucket->pNext) - { - if (!pBucket->seKey->Compare(sKey)) - return pBucket; - } - return NULL; - } - - int CHash::Hash(StringExt *seKey) - { - char *sTemp; - unsigned int nHash = 0; - int nIndex; - - for (sTemp = seKey->GetBuffer(), nIndex = 0; nIndex < seKey->GetLength(); ++sTemp, ++nIndex) - nHash = 17 * nHash + (int)(*sTemp & 0xff); - - return (int)(nHash % m_nBucketsCount); - } - - int CHash::Hash(char *sKey) - { - char *sTemp; - unsigned int nHash = 0; - - for (sTemp = sKey; *sTemp; ++sTemp) - nHash = 17 * nHash + (int)(*sTemp & 0xff); - - return (int)(nHash % m_nBucketsCount); - } -} \ No newline at end of file diff --git a/PdfReader/old/Hash.h b/PdfReader/old/Hash.h deleted file mode 100644 index 73e1c445ea..0000000000 --- a/PdfReader/old/Hash.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_HASH_H -#define _PDF_READER_HASH_H - -namespace PdfReader -{ - class StringExt; - struct THashBucket; - struct THashIter; - - //------------------------------------------------------------------------ - // CHash - //------------------------------------------------------------------------ - - class CHash - { - - public: - - CHash(bool bDeleteKeys = false); - ~CHash(); - - void Add(StringExt *seKey, void *pValue); - void Add(StringExt *seKey, int nValue); - - void Replace(StringExt *seKey, void *pValue); - void Replace(StringExt *seKey, int nValue); - - void *Lookup(StringExt *seKey); - void *Lookup(char *sKey); - int LookupInt(StringExt *seKey); - int LookupInt(char *sKey); - - void *Remove(StringExt *seKey); - void *Remove(char *seKey); - int RemoveInt(StringExt *seKey); - int RemoveInt(char *sKey); - - int GetLength() - { - return m_nLength; - } - - void StartIter(THashIter **ppIter); - - bool GetNext(THashIter **ppIter, StringExt **pseKey, void **ppValue); - bool GetNext(THashIter **ppIter, StringExt **pseKey, int *pnValue); - - void DeleteIter(THashIter **ppIter); - - private: - - void Expand(); - THashBucket *Find(StringExt *seKey, int *pnHashIndex); - THashBucket *Find(char *sKey, int *pnHashIndex); - - int Hash(StringExt *seKey); - int Hash(char *sKey); - - private: - - bool m_bDeleteKeys; // Будем ли удалять имена? set if key strings should be deleted - int m_nBucketsCount; // Количество наборов - int m_nLength; // Количество вхождений - THashBucket **m_ppTable; - }; - -#define DeleteCHash(hash, T) \ - do \ - { \ - CHash *_hash = (hash); \ - { \ - THashIter *_iter; \ - StringExt *_key; \ - void *_p; \ - _hash->StartIter(&_iter); \ - while (_hash->GetNext(&_iter, &_key, &_p)) \ - { \ - delete (T*)_p; \ - } \ - delete _hash; \ - } \ - } while(0); - -} - -#endif // _PDF_READER_HASH_H diff --git a/PdfReader/old/JArithmeticDecoder.cpp b/PdfReader/old/JArithmeticDecoder.cpp deleted file mode 100644 index fec97f4249..0000000000 --- a/PdfReader/old/JArithmeticDecoder.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "Object.h" -#include "Stream.h" -#include "JArithmeticDecoder.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // JArithmeticDecoderStates - //------------------------------------------------------------------------------------------------------------------------------- - - JArithmeticDecoderStats::JArithmeticDecoderStats(int nContextSize) - { - m_nContextSize = nContextSize; - m_pContextTable = (unsigned char *)MemUtilsMallocArray(m_nContextSize, sizeof(unsigned char)); - Reset(); - } - - JArithmeticDecoderStats::~JArithmeticDecoderStats() - { - MemUtilsFree(m_pContextTable); - } - - JArithmeticDecoderStats *JArithmeticDecoderStats::Copy() - { - JArithmeticDecoderStats *pStats = new JArithmeticDecoderStats(m_nContextSize); - memcpy(pStats->m_pContextTable, m_pContextTable, m_nContextSize); - return pStats; - } - - void JArithmeticDecoderStats::Reset() - { - memset(m_pContextTable, 0, m_nContextSize); - } - - void JArithmeticDecoderStats::CopyFrom(JArithmeticDecoderStats *pStats) - { - memcpy(m_pContextTable, pStats->m_pContextTable, m_nContextSize); - } - - void JArithmeticDecoderStats::SetEntry(unsigned int unCx, int nIndex, int nMPS) - { - m_pContextTable[unCx] = (nIndex << 1) + nMPS; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // JArithmeticDecoder - //------------------------------------------------------------------------------------------------------------------------------- - - unsigned int JArithmeticDecoder::arrunQeTable[47] = - { - 0x56010000, 0x34010000, 0x18010000, 0x0AC10000, - 0x05210000, 0x02210000, 0x56010000, 0x54010000, - 0x48010000, 0x38010000, 0x30010000, 0x24010000, - 0x1C010000, 0x16010000, 0x56010000, 0x54010000, - 0x51010000, 0x48010000, 0x38010000, 0x34010000, - 0x30010000, 0x28010000, 0x24010000, 0x22010000, - 0x1C010000, 0x18010000, 0x16010000, 0x14010000, - 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000, - 0x08A10000, 0x05210000, 0x04410000, 0x02A10000, - 0x02210000, 0x01410000, 0x01110000, 0x00850000, - 0x00490000, 0x00250000, 0x00150000, 0x00090000, - 0x00050000, 0x00010000, 0x56010000 - }; - - int JArithmeticDecoder::arrnNMPSTable[47] = - { - 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46 - }; - - int JArithmeticDecoder::arrnNLPSTable[47] = - { - 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14, - 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46 - }; - - int JArithmeticDecoder::arrnSwitchTable[47] = - { - 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - JArithmeticDecoder::JArithmeticDecoder() - { - m_pStream = NULL; - m_nDataSize = 0; - m_bLimitStream = false; - } - - inline unsigned int JArithmeticDecoder::ReadByte() - { - if (m_bLimitStream) - { - --m_nDataSize; - if (m_nDataSize < 0) - { - return 0xff; - } - } - return (unsigned int)m_pStream->GetChar() & 0xff; - } - - JArithmeticDecoder::~JArithmeticDecoder() - { - Cleanup(); - } - - void JArithmeticDecoder::Start() - { - m_unBuffer0 = ReadByte(); - m_unBuffer1 = ReadByte(); - - // INITDEC - m_unC = (m_unBuffer0 ^ 0xff) << 16; - ByteIn(); - m_unC <<= 7; - m_nCT -= 7; - m_unA = 0x80000000; - } - - void JArithmeticDecoder::Restart(int nDatasize) - { - int nOldDataSize = m_nDataSize; - m_nDataSize = nDatasize; - if (nOldDataSize == -1) - { - m_unBuffer1 = ReadByte(); - } - else if (nOldDataSize <= -2) - { - m_unBuffer0 = ReadByte(); - m_unBuffer1 = ReadByte(); - } - } - - void JArithmeticDecoder::Cleanup() - { - if (m_bLimitStream) - { - while (m_nDataSize > 0) - { - m_unBuffer0 = m_unBuffer1; - m_unBuffer1 = ReadByte(); - } - } - } - - int JArithmeticDecoder::DecodeBit(unsigned int unContext, JArithmeticDecoderStats *pStats) - { - int nBit = 0; - - int nICX = pStats->m_pContextTable[unContext] >> 1; - int nMPSCX = pStats->m_pContextTable[unContext] & 1; - unsigned int unQe = arrunQeTable[nICX]; - m_unA -= unQe; - if (m_unC < m_unA) - { - if (m_unA & 0x80000000) - { - nBit = nMPSCX; - } - else - { - // MPS_EXCHANGE - if (m_unA < unQe) - { - nBit = 1 - nMPSCX; - if (arrnSwitchTable[nICX]) - { - pStats->m_pContextTable[unContext] = (arrnNLPSTable[nICX] << 1) | (1 - nMPSCX); - } - else - { - pStats->m_pContextTable[unContext] = (arrnNLPSTable[nICX] << 1) | nMPSCX; - } - } - else - { - nBit = nMPSCX; - pStats->m_pContextTable[unContext] = (arrnNMPSTable[nICX] << 1) | nMPSCX; - } - // RENORMD - do - { - if (m_nCT == 0) - { - ByteIn(); - } - m_unA <<= 1; - m_unC <<= 1; - --m_nCT; - } while (!(m_unA & 0x80000000)); - } - } - else - { - m_unC -= m_unA; - // LPS_EXCHANGE - if (m_unA < unQe) - { - nBit = nMPSCX; - pStats->m_pContextTable[unContext] = (arrnNMPSTable[nICX] << 1) | nMPSCX; - } - else - { - nBit = 1 - nMPSCX; - if (arrnSwitchTable[nICX]) - { - pStats->m_pContextTable[unContext] = (arrnNLPSTable[nICX] << 1) | (1 - nMPSCX); - } - else - { - pStats->m_pContextTable[unContext] = (arrnNLPSTable[nICX] << 1) | nMPSCX; - } - } - m_unA = unQe; - // RENORMD - do - { - if (m_nCT == 0) - { - ByteIn(); - } - m_unA <<= 1; - m_unC <<= 1; - --m_nCT; - } while (!(m_unA & 0x80000000)); - } - return nBit; - } - - int JArithmeticDecoder::DecodeByte(unsigned int unContext, JArithmeticDecoderStats *pStats) - { - int nByte = 0; - for (int nIndex = 0; nIndex < 8; ++nIndex) - { - nByte = (nByte << 1) | DecodeBit(unContext, pStats); - } - return nByte; - } - - bool JArithmeticDecoder::DecodeInt(int *pnValue, JArithmeticDecoderStats *pStats) - { - unsigned int unVal = 0; - m_unPrev = 1; - int nSign = DecodeIntBit(pStats); - if (DecodeIntBit(pStats)) - { - if (DecodeIntBit(pStats)) - { - if (DecodeIntBit(pStats)) - { - if (DecodeIntBit(pStats)) - { - if (DecodeIntBit(pStats)) - { - unVal = 0; - for (int nIndex = 0; nIndex < 32; ++nIndex) - { - unVal = (unVal << 1) | DecodeIntBit(pStats); - } - unVal += 4436; - } - else - { - unVal = 0; - for (int nIndex = 0; nIndex < 12; ++nIndex) - { - unVal = (unVal << 1) | DecodeIntBit(pStats); - } - unVal += 340; - } - } - else - { - unVal = 0; - for (int nIndex = 0; nIndex < 8; ++nIndex) - { - unVal = (unVal << 1) | DecodeIntBit(pStats); - } - unVal += 84; - } - } - else - { - unVal = 0; - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - unVal = (unVal << 1) | DecodeIntBit(pStats); - } - unVal += 20; - } - } - else - { - unVal = DecodeIntBit(pStats); - unVal = (unVal << 1) | DecodeIntBit(pStats); - unVal = (unVal << 1) | DecodeIntBit(pStats); - unVal = (unVal << 1) | DecodeIntBit(pStats); - unVal += 4; - } - } - else - { - unVal = DecodeIntBit(pStats); - unVal = (unVal << 1) | DecodeIntBit(pStats); - } - - if (nSign) - { - if (unVal == 0) - { - return false; - } - *pnValue = -(int)unVal; - } - else - { - *pnValue = (int)unVal; - } - return true; - } - - int JArithmeticDecoder::DecodeIntBit(JArithmeticDecoderStats *pStats) - { - int nBit = DecodeBit(m_unPrev, pStats); - if (m_unPrev < 0x100) - { - m_unPrev = (m_unPrev << 1) | nBit; - } - else - { - m_unPrev = (((m_unPrev << 1) | nBit) & 0x1ff) | 0x100; - } - return nBit; - } - - unsigned int JArithmeticDecoder::DecodeIAID(unsigned int unCodeLen, JArithmeticDecoderStats *pStats) - { - m_unPrev = 1; - for (unsigned int unIndex = 0; unIndex < unCodeLen; ++unIndex) - { - int nBit = DecodeBit(m_unPrev, pStats); - m_unPrev = (m_unPrev << 1) | nBit; - } - return m_unPrev - (1 << unCodeLen); - } - - void JArithmeticDecoder::ByteIn() - { - if (m_unBuffer0 == 0xff) - { - if (m_unBuffer1 > 0x8f) - { - m_nCT = 8; - } - else - { - m_unBuffer0 = m_unBuffer1; - m_unBuffer1 = ReadByte(); - m_unC = m_unC + 0xfe00 - (m_unBuffer0 << 9); - m_nCT = 7; - } - } - else - { - m_unBuffer0 = m_unBuffer1; - m_unBuffer1 = ReadByte(); - m_unC = m_unC + 0xff00 - (m_unBuffer0 << 8); - m_nCT = 8; - } - } -} \ No newline at end of file diff --git a/PdfReader/old/JArithmeticDecoder.h b/PdfReader/old/JArithmeticDecoder.h deleted file mode 100644 index 9187dab4ba..0000000000 --- a/PdfReader/old/JArithmeticDecoder.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_JARITHMETICDECODER_H -#define _PDF_READER_JARITHMETICDECODER_H - -namespace PdfReader -{ - class Stream; - - //------------------------------------------------------------------------------------------------------------------------------- - // JArithmeticDecoderStats - //------------------------------------------------------------------------------------------------------------------------------- - - class JArithmeticDecoderStats - { - public: - - JArithmeticDecoderStats(int nContextSize); - ~JArithmeticDecoderStats(); - JArithmeticDecoderStats *Copy(); - void Reset(); - int GetContextSize() - { - return m_nContextSize; - } - void CopyFrom(JArithmeticDecoderStats *pStats); - void SetEntry(unsigned int unCx, int nIndex, int nMPS); - - private: - - unsigned char *m_pContextTable; // cxTab[cx] = (i[cx] << 1) + mps[cx] - int m_nContextSize; - - friend class JArithmeticDecoder; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // JArithmeticDecoder - //------------------------------------------------------------------------------------------------------------------------------- - - class JArithmeticDecoder - { - public: - - JArithmeticDecoder(); - ~JArithmeticDecoder(); - - void SetStream(Stream *pStream) - { - m_pStream = pStream; - m_nDataSize = 0; - m_bLimitStream = false; - } - void SetStream(Stream *pStream, int nDataSize) - { - m_pStream = pStream; - m_nDataSize = nDataSize; - m_bLimitStream = true; - } - - // Начинаем декодировать новый поток. Заполняем буффер и запускаем INITDEC. - void Start(); - - // Заново декодируем прервынный поток. Заново заполняем буффер, но не запускаем INITDEC. (Используется в потоках JPEG 2000, где - // данные могут быть разделены на блоки.) - void Restart(int nDataSize); - - // Читаем оставшиеся данные в потоке. - void Cleanup(); - - // Декодируем один бит. - int DecodeBit(unsigned int unContext, JArithmeticDecoderStats *pStats); - - // Декодируем один байт. - int DecodeByte(unsigned int unContext, JArithmeticDecoderStats *pStats); - - bool DecodeInt(int *pnValue, JArithmeticDecoderStats *pStats); - - unsigned int DecodeIAID(unsigned int unCodeLen, JArithmeticDecoderStats *pStats); - - private: - - unsigned int ReadByte(); - int DecodeIntBit(JArithmeticDecoderStats *pStats); - void ByteIn(); - - private: - - static unsigned int arrunQeTable[47]; - static int arrnNMPSTable[47]; - static int arrnNLPSTable[47]; - static int arrnSwitchTable[47]; - - unsigned int m_unBuffer0; - unsigned int m_unBuffer1; - unsigned int m_unC; - unsigned int m_unA; - int m_nCT; - - unsigned int m_unPrev; - - Stream *m_pStream; - int m_nDataSize; - bool m_bLimitStream; - }; -} - -#endif // _PDF_READER_JARITHMETICDECODER_H diff --git a/PdfReader/old/JBIG2Stream.cpp b/PdfReader/old/JBIG2Stream.cpp deleted file mode 100644 index 3331bfed99..0000000000 --- a/PdfReader/old/JBIG2Stream.cpp +++ /dev/null @@ -1,3974 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "List.h" -#include "JArithmeticDecoder.h" -#include "JBIG2Stream.h" - -//~ share these tables -#include "CCITT-Tables.h" - -namespace PdfReader -{ - static int c_arrContextSize[4] ={ 16, 13, 10, 10 }; - static int c_arrRefContextSize[2] ={ 13, 10 }; - - //------------------------------------------------------------------------ - // JBIG2HuffmanTable - //------------------------------------------------------------------------ - -#define jbig2HuffmanLOW 0xfffffffd -#define jbig2HuffmanOOB 0xfffffffe -#define jbig2HuffmanEOT 0xffffffff - - struct JBIG2HuffmanTable - { - int nValue; - unsigned int unPrefixLen; - unsigned int unRangeLen; // can also be LOW, OOB, or EOT - unsigned int unPrefix; - }; - - JBIG2HuffmanTable c_oHuffTableA[] = - { - { 0, 1, 4, 0x000 }, - { 16, 2, 8, 0x002 }, - { 272, 3, 16, 0x006 }, - { 65808, 3, 32, 0x007 }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableB[] = - { - { 0, 1, 0, 0x000 }, - { 1, 2, 0, 0x002 }, - { 2, 3, 0, 0x006 }, - { 3, 4, 3, 0x00e }, - { 11, 5, 6, 0x01e }, - { 75, 6, 32, 0x03e }, - { 0, 6, jbig2HuffmanOOB, 0x03f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableC[] = - { - { 0, 1, 0, 0x000 }, - { 1, 2, 0, 0x002 }, - { 2, 3, 0, 0x006 }, - { 3, 4, 3, 0x00e }, - { 11, 5, 6, 0x01e }, - { 0, 6, jbig2HuffmanOOB, 0x03e }, - { 75, 7, 32, 0x0fe }, - { -256, 8, 8, 0x0fe }, - { -257, 8, jbig2HuffmanLOW, 0x0ff }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableD[] = - { - { 1, 1, 0, 0x000 }, - { 2, 2, 0, 0x002 }, - { 3, 3, 0, 0x006 }, - { 4, 4, 3, 0x00e }, - { 12, 5, 6, 0x01e }, - { 76, 5, 32, 0x01f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableE[] = - { - { 1, 1, 0, 0x000 }, - { 2, 2, 0, 0x002 }, - { 3, 3, 0, 0x006 }, - { 4, 4, 3, 0x00e }, - { 12, 5, 6, 0x01e }, - { 76, 6, 32, 0x03e }, - { -255, 7, 8, 0x07e }, - { -256, 7, jbig2HuffmanLOW, 0x07f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableF[] = - { - { 0, 2, 7, 0x000 }, - { 128, 3, 7, 0x002 }, - { 256, 3, 8, 0x003 }, - { -1024, 4, 9, 0x008 }, - { -512, 4, 8, 0x009 }, - { -256, 4, 7, 0x00a }, - { -32, 4, 5, 0x00b }, - { 512, 4, 9, 0x00c }, - { 1024, 4, 10, 0x00d }, - { -2048, 5, 10, 0x01c }, - { -128, 5, 6, 0x01d }, - { -64, 5, 5, 0x01e }, - { -2049, 6, jbig2HuffmanLOW, 0x03e }, - { 2048, 6, 32, 0x03f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableG[] = - { - { -512, 3, 8, 0x000 }, - { 256, 3, 8, 0x001 }, - { 512, 3, 9, 0x002 }, - { 1024, 3, 10, 0x003 }, - { -1024, 4, 9, 0x008 }, - { -256, 4, 7, 0x009 }, - { -32, 4, 5, 0x00a }, - { 0, 4, 5, 0x00b }, - { 128, 4, 7, 0x00c }, - { -128, 5, 6, 0x01a }, - { -64, 5, 5, 0x01b }, - { 32, 5, 5, 0x01c }, - { 64, 5, 6, 0x01d }, - { -1025, 5, jbig2HuffmanLOW, 0x01e }, - { 2048, 5, 32, 0x01f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableH[] = - { - { 0, 2, 1, 0x000 }, - { 0, 2, jbig2HuffmanOOB, 0x001 }, - { 4, 3, 4, 0x004 }, - { -1, 4, 0, 0x00a }, - { 22, 4, 4, 0x00b }, - { 38, 4, 5, 0x00c }, - { 2, 5, 0, 0x01a }, - { 70, 5, 6, 0x01b }, - { 134, 5, 7, 0x01c }, - { 3, 6, 0, 0x03a }, - { 20, 6, 1, 0x03b }, - { 262, 6, 7, 0x03c }, - { 646, 6, 10, 0x03d }, - { -2, 7, 0, 0x07c }, - { 390, 7, 8, 0x07d }, - { -15, 8, 3, 0x0fc }, - { -5, 8, 1, 0x0fd }, - { -7, 9, 1, 0x1fc }, - { -3, 9, 0, 0x1fd }, - { -16, 9, jbig2HuffmanLOW, 0x1fe }, - { 1670, 9, 32, 0x1ff }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableI[] = - { - { 0, 2, jbig2HuffmanOOB, 0x000 }, - { -1, 3, 1, 0x002 }, - { 1, 3, 1, 0x003 }, - { 7, 3, 5, 0x004 }, - { -3, 4, 1, 0x00a }, - { 43, 4, 5, 0x00b }, - { 75, 4, 6, 0x00c }, - { 3, 5, 1, 0x01a }, - { 139, 5, 7, 0x01b }, - { 267, 5, 8, 0x01c }, - { 5, 6, 1, 0x03a }, - { 39, 6, 2, 0x03b }, - { 523, 6, 8, 0x03c }, - { 1291, 6, 11, 0x03d }, - { -5, 7, 1, 0x07c }, - { 779, 7, 9, 0x07d }, - { -31, 8, 4, 0x0fc }, - { -11, 8, 2, 0x0fd }, - { -15, 9, 2, 0x1fc }, - { -7, 9, 1, 0x1fd }, - { -32, 9, jbig2HuffmanLOW, 0x1fe }, - { 3339, 9, 32, 0x1ff }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableJ[] = - { - { -2, 2, 2, 0x000 }, - { 6, 2, 6, 0x001 }, - { 0, 2, jbig2HuffmanOOB, 0x002 }, - { -3, 5, 0, 0x018 }, - { 2, 5, 0, 0x019 }, - { 70, 5, 5, 0x01a }, - { 3, 6, 0, 0x036 }, - { 102, 6, 5, 0x037 }, - { 134, 6, 6, 0x038 }, - { 198, 6, 7, 0x039 }, - { 326, 6, 8, 0x03a }, - { 582, 6, 9, 0x03b }, - { 1094, 6, 10, 0x03c }, - { -21, 7, 4, 0x07a }, - { -4, 7, 0, 0x07b }, - { 4, 7, 0, 0x07c }, - { 2118, 7, 11, 0x07d }, - { -5, 8, 0, 0x0fc }, - { 5, 8, 0, 0x0fd }, - { -22, 8, jbig2HuffmanLOW, 0x0fe }, - { 4166, 8, 32, 0x0ff }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableK[] = - { - { 1, 1, 0, 0x000 }, - { 2, 2, 1, 0x002 }, - { 4, 4, 0, 0x00c }, - { 5, 4, 1, 0x00d }, - { 7, 5, 1, 0x01c }, - { 9, 5, 2, 0x01d }, - { 13, 6, 2, 0x03c }, - { 17, 7, 2, 0x07a }, - { 21, 7, 3, 0x07b }, - { 29, 7, 4, 0x07c }, - { 45, 7, 5, 0x07d }, - { 77, 7, 6, 0x07e }, - { 141, 7, 32, 0x07f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableL[] = - { - { 1, 1, 0, 0x000 }, - { 2, 2, 0, 0x002 }, - { 3, 3, 1, 0x006 }, - { 5, 5, 0, 0x01c }, - { 6, 5, 1, 0x01d }, - { 8, 6, 1, 0x03c }, - { 10, 7, 0, 0x07a }, - { 11, 7, 1, 0x07b }, - { 13, 7, 2, 0x07c }, - { 17, 7, 3, 0x07d }, - { 25, 7, 4, 0x07e }, - { 41, 8, 5, 0x0fe }, - { 73, 8, 32, 0x0ff }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableM[] = - { - { 1, 1, 0, 0x000 }, - { 2, 3, 0, 0x004 }, - { 7, 3, 3, 0x005 }, - { 3, 4, 0, 0x00c }, - { 5, 4, 1, 0x00d }, - { 4, 5, 0, 0x01c }, - { 15, 6, 1, 0x03a }, - { 17, 6, 2, 0x03b }, - { 21, 6, 3, 0x03c }, - { 29, 6, 4, 0x03d }, - { 45, 6, 5, 0x03e }, - { 77, 7, 6, 0x07e }, - { 141, 7, 32, 0x07f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableN[] = - { - { 0, 1, 0, 0x000 }, - { -2, 3, 0, 0x004 }, - { -1, 3, 0, 0x005 }, - { 1, 3, 0, 0x006 }, - { 2, 3, 0, 0x007 }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - JBIG2HuffmanTable c_oHuffTableO[] = - { - { 0, 1, 0, 0x000 }, - { -1, 3, 0, 0x004 }, - { 1, 3, 0, 0x005 }, - { -2, 4, 0, 0x00c }, - { 2, 4, 0, 0x00d }, - { -4, 5, 1, 0x01c }, - { 3, 5, 1, 0x01d }, - { -8, 6, 2, 0x03c }, - { 5, 6, 2, 0x03d }, - { -24, 7, 4, 0x07c }, - { 9, 7, 4, 0x07d }, - { -25, 7, jbig2HuffmanLOW, 0x07e }, - { 25, 7, 32, 0x07f }, - { 0, 0, jbig2HuffmanEOT, 0 } - }; - - //------------------------------------------------------------------------ - // JBIG2HuffmanDecoder - //------------------------------------------------------------------------ - - class JBIG2HuffmanDecoder - { - public: - - JBIG2HuffmanDecoder() - { - m_pStream = NULL; - Reset(); - } - - ~JBIG2HuffmanDecoder() - { - } - void SetStream(Stream *pStream) - { - m_pStream = pStream; - } - void Reset() - { - unBuffer = 0; - unBufferLen = 0; - } - - // Returns false for OOB, otherwise sets * and returns true. - //~ optimize this - bool DecodeInt(int *pnValue, JBIG2HuffmanTable *pTable) - { - unsigned int unIndex = 0, unPrefix = 0, unLen = 0; - while (pTable[unIndex].unRangeLen != jbig2HuffmanEOT) - { - while (unLen < pTable[unIndex].unPrefixLen) - { - unPrefix = (unPrefix << 1) | ReadBit(); - ++unLen; - } - if (unPrefix == pTable[unIndex].unPrefix) - { - if (pTable[unIndex].unRangeLen == jbig2HuffmanOOB) - { - return false; - } - if (pTable[unIndex].unRangeLen == jbig2HuffmanLOW) - { - *pnValue = pTable[unIndex].nValue - ReadBits(32); - } - else if (pTable[unIndex].unRangeLen > 0) - { - *pnValue = pTable[unIndex].nValue + ReadBits(pTable[unIndex].unRangeLen); - } - else - { - *pnValue = pTable[unIndex].nValue; - } - return true; - } - ++unIndex; - } - return false; - } - unsigned int ReadBits(unsigned int unCount) - { - unsigned int unMask = (unCount == 32) ? 0xffffffff : ((1 << unCount) - 1); - unsigned int unValue; - if (unBufferLen >= unCount) - { - unValue = (unBuffer >> (unBufferLen - unCount)) & unMask; - unBufferLen -= unCount; - } - else - { - unValue = unBuffer & ((1 << unBufferLen) - 1); - unsigned int unLeftCount = unCount - unBufferLen; - unBufferLen = 0; - while (unLeftCount >= 8) - { - unValue = (unValue << 8) | (m_pStream->GetChar() & 0xff); - unLeftCount -= 8; - } - if (unLeftCount > 0) - { - unBuffer = m_pStream->GetChar(); - unBufferLen = 8 - unLeftCount; - unValue = (unValue << unLeftCount) | ((unBuffer >> unBufferLen) & ((1 << unLeftCount) - 1)); - } - } - return unValue; - } - - unsigned int ReadBit() - { - if (unBufferLen == 0) - { - unBuffer = m_pStream->GetChar(); - unBufferLen = 8; - } - - --unBufferLen; - return (unBuffer >> unBufferLen) & 1; - } - - - // Sort the table by prefix length and assign prefix values. - void BuildTable(JBIG2HuffmanTable *pTable, unsigned int unLen) - { - // stable selection sort: - // - entries with prefixLen > 0, in ascending prefixLen order - // - entry with prefixLen = 0, rangeLen = EOT - // - all other entries with prefixLen = 0 - // (on entry, table[len] has prefixLen = 0, rangeLen = EOT) - - unsigned int unI, unJ, unK; - for (unI = 0; unI < unLen; ++unI) - { - for (unJ = unI; unJ < unLen && pTable[unJ].unPrefixLen == 0; ++unJ); - if (unJ == unLen) - { - break; - } - for (unK = unJ + 1; unK < unLen; ++unK) - { - if (pTable[unK].unPrefixLen > 0 && pTable[unK].unPrefixLen < pTable[unJ].unPrefixLen) - { - unJ = unK; - } - } - if (unJ != unI) - { - JBIG2HuffmanTable oTable = pTable[unJ]; - for (unK = unJ; unK > unI; --unK) - { - pTable[unK] = pTable[unK - 1]; - } - pTable[unI] = oTable; - } - } - pTable[unI] = pTable[unLen]; - - // assign prefixes - unI = 0; - unsigned int unPrefix = 0; - pTable[unI++].unPrefix = unPrefix++; - for (; pTable[unI].unRangeLen != jbig2HuffmanEOT; ++unI) - { - unPrefix <<= pTable[unI].unPrefixLen - pTable[unI - 1].unPrefixLen; - pTable[unI].unPrefix = unPrefix++; - } - } - - - private: - - Stream *m_pStream; - unsigned int unBuffer; - unsigned int unBufferLen; - }; - - //------------------------------------------------------------------------ - // JBIG2MMRDecoder - //------------------------------------------------------------------------ - - class JBIG2MMRDecoder - { - public: - - JBIG2MMRDecoder() - { - m_pStream = NULL; - Reset(); - } - ~JBIG2MMRDecoder() - { - } - void SetStream(Stream *pStream) - { - m_pStream = pStream; - } - void Reset() - { - unBuffer = 0; - unBufferLen = 0; - unBytesReadCount = 0; - } - int Get2DCode() - { - CCITTCode *pCode = NULL; - - if (unBufferLen == 0) - { - unBuffer = m_pStream->GetChar() & 0xff; - unBufferLen = 8; - ++unBytesReadCount; - pCode = &c_arrTable2D[(unBuffer >> 1) & 0x7f]; - } - else if (unBufferLen == 8) - { - pCode = &c_arrTable2D[(unBuffer >> 1) & 0x7f]; - } - else - { - pCode = &c_arrTable2D[(unBuffer << (7 - unBufferLen)) & 0x7f]; - if (pCode->nBitsCount < 0 || pCode->nBitsCount >(int)unBufferLen) - { - unBuffer = (unBuffer << 8) | (m_pStream->GetChar() & 0xff); - unBufferLen += 8; - ++unBytesReadCount; - pCode = &c_arrTable2D[(unBuffer >> (unBufferLen - 7)) & 0x7f]; - } - } - - if (pCode->nBitsCount < 0) - { - return 0; - } - unBufferLen -= pCode->nBitsCount; - return pCode->nCode; - } - - int GetWhiteCode() - { - if (unBufferLen == 0) - { - unBuffer = m_pStream->GetChar() & 0xff; - unBufferLen = 8; - ++unBytesReadCount; - } - while (1) - { - CCITTCode *pCode = NULL; - if (unBufferLen >= 7 && ((unBuffer >> (unBufferLen - 7)) & 0x7f) == 0) - { - unsigned int unCode; - if (unBufferLen <= 12) - { - unCode = unBuffer << (12 - unBufferLen); - } - else - { - unCode = unBuffer >> (unBufferLen - 12); - } - pCode = &c_arrWhiteTable1[unCode & 0x1f]; - } - else - { - unsigned int unCode; - if (unBufferLen <= 9) - { - unCode = unBuffer << (9 - unBufferLen); - } - else - { - unCode = unBuffer >> (unBufferLen - 9); - } - pCode = &c_arrWhiteTable2[unCode & 0x1ff]; - } - - if (pCode->nBitsCount > 0 && pCode->nBitsCount <= (int)unBufferLen) - { - unBufferLen -= pCode->nBitsCount; - return pCode->nCode; - } - if (unBufferLen >= 12) - { - break; - } - - unBuffer = (unBuffer << 8) | (m_pStream->GetChar() & 0xff); - unBufferLen += 8; - ++unBytesReadCount; - } - // eat a bit and return a positive number so that the caller doesn't - // go into an infinite loop - --unBufferLen; - return 1; - } - int GetBlackCode() - { - if (unBufferLen == 0) - { - unBuffer = m_pStream->GetChar() & 0xff; - unBufferLen = 8; - ++unBytesReadCount; - } - while (1) - { - CCITTCode *pCode = NULL; - if (unBufferLen >= 6 && ((unBuffer >> (unBufferLen - 6)) & 0x3f) == 0) - { - unsigned int unCode; - if (unBufferLen <= 13) - { - unCode = unBuffer << (13 - unBufferLen); - } - else - { - unCode = unBuffer >> (unBufferLen - 13); - } - pCode = &c_arrBlackTable1[unCode & 0x7f]; - } - else if (unBufferLen >= 4 && ((unBuffer >> (unBufferLen - 4)) & 0x0f) == 0) - { - unsigned int unCode; - if (unBufferLen <= 12) - { - unCode = unBuffer << (12 - unBufferLen); - } - else - { - unCode = unBuffer >> (unBufferLen - 12); - } - pCode = &c_arrBlackTable2[(unCode & 0xff) - 64]; - } - else - { - unsigned int unCode; - if (unBufferLen <= 6) - { - unCode = unBuffer << (6 - unBufferLen); - } - else - { - unCode = unBuffer >> (unBufferLen - 6); - } - pCode = &c_arrBlackTable3[unCode & 0x3f]; - } - - if (pCode->nBitsCount > 0 && pCode->nBitsCount <= (int)unBufferLen) - { - unBufferLen -= pCode->nBitsCount; - return pCode->nCode; - } - - if (unBufferLen >= 13) - { - break; - } - unBuffer = (unBuffer << 8) | (m_pStream->GetChar() & 0xff); - unBufferLen += 8; - ++unBytesReadCount; - } - // eat a bit and return a positive number so that the caller doesn't - // go into an infinite loop - --unBufferLen; - return 1; - } - - unsigned int Get24Bits() - { - while (unBufferLen < 24) - { - unBuffer = (unBuffer << 8) | (m_pStream->GetChar() & 0xff); - unBufferLen += 8; - ++unBytesReadCount; - } - return (unBuffer >> (unBufferLen - 24)) & 0xffffff; - } - void SkipTo(unsigned int unLength) - { - while (unBytesReadCount < unLength) - { - m_pStream->GetChar(); - ++unBytesReadCount; - } - } - - - private: - - Stream *m_pStream; - unsigned int unBuffer; - unsigned int unBufferLen; - unsigned int unBytesReadCount; - }; - - //------------------------------------------------------------------------ - // JBIG2Segment - //------------------------------------------------------------------------ - - enum JBIG2SegmentType - { - jbig2SegBitmap, - jbig2SegSymbolDict, - jbig2SegPatternDict, - jbig2SegCodeTable - }; - - class JBIG2Segment - { - public: - - JBIG2Segment(unsigned int unSegNum) - { - m_unSegNum = unSegNum; - } - virtual ~JBIG2Segment() - { - } - void SetSegNum(unsigned int unSegNum) - { - m_unSegNum = unSegNum; - } - unsigned int GetSegNum() - { - return m_unSegNum; - } - virtual JBIG2SegmentType GetType() = 0; - - private: - - unsigned int m_unSegNum; - }; - - //------------------------------------------------------------------------ - // JBIG2Bitmap - //------------------------------------------------------------------------ - - struct JBIG2BitmapPtr - { - unsigned char *pDataPtr; - int nShift; - int nX; - }; - - class JBIG2Bitmap : public JBIG2Segment - { - public: - - JBIG2Bitmap(unsigned int unSegNum, int nW, int nH) : JBIG2Segment(unSegNum) - { - m_nW = nW; - m_nH = nH; - m_nLine = (nW + 7) >> 3; - - if (m_nW <= 0 || m_nH <= 0 || m_nLine <= 0 || m_nH >= (INT_MAX - 1) / m_nLine) - { - m_pData = NULL; - return; - } - - // need to allocate one extra guard byte for use in Combine() - m_pData = (unsigned char *)MemUtilsMalloc(m_nH * m_nLine + 1); - m_pData[m_nH * m_nLine] = 0; - } - virtual ~JBIG2Bitmap() - { - MemUtilsFree(m_pData); - } - - virtual JBIG2SegmentType GetType() - { - return jbig2SegBitmap; - } - JBIG2Bitmap *Copy() - { - return new JBIG2Bitmap(0, this); - } - //~ optimize this - JBIG2Bitmap *GetSlice(unsigned int unX, unsigned int unY, unsigned int unW, unsigned int unH) - { - JBIG2Bitmap *pSlice = new JBIG2Bitmap(0, unW, unH); - pSlice->ClearToZero(); - - for (unsigned int unCurY = 0; unCurY < unH; ++unCurY) - { - for (unsigned int unCurX = 0; unCurX < unW; ++unCurX) - { - if (GetPixel(unX + unCurX, unY + unCurY)) - { - pSlice->SetPixel(unCurX, unCurY); - } - } - } - - return pSlice; - } - void Expand(int nNewH, unsigned int unPixel) - { - if (nNewH <= m_nH || m_nLine <= 0 || nNewH >= (INT_MAX - 1) / m_nLine) - { - return; - } - - // need to allocate one extra guard byte for use in combine() - m_pData = (unsigned char *)MemUtilsRealloc(m_pData, nNewH * m_nLine + 1); - if (unPixel) - { - memset(m_pData + m_nH * m_nLine, 0xff, (nNewH - m_nH) * m_nLine); - } - else - { - memset(m_pData + m_nH * m_nLine, 0x00, (nNewH - m_nH) * m_nLine); - } - - m_nH = nNewH; - m_pData[m_nH * m_nLine] = 0; - } - - void ClearToZero() - { - memset(m_pData, 0, m_nH * m_nLine); - } - void ClearToOne() - { - memset(m_pData, 0xff, m_nH * m_nLine); - } - int GetWidth() - { - return m_nW; - } - int GetHeight() - { - return m_nH; - } - int GetPixel(int nX, int nY) - { - return (nX < 0 || nX >= m_nW || nY < 0 || nY >= m_nH) ? 0 : (m_pData[nY * m_nLine + (nX >> 3)] >> (7 - (nX & 7))) & 1; - } - void SetPixel(int nX, int nY) - { - m_pData[nY * m_nLine + (nX >> 3)] |= 1 << (7 - (nX & 7)); - } - void ClearPixel(int nX, int nY) - { - m_pData[nY * m_nLine + (nX >> 3)] &= 0x7f7f >> (nX & 7); - } - inline void GetPixelPtr(int nX, int nY, JBIG2BitmapPtr *pPtr) - { - if (nY < 0 || nY >= m_nH || nX >= m_nW) - { - pPtr->pDataPtr = NULL; - } - else if (nX < 0) - { - pPtr->pDataPtr = &m_pData[nY * m_nLine]; - pPtr->nShift = 7; - pPtr->nX = nX; - } - else - { - pPtr->pDataPtr = &m_pData[nY * m_nLine + (nX >> 3)]; - pPtr->nShift = 7 - (nX & 7); - pPtr->nX = nX; - } - } - inline int NextPixel(JBIG2BitmapPtr *pPtr) - { - int nPixel; - - if (!pPtr->pDataPtr) - { - nPixel = 0; - } - else if (pPtr->nX < 0) - { - ++pPtr->nX; - nPixel = 0; - } - else - { - nPixel = (*pPtr->pDataPtr >> pPtr->nShift) & 1; - if (++pPtr->nX == m_nW) - { - pPtr->pDataPtr = NULL; - } - else if (pPtr->nShift == 0) - { - ++pPtr->pDataPtr; - pPtr->nShift = 7; - } - else - { - --pPtr->nShift; - } - } - return nPixel; - } - - void DuplicateRow(int nDstY, int nSrcY) - { - memcpy(m_pData + nDstY * m_nLine, m_pData + nSrcY * m_nLine, m_nLine); - } - void Combine(JBIG2Bitmap *pBitmap, int nX, int nY, unsigned int unCombOp) - { - int nY0; - if (nY < 0) - { - nY0 = -nY; - } - else - { - nY0 = 0; - } - - int nY1; - if (nY + pBitmap->m_nH > m_nH) - { - nY1 = m_nH - nY; - } - else - { - nY1 = pBitmap->m_nH; - } - - if (nY0 >= nY1) - { - return; - } - - int nX0; - if (nX >= 0) - { - nX0 = nX & ~7; - } - else - { - nX0 = 0; - } - - int nX1 = nX + pBitmap->m_nW; - if (nX1 > m_nW) - { - nX1 = m_nW; - } - if (nX0 >= nX1) - { - return; - } - - unsigned int unS1 = nX & 7; - unsigned int unS2 = 8 - unS1; - - unsigned int unM1 = 0xff >> (nX1 & 7); - unsigned int unM2 = 0xff << (((nX1 & 7) == 0) ? 0 : 8 - (nX1 & 7)); - unsigned int unM3 = (0xff >> unS1) & unM2; - - bool bOneByte = (nX0 == ((nX1 - 1) & ~7)); - - unsigned char *pSrcPtr, *pDstPtr; - for (int nCurY = nY0; nCurY < nY1; ++nCurY) - { - // one byte per line -- need to mask both left and right side - if (bOneByte) - { - unsigned int unSrc1, unDst; - if (nX >= 0) - { - pDstPtr = m_pData + (nY + nCurY) * m_nLine + (nX >> 3); - pSrcPtr = pBitmap->m_pData + nCurY * pBitmap->m_nLine; - - unDst = *pDstPtr; - unSrc1 = *pSrcPtr; - - switch (unCombOp) - { - case 0: // or - unDst |= (unSrc1 >> unS1) & unM2; - break; - case 1: // and - unDst &= ((0xff00 | unSrc1) >> unS1) | unM1; - break; - case 2: // xor - unDst ^= (unSrc1 >> unS1) & unM2; - break; - case 3: // xnor - unDst ^= ((unSrc1 ^ 0xff) >> unS1) & unM2; - break; - case 4: // replace - unDst = (unDst & ~unM3) | ((unSrc1 >> unS1) & unM3); - break; - } - *pDstPtr = unDst; - } - else - { - pDstPtr = m_pData + (nY + nCurY) * m_nLine; - pSrcPtr = pBitmap->m_pData + nCurY * pBitmap->m_nLine + (-nX >> 3); - - unDst = *pDstPtr; - unSrc1 = *pSrcPtr; - - switch (unCombOp) - { - case 0: // or - unDst |= unSrc1 & unM2; - break; - case 1: // and - unDst &= unSrc1 | unM1; - break; - case 2: // xor - unDst ^= unSrc1 & unM2; - break; - case 3: // xnor - unDst ^= (unSrc1 ^ 0xff) & unM2; - break; - case 4: // replace - unDst = (unSrc1 & unM2) | (unDst & unM1); - break; - } - *pDstPtr = unDst; - } - } - else // multiple bytes per line -- need to mask left side of left-most byte and right side of right-most byte - { - int nCurX; - unsigned int unSrc0, unSrc1, unSrc, unDst; - if (nX >= 0) // left-most byte - { - pDstPtr = m_pData + (nY + nCurY) * m_nLine + (nX >> 3); - pSrcPtr = pBitmap->m_pData + nCurY * pBitmap->m_nLine; - - unSrc1 = *pSrcPtr++; - unDst = *pDstPtr; - - switch (unCombOp) - { - case 0: // or - unDst |= unSrc1 >> unS1; - break; - case 1: // and - unDst &= (0xff00 | unSrc1) >> unS1; - break; - case 2: // xor - unDst ^= unSrc1 >> unS1; - break; - case 3: // xnor - unDst ^= (unSrc1 ^ 0xff) >> unS1; - break; - case 4: // replace - unDst = (unDst & (0xff << unS2)) | (unSrc1 >> unS1); - break; - } - *pDstPtr++ = unDst; - nCurX = nX0 + 8; - } - else - { - pDstPtr = m_pData + (nY + nCurY) * m_nLine; - pSrcPtr = pBitmap->m_pData + nCurY * pBitmap->m_nLine + (-nX >> 3); - - unSrc1 = *pSrcPtr++; - nCurX = nX0; - } - - // middle bytes - for (; nCurX < nX1 - 8; nCurX += 8) - { - unDst = *pDstPtr; - unSrc0 = unSrc1; - unSrc1 = *pSrcPtr++; - unSrc = (((unSrc0 << 8) | unSrc1) >> unS1) & 0xff; - - switch (unCombOp) - { - case 0: // or - unDst |= unSrc; - break; - case 1: // and - unDst &= unSrc; - break; - case 2: // xor - unDst ^= unSrc; - break; - case 3: // xnor - unDst ^= unSrc ^ 0xff; - break; - case 4: // replace - unDst = unSrc; - break; - } - *pDstPtr++ = unDst; - } - - // right-most byte - // note: this last byte (src1) may not actually be used, depending - // on the values of s1, m1, and m2 - and in fact, it may be off - // the edge of the source bitmap, which means we need to allocate - // one extra guard byte at the end of each bitmap - unDst = *pDstPtr; - unSrc0 = unSrc1; - unSrc1 = *pSrcPtr++; - unSrc = (((unSrc0 << 8) | unSrc1) >> unS1) & 0xff; - - switch (unCombOp) - { - case 0: // or - unDst |= unSrc & unM2; - break; - case 1: // and - unDst &= unSrc | unM1; - break; - case 2: // xor - unDst ^= unSrc & unM2; - break; - case 3: // xnor - unDst ^= (unSrc ^ 0xff) & unM2; - break; - case 4: // replace - unDst = (unSrc & unM2) | (unDst & unM1); - break; - } - *pDstPtr = unDst; - } - } - } - - unsigned char *GetDataPtr() - { - return m_pData; - } - int GetDataSize() - { - return m_nH * m_nLine; - } - - private: - - JBIG2Bitmap(unsigned int unSegNum, JBIG2Bitmap *pBitmap) : JBIG2Segment(unSegNum) - { - m_nW = pBitmap->m_nW; - m_nH = pBitmap->m_nH; - m_nLine = pBitmap->m_nLine; - - if (m_nW <= 0 || m_nH <= 0 || m_nLine <= 0 || m_nH >= (INT_MAX - 1) / m_nLine) - { - m_pData = NULL; - return; - } - - // need to allocate one extra guard byte for use in Combine() - m_pData = (unsigned char *)MemUtilsMalloc(m_nH * m_nLine + 1); - memcpy(m_pData, pBitmap->m_pData, m_nH * m_nLine); - m_pData[m_nH * m_nLine] = 0; - } - - private: - - int m_nW; - int m_nH; - int m_nLine; - unsigned char *m_pData; - }; - - //------------------------------------------------------------------------ - // JBIG2SymbolDict - //------------------------------------------------------------------------ - - class JBIG2SymbolDict : public JBIG2Segment - { - public: - - JBIG2SymbolDict(unsigned int unSegNum, unsigned int unSize) : JBIG2Segment(unSegNum) - { - m_unSize = unSize; - m_ppBitmaps = (JBIG2Bitmap **)MemUtilsMallocArray(m_unSize, sizeof(JBIG2Bitmap *)); - - m_pGenericRegionStats = NULL; - m_pRefinementRegionStats = NULL; - } - virtual ~JBIG2SymbolDict() - { - for (unsigned int unIndex = 0; unIndex < m_unSize; ++unIndex) - { - delete m_ppBitmaps[unIndex]; - } - - MemUtilsFree(m_ppBitmaps); - - if (m_pGenericRegionStats) - { - delete m_pGenericRegionStats; - } - if (m_pRefinementRegionStats) - { - delete m_pRefinementRegionStats; - } - } - virtual JBIG2SegmentType GetType() - { - return jbig2SegSymbolDict; - } - unsigned int GetSize() - { - return m_unSize; - } - void SetBitmap(unsigned int unIndex, JBIG2Bitmap *pBitmap) - { - m_ppBitmaps[unIndex] = pBitmap; - } - JBIG2Bitmap *GetBitmap(unsigned int unIndex) - { - return m_ppBitmaps[unIndex]; - } - void SetGenericRegionStats(JArithmeticDecoderStats *pStats) - { - m_pGenericRegionStats = pStats; - } - void SetRefinementRegionStats(JArithmeticDecoderStats *pStats) - { - m_pRefinementRegionStats = pStats; - } - JArithmeticDecoderStats *GetGenericRegionStats() - { - return m_pGenericRegionStats; - } - JArithmeticDecoderStats *GetRefinementRegionStats() - { - return m_pRefinementRegionStats; - } - - private: - - unsigned int m_unSize; - JBIG2Bitmap **m_ppBitmaps; - JArithmeticDecoderStats *m_pGenericRegionStats; - JArithmeticDecoderStats *m_pRefinementRegionStats; - }; - - //------------------------------------------------------------------------ - // JBIG2PatternDict - //------------------------------------------------------------------------ - - class JBIG2PatternDict : public JBIG2Segment - { - public: - - JBIG2PatternDict(unsigned int unSegNum, unsigned int unSize) : JBIG2Segment(unSegNum) - { - m_unSize = unSize; - m_ppBitmaps = (JBIG2Bitmap **)MemUtilsMallocArray(m_unSize, sizeof(JBIG2Bitmap *)); - } - virtual ~JBIG2PatternDict() - { - for (unsigned int unIndex = 0; unIndex < m_unSize; ++unIndex) - { - delete m_ppBitmaps[unIndex]; - } - MemUtilsFree(m_ppBitmaps); - } - virtual JBIG2SegmentType GetType() { return jbig2SegPatternDict; } - unsigned int GetSize() - { - return m_unSize; - } - void SetBitmap(unsigned int unIndex, JBIG2Bitmap *pBitmap) - { - m_ppBitmaps[unIndex] = pBitmap; - } - JBIG2Bitmap *GetBitmap(unsigned int unIndex) - { - return m_ppBitmaps[unIndex]; - } - - private: - - unsigned int m_unSize; - JBIG2Bitmap **m_ppBitmaps; - }; - - //------------------------------------------------------------------------ - // JBIG2CodeTable - //------------------------------------------------------------------------ - - class JBIG2CodeTable : public JBIG2Segment - { - public: - - JBIG2CodeTable(unsigned int unSegNum, JBIG2HuffmanTable *pTable) : JBIG2Segment(unSegNum) - { - m_pTable = pTable; - } - virtual ~JBIG2CodeTable() - { - MemUtilsFree(m_pTable); - } - virtual JBIG2SegmentType GetType() - { - return jbig2SegCodeTable; - } - JBIG2HuffmanTable *GetHuffTable() - { - return m_pTable; - } - - private: - - JBIG2HuffmanTable *m_pTable; - }; - - //------------------------------------------------------------------------ - // JBIG2Stream - //------------------------------------------------------------------------ - - JBIG2Stream::JBIG2Stream(Stream *pStream, Object *pGlobalsStream) : - FilterStream(pStream) - { - m_pPageBitmap = NULL; - - m_pArithDecoder = new JArithmeticDecoder(); - - m_pGenericRegionStats = new JArithmeticDecoderStats(1 << 1); - m_pRefinementRegionStats = new JArithmeticDecoderStats(1 << 1); - - m_pIadhStats = new JArithmeticDecoderStats(1 << 9); - m_pIadwStats = new JArithmeticDecoderStats(1 << 9); - m_pIaexStats = new JArithmeticDecoderStats(1 << 9); - m_pIaaiStats = new JArithmeticDecoderStats(1 << 9); - m_pIadtStats = new JArithmeticDecoderStats(1 << 9); - m_pIaitStats = new JArithmeticDecoderStats(1 << 9); - m_pIafsStats = new JArithmeticDecoderStats(1 << 9); - m_pIadsStats = new JArithmeticDecoderStats(1 << 9); - m_pIardxStats = new JArithmeticDecoderStats(1 << 9); - m_pIardyStats = new JArithmeticDecoderStats(1 << 9); - m_pIardwStats = new JArithmeticDecoderStats(1 << 9); - m_pIardhStats = new JArithmeticDecoderStats(1 << 9); - m_pIariStats = new JArithmeticDecoderStats(1 << 9); - m_pIaidStats = new JArithmeticDecoderStats(1 << 1); - - m_pHuffDecoder = new JBIG2HuffmanDecoder(); - m_pMMrDecoder = new JBIG2MMRDecoder(); - - pGlobalsStream->Copy(&m_oGlobalsStream); - - m_pSegments = m_pGlobalSegments = NULL; - m_pCurStream = NULL; - m_pDataPtr = m_pDataEnd = NULL; - } - - JBIG2Stream::~JBIG2Stream() - { - Close(); - m_oGlobalsStream.Free(); - - delete m_pArithDecoder; - delete m_pGenericRegionStats; - delete m_pRefinementRegionStats; - delete m_pIadhStats; - delete m_pIadwStats; - delete m_pIaexStats; - delete m_pIaaiStats; - delete m_pIadtStats; - delete m_pIaitStats; - delete m_pIafsStats; - delete m_pIadsStats; - delete m_pIardxStats; - delete m_pIardyStats; - delete m_pIardwStats; - delete m_pIardhStats; - delete m_pIariStats; - delete m_pIaidStats; - delete m_pHuffDecoder; - delete m_pMMrDecoder; - delete m_pStream; - } - - void JBIG2Stream::Reset() - { - // read the globals stream - m_pGlobalSegments = new CList(); - if (m_oGlobalsStream.IsStream()) - { - m_pSegments = m_pGlobalSegments; - - m_pCurStream = m_oGlobalsStream.GetStream(); - m_pCurStream->Reset(); - - m_pArithDecoder->SetStream(m_pCurStream); - m_pHuffDecoder->SetStream(m_pCurStream); - m_pMMrDecoder->SetStream(m_pCurStream); - ReadSegments(); - m_pCurStream->Close(); - } - - // read the main stream - m_pSegments = new CList(); - - m_pCurStream = m_pStream; - m_pCurStream->Reset(); - - m_pArithDecoder->SetStream(m_pCurStream); - m_pHuffDecoder->SetStream(m_pCurStream); - m_pMMrDecoder->SetStream(m_pCurStream); - - ReadSegments(); - - if (m_pPageBitmap) - { - m_pDataPtr = m_pPageBitmap->GetDataPtr(); - m_pDataEnd = m_pDataPtr + m_pPageBitmap->GetDataSize(); - } - else - { - m_pDataPtr = m_pDataEnd = NULL; - } - } - - void JBIG2Stream::Close() - { - if (m_pPageBitmap) - { - delete m_pPageBitmap; - m_pPageBitmap = NULL; - } - if (m_pSegments) - { - DeleteCList(m_pSegments, JBIG2Segment); - m_pSegments = NULL; - } - if (m_pGlobalSegments) - { - DeleteCList(m_pGlobalSegments, JBIG2Segment); - m_pGlobalSegments = NULL; - } - m_pDataPtr = m_pDataEnd = NULL; - FilterStream::Close(); - } - - int JBIG2Stream::GetChar() - { - if (m_pDataPtr && m_pDataPtr < m_pDataEnd) - { - return (*m_pDataPtr++ ^ 0xff) & 0xff; - } - return EOF; - } - - int JBIG2Stream::LookChar() - { - if (m_pDataPtr && m_pDataPtr < m_pDataEnd) - { - return (*m_pDataPtr ^ 0xff) & 0xff; - } - return EOF; - } - - StringExt *JBIG2Stream::GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - - bool JBIG2Stream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - void JBIG2Stream::ReadSegments() - { - unsigned int unSegNum; - while (ReadULong(&unSegNum)) - { - // segment header flags - unsigned int unSegFlags; - if (!ReadUByte(&unSegFlags)) - { - return; - } - - unsigned int unSegType = unSegFlags & 0x3f; - - // referred-to segment count and retention flags - unsigned int unRefFlags; - if (!ReadUByte(&unRefFlags)) - { - return; - } - unsigned int unRefSegsCount = unRefFlags >> 5; - - if (7 == unRefSegsCount) - { - int nChar1, nChar2, nChar3; - if (EOF == (nChar1 = m_pCurStream->GetChar()) || EOF == (nChar2 = m_pCurStream->GetChar()) || EOF == (nChar3 = m_pCurStream->GetChar())) - { - return; - } - unRefFlags = (unRefFlags << 24) | (nChar1 << 16) | (nChar2 << 8) | nChar3; - unRefSegsCount = unRefFlags & 0x1fffffff; - for (unsigned int unIndex = 0; unIndex < (unRefSegsCount + 9) >> 3; ++unIndex) - { - nChar1 = m_pCurStream->GetChar(); - } - } - - // referred-to segment numbers - unsigned int *punRefSegs = (unsigned int *)MemUtilsMallocArray(unRefSegsCount, sizeof(unsigned int)); - if (unSegNum <= 256) - { - for (unsigned int unIndex = 0; unIndex < unRefSegsCount; ++unIndex) - { - if (!ReadUByte(&punRefSegs[unIndex])) - { - MemUtilsFree(punRefSegs); - return; - } - } - } - else if (unSegNum <= 65536) - { - for (unsigned int unIndex = 0; unIndex < unRefSegsCount; ++unIndex) - { - if (!ReadUWord(&punRefSegs[unIndex])) - { - MemUtilsFree(punRefSegs); - return; - } - } - } - else - { - for (unsigned int unIndex = 0; unIndex < unRefSegsCount; ++unIndex) - { - if (!ReadULong(&punRefSegs[unIndex])) - { - MemUtilsFree(punRefSegs); - return; - } - } - } - - // segment page association - unsigned int unPage; - if (unSegFlags & 0x40) - { - if (!ReadULong(&unPage)) - { - MemUtilsFree(punRefSegs); - return; - } - } - else - { - if (!ReadUByte(&unPage)) - { - MemUtilsFree(punRefSegs); - return; - } - } - - // segment data length - unsigned int unSegLength; - if (!ReadULong(&unSegLength)) - { - MemUtilsFree(punRefSegs); - return; - } - - unsigned int unDataStartPos = m_pCurStream->GetPos(); - - // read the segment data - switch (unSegType) - { - case 0: - if (!ReadSymbolDictSegment(unSegNum, unSegLength, punRefSegs, unRefSegsCount)) - { - MemUtilsFree(punRefSegs); - return; - } - break; - case 4: - ReadTextRegionSegment(unSegNum, false, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 6: - ReadTextRegionSegment(unSegNum, true, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 7: - ReadTextRegionSegment(unSegNum, true, true, unSegLength, punRefSegs, unRefSegsCount); - break; - case 16: - ReadPatternDictSegment(unSegNum, unSegLength); - break; - case 20: - ReadHalftoneRegionSegment(unSegNum, false, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 22: - ReadHalftoneRegionSegment(unSegNum, true, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 23: - ReadHalftoneRegionSegment(unSegNum, true, true, unSegLength, punRefSegs, unRefSegsCount); - break; - case 36: - ReadGenericRegionSegment(unSegNum, false, false, unSegLength); - break; - case 38: - ReadGenericRegionSegment(unSegNum, true, false, unSegLength); - break; - case 39: - ReadGenericRegionSegment(unSegNum, true, true, unSegLength); - break; - case 40: - ReadGenericRefinementRegionSegment(unSegNum, false, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 42: - ReadGenericRefinementRegionSegment(unSegNum, true, false, unSegLength, punRefSegs, unRefSegsCount); - break; - case 43: - ReadGenericRefinementRegionSegment(unSegNum, true, true, unSegLength, punRefSegs, unRefSegsCount); - break; - case 48: - ReadPageInfoSegment(unSegLength); - break; - case 50: - ReadEndOfStripeSegment(unSegLength); - break; - case 52: - ReadProfilesSegment(unSegLength); - break; - case 53: - ReadCodeTableSegment(unSegNum, unSegLength); - break; - case 62: - ReadExtensionSegment(unSegLength); - break; - default: - for (unsigned int unIndex = 0; unIndex < unSegLength; ++unIndex) - { - int nChar; - if (EOF == (nChar = m_pCurStream->GetChar())) - { - MemUtilsFree(punRefSegs); - return; - } - } - break; - } - - MemUtilsFree(punRefSegs); - - if (unSegLength != 0xFFFFFFFF && m_pCurStream->GetPos() - unDataStartPos != unSegLength) - m_pCurStream->SetPos(unDataStartPos + unSegLength); - } - - return; - } - - bool JBIG2Stream::ReadSymbolDictSegment(unsigned int unSegNum, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount) - { - // symbol dictionary flags - unsigned int unFlags; - if (!ReadUWord(&unFlags)) - { - return false; - } - unsigned int unHuff = unFlags & 1; - unsigned int unRefAgg = (unFlags >> 1) & 1; - unsigned int unHuffDH = (unFlags >> 2) & 3; - unsigned int unHuffDW = (unFlags >> 4) & 3; - unsigned int unHuffBMSize = (unFlags >> 6) & 1; - unsigned int unHuffAggInst = (unFlags >> 7) & 1; - unsigned int unContextUsed = (unFlags >> 8) & 1; - unsigned int unContextRetained = (unFlags >> 9) & 1; - unsigned int unSDTemplate = (unFlags >> 10) & 3; - unsigned int unSDRTemplate = (unFlags >> 12) & 1; - - // symbol dictionary AT flags - int arrSDATx[4], arrSDATy[4]; - if (!unHuff) - { - if (unSDTemplate == 0) - { - if (!ReadByte(&arrSDATx[0]) || !ReadByte(&arrSDATy[0]) || !ReadByte(&arrSDATx[1]) || !ReadByte(&arrSDATy[1]) || - !ReadByte(&arrSDATx[2]) || !ReadByte(&arrSDATy[2]) || !ReadByte(&arrSDATx[3]) || !ReadByte(&arrSDATy[3])) - { - return false; - } - } - else - { - if (!ReadByte(&arrSDATx[0]) || !ReadByte(&arrSDATy[0])) - { - return false; - } - } - } - - // symbol dictionary refinement AT flags - int arrSDRATx[2], arrSDRATy[2]; - if (unRefAgg && !unSDRTemplate) - { - if (!ReadByte(&arrSDRATx[0]) || !ReadByte(&arrSDRATy[0]) || !ReadByte(&arrSDRATx[1]) || !ReadByte(&arrSDRATy[1])) - { - return false; - } - } - - // SDNUMEXSYMS and SDNUMNEWSYMS - unsigned int unNumExSyms, unNumNewSyms; - if (!ReadULong(&unNumExSyms) || !ReadULong(&unNumNewSyms)) - { - return false; - } - - // get referenced segments: input symbol dictionaries and code tables - CList *pCodeTables = new CList(); - unsigned int unNumInputSyms = 0, unI; - for (unI = 0; unI < unRefSegsCount; ++unI) - { - JBIG2Segment *pSegment = FindSegment(punRefSegs[unI]); - if (pSegment->GetType() == jbig2SegSymbolDict) - { - unNumInputSyms += ((JBIG2SymbolDict *)pSegment)->GetSize(); - } - else if (pSegment->GetType() == jbig2SegCodeTable) - { - pCodeTables->Append(pSegment); - } - } - - // compute symbol code length - unsigned int unSymCodeLen = 0; - unI = 1; - while (unI < unNumInputSyms + unNumNewSyms) - { - ++unSymCodeLen; - unI <<= 1; - } - - // get the input symbol bitmaps - JBIG2Bitmap **ppBitmaps = (JBIG2Bitmap **)MemUtilsMallocArray(unNumInputSyms + unNumNewSyms, sizeof(JBIG2Bitmap *)); - for (unI = 0; unI < unNumInputSyms + unNumNewSyms; ++unI) - { - ppBitmaps[unI] = NULL; - } - - unsigned int unK = 0, unJ; - JBIG2SymbolDict *pInputSymbolDict = NULL; - for (unI = 0; unI < unRefSegsCount; ++unI) - { - JBIG2Segment *pSegment = FindSegment(punRefSegs[unI]); - if (pSegment->GetType() == jbig2SegSymbolDict) - { - pInputSymbolDict = (JBIG2SymbolDict *)pSegment; - for (unJ = 0; unJ < pInputSymbolDict->GetSize(); ++unJ) - { - ppBitmaps[unK++] = pInputSymbolDict->GetBitmap(unJ); - } - } - } - - // get the Huffman tables - JBIG2HuffmanTable *pHuffDHTable = NULL, *pHuffDWTable = NULL, *pHuffBMSizeTable = NULL, *pHuffAggInstTable = NULL; - unI = 0; - if (unHuff) - { - if (unHuffDH == 0) - { - pHuffDHTable = c_oHuffTableD; - } - else if (unHuffDH == 1) - { - pHuffDHTable = c_oHuffTableE; - } - else - { - pHuffDHTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unI++))->GetHuffTable(); - } - - if (unHuffDW == 0) - { - pHuffDWTable = c_oHuffTableB; - } - else if (unHuffDW == 1) - { - pHuffDWTable = c_oHuffTableC; - } - else - { - pHuffDWTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unI++))->GetHuffTable(); - } - - if (unHuffBMSize == 0) - { - pHuffBMSizeTable = c_oHuffTableA; - } - else - { - pHuffBMSizeTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unI++))->GetHuffTable(); - } - - if (unHuffAggInst == 0) - { - pHuffAggInstTable = c_oHuffTableA; - } - else - { - pHuffAggInstTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unI++))->GetHuffTable(); - } - } - delete pCodeTables; - - // set up the Huffman decoder - if (unHuff) - { - m_pHuffDecoder->Reset(); - } - else // set up the arithmetic decoder - { - if (unContextUsed && pInputSymbolDict) - { - ResetGenericStats(unSDTemplate, pInputSymbolDict->GetGenericRegionStats()); - } - else - { - ResetGenericStats(unSDTemplate, NULL); - } - ResetIntStats(unSymCodeLen); - m_pArithDecoder->Start(); - } - - // set up the arithmetic decoder for refinement/aggregation - if (unRefAgg) - { - if (unContextUsed && pInputSymbolDict) - { - ResetRefinementStats(unSDRTemplate, pInputSymbolDict->GetRefinementRegionStats()); - } - else - { - ResetRefinementStats(unSDRTemplate, NULL); - } - } - - // allocate symbol widths storage - unsigned int *pSymWidths = NULL; - if (unHuff && !unRefAgg) - { - pSymWidths = (unsigned int *)MemUtilsMallocArray(unNumNewSyms, sizeof(unsigned int)); - } - - unsigned int unSymHeight = 0; - unI = 0; - while (unI < unNumNewSyms) - { - // read the height class delta height - int nDh; - if (unHuff) - { - m_pHuffDecoder->DecodeInt(&nDh, pHuffDHTable); - } - else - { - m_pArithDecoder->DecodeInt(&nDh, m_pIadhStats); - } - if (nDh < 0 && (unsigned int)-nDh >= unSymHeight) - { - // SyntaxError - for (unsigned int unIndex = 0; unIndex < unNumNewSyms; ++unIndex) - { - if (ppBitmaps[unNumInputSyms + unIndex]) - { - delete ppBitmaps[unNumInputSyms + unIndex]; - } - } - - MemUtilsFree(ppBitmaps); - if (pSymWidths) - { - MemUtilsFree(pSymWidths); - } - return false; - } - unSymHeight += nDh; - unsigned int unSymWidth = 0, unTotalWidth = 0; - unJ = unI; - - // read the symbols in this height class - while (1) - { - // read the delta width - int nDw; - if (unHuff) - { - if (!m_pHuffDecoder->DecodeInt(&nDw, pHuffDWTable)) - { - break; - } - } - else - { - if (!m_pArithDecoder->DecodeInt(&nDw, m_pIadwStats)) - { - break; - } - } - if (nDw < 0 && (unsigned int)-nDw >= unSymWidth) - { - // SyntaxError - for (unsigned int unIndex = 0; unIndex < unNumNewSyms; ++unIndex) - { - if (ppBitmaps[unNumInputSyms + unIndex]) - { - delete ppBitmaps[unNumInputSyms + unIndex]; - } - } - - MemUtilsFree(ppBitmaps); - if (pSymWidths) - { - MemUtilsFree(pSymWidths); - } - return false; - } - unSymWidth += nDw; - - // using a collective bitmap, so don't read a bitmap here - if (unHuff && !unRefAgg) - { - pSymWidths[unI] = unSymWidth; - unTotalWidth += unSymWidth; - } - else if (unRefAgg) // refinement/aggregate coding - { - int nRefAggNum; - if (unHuff) - { - if (!m_pHuffDecoder->DecodeInt(&nRefAggNum, pHuffAggInstTable)) - { - break; - } - } - else - { - if (!m_pArithDecoder->DecodeInt(&nRefAggNum, m_pIaaiStats)) - { - break; - } - } -#if 0 //~ This special case was added about a year before the final draft - //~ of the JBIG2 spec was released. I have encountered some old - //~ JBIG2 images that predate it. - if ( 0 ) - { -#else - if (nRefAggNum == 1) - { -#endif - unsigned int unSymID; - int nRefDX, nRefDY, nBMSize; - if (unHuff) - { - unSymID = m_pHuffDecoder->ReadBits(unSymCodeLen); - m_pHuffDecoder->DecodeInt(&nRefDX, c_oHuffTableO); - m_pHuffDecoder->DecodeInt(&nRefDY, c_oHuffTableO); - m_pHuffDecoder->DecodeInt(&nBMSize, c_oHuffTableA); - m_pHuffDecoder->Reset(); - m_pArithDecoder->Start(); - } - else - { - unSymID = m_pArithDecoder->DecodeIAID(unSymCodeLen, m_pIaidStats); - m_pArithDecoder->DecodeInt(&nRefDX, m_pIardxStats); - m_pArithDecoder->DecodeInt(&nRefDY, m_pIardyStats); - } - JBIG2Bitmap *pRefBitmap = ppBitmaps[unSymID]; - ppBitmaps[unNumInputSyms + unI] = ReadGenericRefinementRegion(unSymWidth, unSymHeight, unSDRTemplate, false, pRefBitmap, nRefDX, nRefDY, arrSDRATx, arrSDRATy); - } - else //~ do we need to use the bmSize value here (in Huffman mode)? - { - ppBitmaps[unNumInputSyms + unI] = ReadTextRegion(unHuff ? true : false, true, unSymWidth, unSymHeight, nRefAggNum, 0, unNumInputSyms + unI, NULL, unSymCodeLen, ppBitmaps, 0, 0, 0, 1, 0, c_oHuffTableF, c_oHuffTableH, c_oHuffTableK, c_oHuffTableO, c_oHuffTableO, c_oHuffTableO, c_oHuffTableO, c_oHuffTableA, unSDRTemplate, arrSDRATx, arrSDRATy); - } - } - else // non-ref/agg coding - { - ppBitmaps[unNumInputSyms + unI] = ReadGenericBitmap(false, unSymWidth, unSymHeight, unSDTemplate, false, false, NULL, arrSDATx, arrSDATy, 0); - } - - ++unI; - } - - // read the collective bitmap - if (unHuff && !unRefAgg) - { - int nBMSize; - m_pHuffDecoder->DecodeInt(&nBMSize, pHuffBMSizeTable); - m_pHuffDecoder->Reset(); - - JBIG2Bitmap *pCollBitmap; - if (nBMSize == 0) - { - pCollBitmap = new JBIG2Bitmap(0, unTotalWidth, unSymHeight); - nBMSize = unSymHeight * ((unTotalWidth + 7) >> 3); - unsigned char *pDataPtr = pCollBitmap->GetDataPtr(); - for (unK = 0; unK < (unsigned int)nBMSize; ++unK) - { - *pDataPtr++ = m_pCurStream->GetChar(); - } - } - else - { - pCollBitmap = ReadGenericBitmap(true, unTotalWidth, unSymHeight, 0, false, false, NULL, NULL, NULL, nBMSize); - } - unsigned int unX = 0; - for (; unJ < unI; ++unJ) - { - ppBitmaps[unNumInputSyms + unJ] = pCollBitmap->GetSlice(unX, 0, pSymWidths[unJ], unSymHeight); - unX += pSymWidths[unJ]; - } - delete pCollBitmap; - } - } - - // create the symbol dict object - JBIG2SymbolDict *pSymbolDict = new JBIG2SymbolDict(unSegNum, unNumExSyms); - - // exported symbol list - unI = unJ = 0; - bool bEx = false; - while (unI < unNumInputSyms + unNumNewSyms) - { - int nRun; - if (unHuff) - { - m_pHuffDecoder->DecodeInt(&nRun, c_oHuffTableA); - } - else - { - m_pArithDecoder->DecodeInt(&nRun, m_pIaexStats); - } - if (bEx) - { - for (int nCounter = 0; nCounter < nRun; ++nCounter) - { - pSymbolDict->SetBitmap(unJ++, ppBitmaps[unI++]->Copy()); - } - } - else - { - unI += nRun; - } - bEx = !bEx; - } - - for (unI = 0; unI < unNumNewSyms; ++unI) - { - delete ppBitmaps[unNumInputSyms + unI]; - } - MemUtilsFree(ppBitmaps); - if (pSymWidths) - { - MemUtilsFree(pSymWidths); - } - - // save the arithmetic decoder stats - if (!unHuff && unContextRetained) - { - pSymbolDict->SetGenericRegionStats(m_pGenericRegionStats->Copy()); - if (unRefAgg) - { - pSymbolDict->SetRefinementRegionStats(m_pRefinementRegionStats->Copy()); - } - } - - // store the new symbol dict - m_pSegments->Append(pSymbolDict); - - return true; - } - - void JBIG2Stream::ReadTextRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount) - { - // region segment info field - unsigned int unW, unH, unX, unY, unSegInfoFlags; - if (!ReadULong(&unW) || !ReadULong(&unH) || !ReadULong(&unX) || !ReadULong(&unY) || !ReadUByte(&unSegInfoFlags)) - { - return; - } - - unsigned int unExtCombOp = unSegInfoFlags & 7; - - // rest of the text region header - unsigned int unFlags; - if (!ReadUWord(&unFlags)) - { - return; - } - - unsigned int unHuff = unFlags & 1; - unsigned int unRefine = (unFlags >> 1) & 1; - unsigned int unLogStrips = (unFlags >> 2) & 3; - unsigned int unRefCorner = (unFlags >> 4) & 3; - unsigned int unTransposed = (unFlags >> 6) & 1; - unsigned int unCombOp = (unFlags >> 7) & 3; - unsigned int unDefPixel = (unFlags >> 9) & 1; - int nSOffset = (unFlags >> 10) & 0x1f; - unsigned int unTempl = (unFlags >> 15) & 1; - - if (nSOffset & 0x10) - { - nSOffset |= -1 - 0x0f; - } - - unsigned int unHuffFS = 0, unHuffDS = 0, unHuffDT = 0, unHuffRDW = 0, unHuffRDH = 0, unHuffRDX = 0, unHuffRDY = 0, unHuffRSize = 0; - if (unHuff) - { - unsigned int unHuffFlags; - if (!ReadUWord(&unHuffFlags)) - { - return; - } - unHuffFS = unHuffFlags & 3; - unHuffDS = (unHuffFlags >> 2) & 3; - unHuffDT = (unHuffFlags >> 4) & 3; - unHuffRDW = (unHuffFlags >> 6) & 3; - unHuffRDH = (unHuffFlags >> 8) & 3; - unHuffRDX = (unHuffFlags >> 10) & 3; - unHuffRDY = (unHuffFlags >> 12) & 3; - unHuffRSize = (unHuffFlags >> 14) & 1; - } - - int arrATx[2], arrATy[2]; - if (unRefine && unTempl == 0) - { - if (!ReadByte(&arrATx[0]) || !ReadByte(&arrATy[0]) || !ReadByte(&arrATx[1]) || !ReadByte(&arrATy[1])) - { - return; - } - } - - unsigned int unNumInstances; - if (!ReadULong(&unNumInstances)) - { - return; - } - - // get symbol dictionaries and tables - CList *pCodeTables = new CList(); - unsigned int unNumSyms = 0; - unsigned int unIndex; - for (unIndex = 0; unIndex < unRefSegsCount; ++unIndex) - { - JBIG2Segment *pSegment = NULL; - if ((pSegment = FindSegment(punRefSegs[unIndex]))) - { - if (pSegment->GetType() == jbig2SegSymbolDict) - { - unNumSyms += ((JBIG2SymbolDict *)pSegment)->GetSize(); - } - else if (pSegment->GetType() == jbig2SegCodeTable) - { - pCodeTables->Append(pSegment); - } - } - else - { - } - } - - unsigned int unSymCodeLen = 0; - unIndex = 1; - while (unIndex < unNumSyms) - { - ++unSymCodeLen; - unIndex <<= 1; - } - - // get the symbol bitmaps - JBIG2Bitmap **ppSyms = (JBIG2Bitmap **)MemUtilsMallocArray(unNumSyms, sizeof(JBIG2Bitmap *)); - unsigned int unSymsIndex = 0; - for (unIndex = 0; unIndex < unRefSegsCount; ++unIndex) - { - JBIG2Segment *pSegment = NULL; - if ((pSegment = FindSegment(punRefSegs[unIndex]))) - { - if (pSegment->GetType() == jbig2SegSymbolDict) - { - JBIG2SymbolDict *pSymbolDict = (JBIG2SymbolDict *)pSegment; - for (unsigned int unK = 0; unK < pSymbolDict->GetSize(); ++unK) - { - ppSyms[unSymsIndex++] = pSymbolDict->GetBitmap(unK); - } - } - } - } - - // get the Huffman tables - JBIG2HuffmanTable *pHuffFSTable = NULL, *pHuffDSTable = NULL, *pHuffDTTable = NULL, *pHuffRDWTable = NULL, *pHuffRDHTable = NULL, *pHuffRDXTable = NULL, *pHuffRDYTable = NULL, *pHuffRSizeTable = NULL; - unIndex = 0; - if (unHuff) - { - if (unHuffFS == 0) - { - pHuffFSTable = c_oHuffTableF; - } - else if (unHuffFS == 1) - { - pHuffFSTable = c_oHuffTableG; - } - else - { - pHuffFSTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - if (unHuffDS == 0) - { - pHuffDSTable = c_oHuffTableH; - } - else if (unHuffDS == 1) - { - pHuffDSTable = c_oHuffTableI; - } - else if (unHuffDS == 2) - { - pHuffDSTable = c_oHuffTableJ; - } - else - { - pHuffDSTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffDT == 0) - { - pHuffDTTable = c_oHuffTableK; - } - else if (unHuffDT == 1) - { - pHuffDTTable = c_oHuffTableL; - } - else if (unHuffDT == 2) - { - pHuffDTTable = c_oHuffTableM; - } - else - { - pHuffDTTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffRDW == 0) - { - pHuffRDWTable = c_oHuffTableN; - } - else if (unHuffRDW == 1) - { - pHuffRDWTable = c_oHuffTableO; - } - else - { - pHuffRDWTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffRDH == 0) - { - pHuffRDHTable = c_oHuffTableN; - } - else if (unHuffRDH == 1) - { - pHuffRDHTable = c_oHuffTableO; - } - else - { - pHuffRDHTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffRDX == 0) - { - pHuffRDXTable = c_oHuffTableN; - } - else if (unHuffRDX == 1) - { - pHuffRDXTable = c_oHuffTableO; - } - else - { - pHuffRDXTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffRDY == 0) - { - pHuffRDYTable = c_oHuffTableN; - } - else if (unHuffRDY == 1) - { - pHuffRDYTable = c_oHuffTableO; - } - else - { - pHuffRDYTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - - if (unHuffRSize == 0) - { - pHuffRSizeTable = c_oHuffTableA; - } - else - { - pHuffRSizeTable = ((JBIG2CodeTable *)pCodeTables->GetByIndex(unIndex++))->GetHuffTable(); - } - } - delete pCodeTables; - - // symbol ID Huffman decoding table - JBIG2HuffmanTable *pSymCodeTab; - if (unHuff) - { - m_pHuffDecoder->Reset(); - JBIG2HuffmanTable arrRunLengthTab[36]; - - for (unIndex = 0; unIndex < 32; ++unIndex) - { - arrRunLengthTab[unIndex].nValue = unIndex; - arrRunLengthTab[unIndex].unPrefixLen = m_pHuffDecoder->ReadBits(4); - arrRunLengthTab[unIndex].unRangeLen = 0; - } - arrRunLengthTab[32].nValue = 0x103; - arrRunLengthTab[32].unPrefixLen = m_pHuffDecoder->ReadBits(4); - arrRunLengthTab[32].unRangeLen = 2; - - arrRunLengthTab[33].nValue = 0x203; - arrRunLengthTab[33].unPrefixLen = m_pHuffDecoder->ReadBits(4); - arrRunLengthTab[33].unRangeLen = 3; - - arrRunLengthTab[34].nValue = 0x20b; - arrRunLengthTab[34].unPrefixLen = m_pHuffDecoder->ReadBits(4); - arrRunLengthTab[34].unRangeLen = 7; - - arrRunLengthTab[35].unPrefixLen = 0; - arrRunLengthTab[35].unRangeLen = jbig2HuffmanEOT; - - m_pHuffDecoder->BuildTable(arrRunLengthTab, 35); - pSymCodeTab = (JBIG2HuffmanTable *)MemUtilsMallocArray(unNumSyms + 1, sizeof(JBIG2HuffmanTable)); - - for (unIndex = 0; unIndex < unNumSyms; ++unIndex) - { - pSymCodeTab[unIndex].nValue = unIndex; - pSymCodeTab[unIndex].unRangeLen = 0; - } - unIndex = 0; - - int nJ; - while (unIndex < unNumSyms) - { - m_pHuffDecoder->DecodeInt(&nJ, arrRunLengthTab); - if (nJ > 0x200) - { - for (nJ -= 0x200; nJ && unIndex < unNumSyms; --nJ) - { - pSymCodeTab[unIndex++].unPrefixLen = 0; - } - } - else if (nJ > 0x100) - { - for (nJ -= 0x100; nJ && unIndex < unNumSyms; --nJ) - { - pSymCodeTab[unIndex].unPrefixLen = pSymCodeTab[unIndex - 1].unPrefixLen; - ++unIndex; - } - } - else - { - pSymCodeTab[unIndex++].unPrefixLen = nJ; - } - } - pSymCodeTab[unNumSyms].unPrefixLen = 0; - pSymCodeTab[unNumSyms].unRangeLen = jbig2HuffmanEOT; - m_pHuffDecoder->BuildTable(pSymCodeTab, unNumSyms); - m_pHuffDecoder->Reset(); - } - else // set up the arithmetic decoder - { - pSymCodeTab = NULL; - ResetIntStats(unSymCodeLen); - m_pArithDecoder->Start(); - } - if (unRefine) - { - ResetRefinementStats(unTempl, NULL); - } - - JBIG2Bitmap *pBitmap = ReadTextRegion(unHuff ? true : false, unRefine ? true : false, unW, unH, unNumInstances, unLogStrips, unNumSyms, pSymCodeTab, unSymCodeLen, ppSyms, unDefPixel, unCombOp, unTransposed, unRefCorner, nSOffset, pHuffFSTable, pHuffDSTable, pHuffDTTable, pHuffRDWTable, pHuffRDHTable, pHuffRDXTable, pHuffRDYTable, pHuffRSizeTable, unTempl, arrATx, arrATy); - - MemUtilsFree(ppSyms); - - // combine the region bitmap into the page bitmap - if (bImm) - { - if (m_unPageH == 0xffffffff && unY + unH > m_unCurPageH) - { - m_pPageBitmap->Expand(unY + unH, m_unPageDefPixel); - } - m_pPageBitmap->Combine(pBitmap, unX, unY, unExtCombOp); - delete pBitmap; - } - else // store the region bitmap - { - pBitmap->SetSegNum(unSegNum); - m_pSegments->Append(pBitmap); - } - - // clean up the Huffman decoder - if (unHuff) - { - MemUtilsFree(pSymCodeTab); - } - - return; - } - - JBIG2Bitmap *JBIG2Stream::ReadTextRegion(bool bHuff, bool bRefine, int nW, int nH, unsigned int unNumInstances, unsigned int unLogStrips, int nNumSyms, JBIG2HuffmanTable *pSymCodeTab, unsigned int unSymCodeLen, JBIG2Bitmap **ppSyms, unsigned int unDefPixel, unsigned int unCombOp, unsigned int transposed, unsigned int refCorner, int nSOffset, JBIG2HuffmanTable *pHuffFSTable, JBIG2HuffmanTable *pHuffDSTable, JBIG2HuffmanTable *pHuffDTTable, JBIG2HuffmanTable *pHuffRDWTable, JBIG2HuffmanTable *pHuffRDHTable, JBIG2HuffmanTable *pHuffRDXTable, JBIG2HuffmanTable *pHuffRDYTable, JBIG2HuffmanTable *pHuffRSizeTable, unsigned int unTempl, int *pnATx, int *pnATy) - { - unsigned int unStrips = 1 << unLogStrips; - - // allocate the bitmap - JBIG2Bitmap *pBitmap = new JBIG2Bitmap(0, nW, nH); - if (unDefPixel) - { - pBitmap->ClearToOne(); - } - else - { - pBitmap->ClearToZero(); - } - - // decode initial T value - int nT; - if (bHuff) - { - m_pHuffDecoder->DecodeInt(&nT, pHuffDTTable); - } - else - { - m_pArithDecoder->DecodeInt(&nT, m_pIadtStats); - } - nT *= -(int)unStrips; - - unsigned int unInstance = 0; - int nSFirst = 0; - while (unInstance < unNumInstances) - { - // decode delta-T - int nDeltaT; - if (bHuff) - { - m_pHuffDecoder->DecodeInt(&nDeltaT, pHuffDTTable); - } - else - { - m_pArithDecoder->DecodeInt(&nDeltaT, m_pIadtStats); - } - nT += nDeltaT * unStrips; - - // first S value - int nDS; - if (bHuff) - { - m_pHuffDecoder->DecodeInt(&nDS, pHuffFSTable); - } - else - { - m_pArithDecoder->DecodeInt(&nDS, m_pIafsStats); - } - nSFirst += nDS; - - int nCurS = nSFirst; - - // read the instances - while (1) - { - // T value - if (1 == unStrips) - { - nDeltaT = 0; - } - else if (bHuff) - { - nDeltaT = m_pHuffDecoder->ReadBits(unLogStrips); - } - else - { - m_pArithDecoder->DecodeInt(&nDeltaT, m_pIaitStats); - } - int nCurT = nT + nDeltaT; - - // symbol ID - unsigned int unSymID; - if (bHuff) - { - if (pSymCodeTab) - { - int nTemp; - m_pHuffDecoder->DecodeInt(&nTemp, pSymCodeTab); - unSymID = (unsigned int)nTemp; - } - else - { - unSymID = m_pHuffDecoder->ReadBits(unSymCodeLen); - } - } - else - { - unSymID = m_pArithDecoder->DecodeIAID(unSymCodeLen, m_pIaidStats); - } - - if (unSymID >= (unsigned int)nNumSyms) - { - } - else - { - // get the symbol bitmap - JBIG2Bitmap *pSymbolBitmap = NULL; - int nReadInt; - if (bRefine) - { - if (bHuff) - { - nReadInt = (int)m_pHuffDecoder->ReadBit(); - } - else - { - m_pArithDecoder->DecodeInt(&nReadInt, m_pIariStats); - } - } - else - { - nReadInt = 0; - } - - if (nReadInt) - { - int nRDW, nRDH, nRDX, nRDY, nBMSize; - if (bHuff) - { - m_pHuffDecoder->DecodeInt(&nRDW, pHuffRDWTable); - m_pHuffDecoder->DecodeInt(&nRDH, pHuffRDHTable); - m_pHuffDecoder->DecodeInt(&nRDX, pHuffRDXTable); - m_pHuffDecoder->DecodeInt(&nRDY, pHuffRDYTable); - m_pHuffDecoder->DecodeInt(&nBMSize, pHuffRSizeTable); - m_pHuffDecoder->Reset(); - m_pArithDecoder->Start(); - } - else - { - m_pArithDecoder->DecodeInt(&nRDW, m_pIardwStats); - m_pArithDecoder->DecodeInt(&nRDH, m_pIardhStats); - m_pArithDecoder->DecodeInt(&nRDX, m_pIardxStats); - m_pArithDecoder->DecodeInt(&nRDY, m_pIardyStats); - } - - int nRefDX = ((nRDW >= 0) ? nRDW : nRDW - 1) / 2 + nRDX; - int nRefDY = ((nRDH >= 0) ? nRDH : nRDH - 1) / 2 + nRDY; - - pSymbolBitmap = ReadGenericRefinementRegion(nRDW + ppSyms[unSymID]->GetWidth(), nRDH + ppSyms[unSymID]->GetHeight(), unTempl, false, ppSyms[unSymID], nRefDX, nRefDY, pnATx, pnATy); - } - else //~ do we need to use the bmSize value here (in Huffman mode)? - { - pSymbolBitmap = ppSyms[unSymID]; - } - - // combine the symbol bitmap into the region bitmap - //~ something is wrong here - refCorner shouldn't degenerate into - //~ two cases - unsigned int unBitmapW = pSymbolBitmap->GetWidth() - 1; - unsigned int unBitmapH = pSymbolBitmap->GetHeight() - 1; - if (transposed) - { - switch (refCorner) - { - case 0: // bottom left - pBitmap->Combine(pSymbolBitmap, nCurT, nCurS, unCombOp); - break; - case 1: // top left - pBitmap->Combine(pSymbolBitmap, nCurT, nCurS, unCombOp); - break; - case 2: // bottom right - pBitmap->Combine(pSymbolBitmap, nCurT - unBitmapW, nCurS, unCombOp); - break; - case 3: // top right - pBitmap->Combine(pSymbolBitmap, nCurT - unBitmapW, nCurS, unCombOp); - break; - } - nCurS += unBitmapH; - } - else - { - switch (refCorner) - { - case 0: // bottom left - pBitmap->Combine(pSymbolBitmap, nCurS, nCurT - unBitmapH, unCombOp); - break; - case 1: // top left - pBitmap->Combine(pSymbolBitmap, nCurS, nCurT, unCombOp); - break; - case 2: // bottom right - pBitmap->Combine(pSymbolBitmap, nCurS, nCurT - unBitmapH, unCombOp); - break; - case 3: // top right - pBitmap->Combine(pSymbolBitmap, nCurS, nCurT, unCombOp); - break; - } - nCurS += unBitmapW; - } - - if (nReadInt) - { - delete pSymbolBitmap; - } - } - - // next instance - ++unInstance; - - // next S value - if (bHuff) - { - if (!m_pHuffDecoder->DecodeInt(&nDS, pHuffDSTable)) - { - break; - } - } - else - { - if (!m_pArithDecoder->DecodeInt(&nDS, m_pIadsStats)) - { - break; - } - } - nCurS += nSOffset + nDS; - } - } - - return pBitmap; - } - - void JBIG2Stream::ReadPatternDictSegment(unsigned int unSegNum, unsigned int unLength) - { - // halftone dictionary flags, pattern width and height, max gray value - unsigned int unFlags, unPatternW, unPatternH, unGrayMax; - if (!ReadUByte(&unFlags) || !ReadUByte(&unPatternW) || !ReadUByte(&unPatternH) || !ReadULong(&unGrayMax)) - { - return; - } - unsigned int unTempl = (unFlags >> 1) & 3; - unsigned int unMMR = unFlags & 1; - - // set up the arithmetic decoder - if (!unMMR) - { - ResetGenericStats(unTempl, NULL); - m_pArithDecoder->Start(); - } - - // read the bitmap - int arrATx[4], arrATy[4]; - arrATx[0] = -(int)unPatternW; arrATy[0] = 0; - arrATx[1] = -3; arrATy[1] = -1; - arrATx[2] = 2; arrATy[2] = -2; - arrATx[3] = -2; arrATy[3] = -2; - JBIG2Bitmap *pBitmap = ReadGenericBitmap(unMMR ? true : false, (unGrayMax + 1) * unPatternW, unPatternH, unTempl, false, false, NULL, arrATx, arrATy, unLength - 7); - - // create the pattern dict object - JBIG2PatternDict *pPatternDict = new JBIG2PatternDict(unSegNum, unGrayMax + 1); - - // split up the bitmap - unsigned int unX = 0; - for (unsigned int unIndex = 0; unIndex <= unGrayMax; ++unIndex) - { - pPatternDict->SetBitmap(unIndex, pBitmap->GetSlice(unX, 0, unPatternW, unPatternH)); - unX += unPatternW; - } - - // free memory - delete pBitmap; - - // store the new pattern dict - m_pSegments->Append(pPatternDict); - - return; - } - - void JBIG2Stream::ReadHalftoneRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount) - { - // region segment info field - unsigned int unW, unH, unX, unY, unSegInfoFlags; - if (!ReadULong(&unW) || !ReadULong(&unH) || !ReadULong(&unX) || !ReadULong(&unY) || !ReadUByte(&unSegInfoFlags)) - { - return; - } - unsigned int unExtCombOp = unSegInfoFlags & 7; - - // rest of the halftone region header - unsigned int unFlags; - if (!ReadUByte(&unFlags)) - { - return; - } - unsigned int unMMR = unFlags & 1; - unsigned int unTempl = (unFlags >> 1) & 3; - unsigned int unEnableSkip = (unFlags >> 3) & 1; - unsigned int unCombOp = (unFlags >> 4) & 7; - - unsigned int unGridW, unGridH, unStepX, unStepY; - int nGridX, nGridY; - if (!ReadULong(&unGridW) || !ReadULong(&unGridH) || !ReadLong(&nGridX) || !ReadLong(&nGridY) || !ReadUWord(&unStepX) || !ReadUWord(&unStepY)) - { - return; - } - if (unW == 0 || unH == 0 || unW >= INT_MAX / unH) - { - return; - } - if (unGridH == 0 || unGridW >= INT_MAX / unGridH) - { - return; - } - - // get pattern dictionary - if (unRefSegsCount != 1) - { - return; - } - - JBIG2Segment *pSegment = FindSegment(punRefSegs[0]); - if (pSegment->GetType() != jbig2SegPatternDict) - { - return; - } - JBIG2PatternDict *pPatternDict = (JBIG2PatternDict *)pSegment; - - unsigned int unBPP = 0; - unsigned int unIndex = 1; - while (unIndex < pPatternDict->GetSize()) - { - ++unBPP; - unIndex <<= 1; - } - - unsigned int unPatternW = pPatternDict->GetBitmap(0)->GetWidth(); - unsigned int unPatternH = pPatternDict->GetBitmap(0)->GetHeight(); - - // set up the arithmetic decoder - if (!unMMR) - { - ResetGenericStats(unTempl, NULL); - m_pArithDecoder->Start(); - } - - // allocate the bitmap - JBIG2Bitmap *pBitmap = new JBIG2Bitmap(unSegNum, unW, unH); - if (unFlags & 0x80) // HDEFPIXEL - { - pBitmap->ClearToOne(); - } - else - { - pBitmap->ClearToZero(); - } - - // compute the skip bitmap - JBIG2Bitmap *pSkipBitmap = NULL; - if (unEnableSkip) - { - pSkipBitmap = new JBIG2Bitmap(0, unGridW, unGridH); - pSkipBitmap->ClearToZero(); - - for (unsigned int unM = 0; unM < unGridH; ++unM) - { - for (unsigned int unN = 0; unN < unGridW; ++unN) - { - int nCurX = nGridX + unM * unStepY + unN * unStepX; - int nCurY = nGridY + unM * unStepX - unN * unStepY; - if (((nCurX + (int)unPatternW) >> 8) <= 0 || (nCurX >> 8) >= (int)unW || ((nCurY + (int)unPatternH) >> 8) <= 0 || (nCurY >> 8) >= (int)unH) - { - pSkipBitmap->SetPixel(unN, unM); - } - } - } - } - - // read the gray-scale image - unsigned int *pGrayImage = (unsigned int *)MemUtilsMallocArray(unGridW * unGridH, sizeof(unsigned int)); - memset(pGrayImage, 0, unGridW * unGridH * sizeof(unsigned int)); - - int arrATx[4], arrATy[4]; - arrATx[0] = unTempl <= 1 ? 3 : 2; arrATy[0] = -1; - arrATx[1] = -3; arrATy[1] = -1; - arrATx[2] = 2; arrATy[2] = -2; - arrATx[3] = -2; arrATy[3] = -2; - - for (int nBitIndex = unBPP - 1; nBitIndex >= 0; --nBitIndex) - { - JBIG2Bitmap *pGrayBitmap = ReadGenericBitmap(0 != unMMR, unGridW, unGridH, unTempl, false, 0 != unEnableSkip, pSkipBitmap, arrATx, arrATy, -1); - unIndex = 0; - for (unsigned int unM = 0; unM < unGridH; ++unM) - { - for (unsigned int unN = 0; unN < unGridW; ++unN) - { - int nBit = pGrayBitmap->GetPixel(unN, unM) ^ (pGrayImage[unIndex] & 1); - pGrayImage[unIndex] = (pGrayImage[unIndex] << 1) | nBit; - ++unIndex; - } - } - delete pGrayBitmap; - } - - // decode the image - unIndex = 0; - for (unsigned int unM = 0; unM < unGridH; ++unM) - { - int nCurX = nGridX + unM * unStepY; - int nCurY = nGridY + unM * unStepX; - for (unsigned int unN = 0; unN < unGridW; ++unN) - { - if (!(unEnableSkip && pSkipBitmap->GetPixel(unN, unM))) - { - JBIG2Bitmap *pPatternBitmap = pPatternDict->GetBitmap(pGrayImage[unIndex]); - pBitmap->Combine(pPatternBitmap, nCurX >> 8, nCurY >> 8, unCombOp); - } - nCurX += unStepX; - nCurY -= unStepY; - ++unIndex; - } - } - - MemUtilsFree(pGrayImage); - if (pSkipBitmap) - { - delete pSkipBitmap; - } - - // combine the region bitmap into the page bitmap - if (bImm) - { - if (m_unPageH == 0xffffffff && unY + unH > m_unCurPageH) - { - m_pPageBitmap->Expand(unY + unH, m_unPageDefPixel); - } - m_pPageBitmap->Combine(pBitmap, unX, unY, unExtCombOp); - delete pBitmap; - } - else // store the region bitmap - { - m_pSegments->Append(pBitmap); - } - - return; - } - - void JBIG2Stream::ReadGenericRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength) - { - // region segment info field - unsigned int unW, unH, unX, unY, unSegInfoFlags; - if (!ReadULong(&unW) || !ReadULong(&unH) || !ReadULong(&unX) || !ReadULong(&unY) || !ReadUByte(&unSegInfoFlags)) - { - return; - } - unsigned int unExtCombOp = unSegInfoFlags & 7; - - // rest of the generic region segment header - unsigned int unFlags; - if (!ReadUByte(&unFlags)) - { - return; - } - unsigned int unMMR = unFlags & 1; - unsigned int unTempl = (unFlags >> 1) & 3; - unsigned int unTpgdOn = (unFlags >> 3) & 1; - - // AT flags - int arrATx[4], arrATy[4]; - if (!unMMR) - { - if (unTempl == 0) - { - if (!ReadByte(&arrATx[0]) || !ReadByte(&arrATy[0]) || !ReadByte(&arrATx[1]) || !ReadByte(&arrATy[1]) || - !ReadByte(&arrATx[2]) || !ReadByte(&arrATy[2]) || !ReadByte(&arrATx[3]) || !ReadByte(&arrATy[3])) - { - return; - } - } - else - { - if (!ReadByte(&arrATx[0]) || !ReadByte(&arrATy[0])) - { - return; - } - } - } - - // set up the arithmetic decoder - if (!unMMR) - { - ResetGenericStats(unTempl, NULL); - m_pArithDecoder->Start(); - } - - // read the bitmap - JBIG2Bitmap *pBitmap = ReadGenericBitmap(0 != unMMR, unW, unH, unTempl, 0 != unTpgdOn, false, NULL, arrATx, arrATy, unMMR ? 0 : unLength - 18); - - // combine the region bitmap into the page bitmap - if (bImm) - { - if (m_unPageH == 0xffffffff && unY + unH > m_unCurPageH) - { - m_pPageBitmap->Expand(unY + unH, m_unPageDefPixel); - } - m_pPageBitmap->Combine(pBitmap, unX, unY, unExtCombOp); - delete pBitmap; - } - else // store the region bitmap - { - pBitmap->SetSegNum(unSegNum); - m_pSegments->Append(pBitmap); - } - - return; - } - - JBIG2Bitmap *JBIG2Stream::ReadGenericBitmap(bool bMMR, int nW, int nH, int unTempl, bool bTpgdOn, bool bUseSkip, JBIG2Bitmap *pSkip, int *pnATx, int *pnATy, int nMMrDataLength) - { - JBIG2Bitmap *pBitmap = new JBIG2Bitmap(0, nW, nH); - pBitmap->ClearToZero(); - - if (bMMR) //----- MMR decode - { - m_pMMrDecoder->Reset(); - - int *pRefLine = (int *)MemUtilsMallocArray(nW + 2, sizeof(int)); - int *pCodingLine = (int *)MemUtilsMallocArray(nW + 2, sizeof(int)); - - pCodingLine[0] = pCodingLine[1] = nW; - - for (int nY = 0; nY < nH; ++nY) - { - // copy coding line to ref line - int nIndex; - for (nIndex = 0; pCodingLine[nIndex] < nW; ++nIndex) - { - pRefLine[nIndex] = pCodingLine[nIndex]; - } - pRefLine[nIndex] = pRefLine[nIndex + 1] = nW; - - // decode a line - int nRefIndex = 0; // nB1 = pRefLine[refI] - int nCodingIndex = 0; // nA1 = pCodingLine[codingI] - int nA0 = 0; - - do - { - int nCode1 = m_pMMrDecoder->Get2DCode(); - switch (nCode1) - { - case Pass_2D: - - if (pRefLine[nRefIndex] < nW) - { - nA0 = pRefLine[nRefIndex + 1]; - nRefIndex += 2; - } - break; - - case Horiz_2D: - - { - int nCode2, nCode3; - - if (nCodingIndex & 1) - { - nCode1 = 0; - do - { - nCode1 += nCode3 = m_pMMrDecoder->GetBlackCode(); - } while (nCode3 >= 64); - - nCode2 = 0; - do - { - nCode2 += nCode3 = m_pMMrDecoder->GetWhiteCode(); - } while (nCode3 >= 64); - } - else - { - nCode1 = 0; - do - { - nCode1 += nCode3 = m_pMMrDecoder->GetWhiteCode(); - } while (nCode3 >= 64); - - nCode2 = 0; - do - { - nCode2 += nCode3 = m_pMMrDecoder->GetBlackCode(); - } while (nCode3 >= 64); - } - if (nCode1 > 0 || nCode2 > 0) - { - nA0 = pCodingLine[nCodingIndex++] = nA0 + nCode1; - nA0 = pCodingLine[nCodingIndex++] = nA0 + nCode2; - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - } - } - break; - - case Vert0_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex]; - if (pRefLine[nRefIndex] < nW) - { - ++nRefIndex; - } - break; - - case VertR1_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] + 1; - if (pRefLine[nRefIndex] < nW) - { - ++nRefIndex; - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - } - break; - - case VertR2_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] + 2; - if (pRefLine[nRefIndex] < nW) - { - ++nRefIndex; - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - } - break; - - case VertR3_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] + 3; - if (pRefLine[nRefIndex] < nW) - { - ++nRefIndex; - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - } - break; - - case VertL1_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] - 1; - if (nRefIndex > 0) - { - --nRefIndex; - } - else - { - ++nRefIndex; - } - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - break; - - case VertL2_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] - 2; - if (nRefIndex > 0) - { - --nRefIndex; - } - else - { - ++nRefIndex; - } - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - break; - - case VertL3_2D: - - nA0 = pCodingLine[nCodingIndex++] = pRefLine[nRefIndex] - 3; - if (nRefIndex > 0) - { - --nRefIndex; - } - else - { - ++nRefIndex; - } - while (pRefLine[nRefIndex] <= nA0 && pRefLine[nRefIndex] < nW) - { - nRefIndex += 2; - } - break; - - default: - - break; - - } - } while (nA0 < nW); - pCodingLine[nCodingIndex++] = nW; - - // convert the run lengths to a bitmap line - nIndex = 0; - while (pCodingLine[nIndex] < nW) - { - for (int nX = pCodingLine[nIndex]; nX < pCodingLine[nIndex + 1]; ++nX) - { - pBitmap->SetPixel(nX, nY); - } - nIndex += 2; - } - } - - if (nMMrDataLength >= 0) - { - m_pMMrDecoder->SkipTo(nMMrDataLength); - } - else - { - if (m_pMMrDecoder->Get24Bits() != 0x001001) - { - } - } - - MemUtilsFree(pRefLine); - MemUtilsFree(pCodingLine); - } - else //----- arithmetic decode - { - // set up the typical row context - unsigned int unLtpCX = 0; - if (bTpgdOn) - { - switch (unTempl) - { - case 0: - unLtpCX = 0x3953; // 001 11001 0101 0011 - break; - case 1: - unLtpCX = 0x079a; // 0011 11001 101 0 - break; - case 2: - unLtpCX = 0x0e3; // 001 1100 01 1 - break; - case 3: - unLtpCX = 0x18a; // 01100 0101 1 - break; - } - } - - bool bLtp = 0; - unsigned int unCX = 0, unCX0 = 0, unCX1 = 0, unCX2 = 0; - JBIG2BitmapPtr oCXPtr0, oCXPtr1; - JBIG2BitmapPtr oATPtr0, oATPtr1, oATPtr2, oATPtr3; - - for (int nY = 0; nY < nH; ++nY) - { - // check for a "typical" (duplicate) row - if (bTpgdOn) - { - if (m_pArithDecoder->DecodeBit(unLtpCX, m_pGenericRegionStats)) - { - bLtp = !bLtp; - } - if (bLtp) - { - if (nY > 0) - pBitmap->DuplicateRow(nY, nY - 1); - continue; - } - } - - switch (unTempl) - { - case 0: - - // set up the context - pBitmap->GetPixelPtr(0, nY - 2, &oCXPtr0); - unCX0 = pBitmap->NextPixel(&oCXPtr0); - unCX0 = (unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0); - - pBitmap->GetPixelPtr(0, nY - 1, &oCXPtr1); - unCX1 = pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - - unCX2 = 0; - pBitmap->GetPixelPtr(pnATx[0], nY + pnATy[0], &oATPtr0); - pBitmap->GetPixelPtr(pnATx[1], nY + pnATy[1], &oATPtr1); - pBitmap->GetPixelPtr(pnATx[2], nY + pnATy[2], &oATPtr2); - pBitmap->GetPixelPtr(pnATx[3], nY + pnATy[3], &oATPtr3); - - // decode the row - for (int nX = 0; nX < nW; ++nX) - { - // build the context - unCX = (unCX0 << 13) | (unCX1 << 8) | (unCX2 << 4) | (pBitmap->NextPixel(&oATPtr0) << 3) | (pBitmap->NextPixel(&oATPtr1) << 2) | (pBitmap->NextPixel(&oATPtr2) << 1) | pBitmap->NextPixel(&oATPtr3); - - int nPixel; - if (bUseSkip && pSkip->GetPixel(nX, nY)) // check for a skipped pixel - { - nPixel = 0; - } - else if ((nPixel = m_pArithDecoder->DecodeBit(unCX, m_pGenericRegionStats))) // decode the pixel - { - pBitmap->SetPixel(nX, nY); - } - - // update the context - unCX0 = ((unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0)) & 0x07; - unCX1 = ((unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1)) & 0x1f; - unCX2 = ((unCX2 << 1) | nPixel) & 0x0f; - } - break; - - case 1: - - // set up the context - pBitmap->GetPixelPtr(0, nY - 2, &oCXPtr0); - unCX0 = pBitmap->NextPixel(&oCXPtr0); - unCX0 = (unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0); - unCX0 = (unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0); - - pBitmap->GetPixelPtr(0, nY - 1, &oCXPtr1); - unCX1 = pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - unCX2 = 0; - - pBitmap->GetPixelPtr(pnATx[0], nY + pnATy[0], &oATPtr0); - - // decode the row - for (int nX = 0; nX < nW; ++nX) - { - // build the context - unCX = (unCX0 << 9) | (unCX1 << 4) | (unCX2 << 1) | pBitmap->NextPixel(&oATPtr0); - - int nPixel; - if (bUseSkip && pSkip->GetPixel(nX, nY)) // check for a skipped pixel - { - nPixel = 0; - } - else if ((nPixel = m_pArithDecoder->DecodeBit(unCX, m_pGenericRegionStats))) // decode the pixel - { - pBitmap->SetPixel(nX, nY); - } - - // update the context - unCX0 = ((unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0)) & 0x0f; - unCX1 = ((unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1)) & 0x1f; - unCX2 = ((unCX2 << 1) | nPixel) & 0x07; - } - break; - - case 2: - - // set up the context - pBitmap->GetPixelPtr(0, nY - 2, &oCXPtr0); - unCX0 = pBitmap->NextPixel(&oCXPtr0); - unCX0 = (unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0); - - pBitmap->GetPixelPtr(0, nY - 1, &oCXPtr1); - unCX1 = pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - unCX2 = 0; - - pBitmap->GetPixelPtr(pnATx[0], nY + pnATy[0], &oATPtr0); - - // decode the row - for (int nX = 0; nX < nW; ++nX) - { - - // build the context - unCX = (unCX0 << 7) | (unCX1 << 3) | (unCX2 << 1) | pBitmap->NextPixel(&oATPtr0); - - int nPixel; - if (bUseSkip && pSkip->GetPixel(nX, nY)) // check for a skipped pixel - { - nPixel = 0; - } - else if ((nPixel = m_pArithDecoder->DecodeBit(unCX, m_pGenericRegionStats))) // decode the pixel - { - pBitmap->SetPixel(nX, nY); - } - - // update the context - unCX0 = ((unCX0 << 1) | pBitmap->NextPixel(&oCXPtr0)) & 0x07; - unCX1 = ((unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1)) & 0x0f; - unCX2 = ((unCX2 << 1) | nPixel) & 0x03; - } - break; - - case 3: - - // set up the context - pBitmap->GetPixelPtr(0, nY - 1, &oCXPtr1); - unCX1 = pBitmap->NextPixel(&oCXPtr1); - unCX1 = (unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1); - unCX2 = 0; - - pBitmap->GetPixelPtr(pnATx[0], nY + pnATy[0], &oATPtr0); - - // decode the row - for (int nX = 0; nX < nW; ++nX) - { - // build the context - unCX = (unCX1 << 5) | (unCX2 << 1) | pBitmap->NextPixel(&oATPtr0); - - int nPixel; - if (bUseSkip && pSkip->GetPixel(nX, nY)) // check for a skipped pixel - { - nPixel = 0; - } - else if ((nPixel = m_pArithDecoder->DecodeBit(unCX, m_pGenericRegionStats))) // decode the pixel - { - pBitmap->SetPixel(nX, nY); - } - // update the context - unCX1 = ((unCX1 << 1) | pBitmap->NextPixel(&oCXPtr1)) & 0x1f; - unCX2 = ((unCX2 << 1) | nPixel) & 0x0f; - } - break; - } - } - } - - return pBitmap; - } - - void JBIG2Stream::ReadGenericRefinementRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount) - { - unsigned int unW, unH, unX, unY, unSegInfoFlags; - - // region segment info field - if (!ReadULong(&unW) || !ReadULong(&unH) || !ReadULong(&unX) || !ReadULong(&unY) || !ReadUByte(&unSegInfoFlags)) - { - return; - } - unsigned int unExtCombOp = unSegInfoFlags & 7; - - // rest of the generic refinement region segment header - unsigned int unFlags; - if (!ReadUByte(&unFlags)) - { - return; - } - - unsigned int unTempl = unFlags & 1; - unsigned int unTpgrOn = (unFlags >> 1) & 1; - - // AT flags - int arrATx[2], arrATy[2]; - if (!unTempl) - { - if (!ReadByte(&arrATx[0]) || !ReadByte(&arrATy[0]) || !ReadByte(&arrATx[1]) || !ReadByte(&arrATy[1])) - { - return; - } - } - - // resize the page bitmap if needed - if (unRefSegsCount == 0 || bImm) - { - if (m_unPageH == 0xffffffff && unY + unH > m_unCurPageH) - { - m_pPageBitmap->Expand(unY + unH, m_unPageDefPixel); - } - } - - // get referenced bitmap - JBIG2Bitmap *pRefBitmap = NULL; - if (unRefSegsCount > 1) - { - return; - } - if (unRefSegsCount == 1) - { - JBIG2Segment *pSegment = FindSegment(punRefSegs[0]); - if (pSegment->GetType() != jbig2SegBitmap) - { - return; - } - pRefBitmap = (JBIG2Bitmap *)pSegment; - } - else - { - pRefBitmap = m_pPageBitmap->GetSlice(unX, unY, unW, unH); - } - - // set up the arithmetic decoder - ResetRefinementStats(unTempl, NULL); - m_pArithDecoder->Start(); - - // read - JBIG2Bitmap *pBitmap = ReadGenericRefinementRegion(unW, unH, unTempl, 0 != unTpgrOn, pRefBitmap, 0, 0, arrATx, arrATy); - - if (bImm) // combine the region bitmap into the page bitmap - { - m_pPageBitmap->Combine(pBitmap, unX, unY, unExtCombOp); - delete pBitmap; - } - else // store the region bitmap - { - pBitmap->SetSegNum(unSegNum); - m_pSegments->Append(pBitmap); - } - - // delete the referenced bitmap - if (unRefSegsCount == 1) - { - DiscardSegment(punRefSegs[0]); - } - else - { - delete pRefBitmap; - } - - return; - } - - JBIG2Bitmap *JBIG2Stream::ReadGenericRefinementRegion(int nW, int nH, int nTempl, bool bTpgrOn, JBIG2Bitmap *pRefBitmap, int nRefDX, int nRefDY, int *pnAtx, int *pnAty) - { - JBIG2Bitmap *pBitmap = new JBIG2Bitmap(0, nW, nH); - pBitmap->ClearToZero(); - - // Typical row context - unsigned int unLtpCX; - if (nTempl) - { - unLtpCX = 0x008; - } - else - { - unLtpCX = 0x0010; - } - - bool bLtp = 0; - unsigned int unCx0, unCx2, unCx3, unCx4; - JBIG2BitmapPtr oCxPtr0, oCxPtr1, oCxPtr2, oCxPtr3, oCxPtr4, oCxPtr5, oCxPtr6; - for (int nY = 0; nY < nH; ++nY) - { - if (nTempl) - { - // set up the context - pBitmap->GetPixelPtr(0, nY - 1, &oCxPtr0); - unCx0 = pBitmap->NextPixel(&oCxPtr0); - - pBitmap->GetPixelPtr(-1, nY, &oCxPtr1); - pRefBitmap->GetPixelPtr(-nRefDX, nY - 1 - nRefDY, &oCxPtr2); - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - nRefDY, &oCxPtr3); - - unCx3 = pRefBitmap->NextPixel(&oCxPtr3); - unCx3 = (unCx3 << 1) | pRefBitmap->NextPixel(&oCxPtr3); - - pRefBitmap->GetPixelPtr(-nRefDX, nY + 1 - nRefDY, &oCxPtr4); - unCx4 = pRefBitmap->NextPixel(&oCxPtr4); - - // set up the typical prediction context - unsigned int unTpgrCX0 = 0, unTpgrCX1 = 0, unTpgrCX2 = 0; - JBIG2BitmapPtr oTpgrCXPtr0, oTpgrCXPtr1, oTpgrCXPtr2; - if (bTpgrOn) - { - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - 1 - nRefDY, &oTpgrCXPtr0); - unTpgrCX0 = pRefBitmap->NextPixel(&oTpgrCXPtr0); - unTpgrCX0 = (unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0); - unTpgrCX0 = (unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - nRefDY, &oTpgrCXPtr1); - unTpgrCX1 = pRefBitmap->NextPixel(&oTpgrCXPtr1); - unTpgrCX1 = (unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1); - unTpgrCX1 = (unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY + 1 - nRefDY, &oTpgrCXPtr2); - unTpgrCX2 = pRefBitmap->NextPixel(&oTpgrCXPtr2); - unTpgrCX2 = (unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2); - unTpgrCX2 = (unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2); - } - - for (int nX = 0; nX < nW; ++nX) - { - - // update the context - unCx0 = ((unCx0 << 1) | pBitmap->NextPixel(&oCxPtr0)) & 7; - unCx3 = ((unCx3 << 1) | pRefBitmap->NextPixel(&oCxPtr3)) & 7; - unCx4 = ((unCx4 << 1) | pRefBitmap->NextPixel(&oCxPtr4)) & 3; - - if (bTpgrOn) - { - // update the typical predictor context - unTpgrCX0 = ((unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0)) & 7; - unTpgrCX1 = ((unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1)) & 7; - unTpgrCX2 = ((unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2)) & 7; - - // check for a "typical" pixel - if (m_pArithDecoder->DecodeBit(unLtpCX, m_pRefinementRegionStats)) - { - bLtp = !bLtp; - } - if (unTpgrCX0 == 0 && unTpgrCX1 == 0 && unTpgrCX2 == 0) - { - pBitmap->ClearPixel(nX, nY); - continue; - } - else if (unTpgrCX0 == 7 && unTpgrCX1 == 7 && unTpgrCX2 == 7) - { - pBitmap->SetPixel(nX, nY); - continue; - } - } - - // build the context - unsigned int unCx = (unCx0 << 7) | (pBitmap->NextPixel(&oCxPtr1) << 6) | (pRefBitmap->NextPixel(&oCxPtr2) << 5) | (unCx3 << 2) | unCx4; - - // decode the pixel - int nPix; - if ((nPix = m_pArithDecoder->DecodeBit(unCx, m_pRefinementRegionStats))) - { - pBitmap->SetPixel(nX, nY); - } - } - - } - else - { - - // set up the context - pBitmap->GetPixelPtr(0, nY - 1, &oCxPtr0); - unCx0 = pBitmap->NextPixel(&oCxPtr0); - - pBitmap->GetPixelPtr(-1, nY, &oCxPtr1); - - pRefBitmap->GetPixelPtr(-nRefDX, nY - 1 - nRefDY, &oCxPtr2); - unCx2 = pRefBitmap->NextPixel(&oCxPtr2); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - nRefDY, &oCxPtr3); - unCx3 = pRefBitmap->NextPixel(&oCxPtr3); - unCx3 = (unCx3 << 1) | pRefBitmap->NextPixel(&oCxPtr3); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY + 1 - nRefDY, &oCxPtr4); - unCx4 = pRefBitmap->NextPixel(&oCxPtr4); - unCx4 = (unCx4 << 1) | pRefBitmap->NextPixel(&oCxPtr4); - - pBitmap->GetPixelPtr(pnAtx[0], nY + pnAty[0], &oCxPtr5); - - pRefBitmap->GetPixelPtr(pnAtx[1] - nRefDX, nY + pnAty[1] - nRefDY, &oCxPtr6); - - // set up the typical prediction context - unsigned int unTpgrCX0 = 0, unTpgrCX1 = 0, unTpgrCX2 = 0; - JBIG2BitmapPtr oTpgrCXPtr0, oTpgrCXPtr1, oTpgrCXPtr2; - if (bTpgrOn) - { - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - 1 - nRefDY, &oTpgrCXPtr0); - unTpgrCX0 = pRefBitmap->NextPixel(&oTpgrCXPtr0); - unTpgrCX0 = (unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0); - unTpgrCX0 = (unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY - nRefDY, &oTpgrCXPtr1); - unTpgrCX1 = pRefBitmap->NextPixel(&oTpgrCXPtr1); - unTpgrCX1 = (unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1); - unTpgrCX1 = (unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1); - - pRefBitmap->GetPixelPtr(-1 - nRefDX, nY + 1 - nRefDY, &oTpgrCXPtr2); - unTpgrCX2 = pRefBitmap->NextPixel(&oTpgrCXPtr2); - unTpgrCX2 = (unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2); - unTpgrCX2 = (unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2); - } - - for (int nX = 0; nX < nW; ++nX) - { - - // update the context - unCx0 = ((unCx0 << 1) | pBitmap->NextPixel(&oCxPtr0)) & 3; - unCx2 = ((unCx2 << 1) | pRefBitmap->NextPixel(&oCxPtr2)) & 3; - unCx3 = ((unCx3 << 1) | pRefBitmap->NextPixel(&oCxPtr3)) & 7; - unCx4 = ((unCx4 << 1) | pRefBitmap->NextPixel(&oCxPtr4)) & 7; - - if (bTpgrOn) - { - // update the typical predictor context - unTpgrCX0 = ((unTpgrCX0 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr0)) & 7; - unTpgrCX1 = ((unTpgrCX1 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr1)) & 7; - unTpgrCX2 = ((unTpgrCX2 << 1) | pRefBitmap->NextPixel(&oTpgrCXPtr2)) & 7; - - // check for a "typical" pixel - if (m_pArithDecoder->DecodeBit(unLtpCX, m_pRefinementRegionStats)) - { - bLtp = !bLtp; - } - if (unTpgrCX0 == 0 && unTpgrCX1 == 0 && unTpgrCX2 == 0) - { - pBitmap->ClearPixel(nX, nY); - continue; - } - else if (unTpgrCX0 == 7 && unTpgrCX1 == 7 && unTpgrCX2 == 7) - { - pBitmap->SetPixel(nX, nY); - continue; - } - } - - // build the context - unsigned int unCx = (unCx0 << 11) | (pBitmap->NextPixel(&oCxPtr1) << 10) | (unCx2 << 8) | (unCx3 << 5) | (unCx4 << 2) | (pBitmap->NextPixel(&oCxPtr5) << 1) | pRefBitmap->NextPixel(&oCxPtr6); - - // decode the pixel - int nPix; - if ((nPix = m_pArithDecoder->DecodeBit(unCx, m_pRefinementRegionStats))) - { - pBitmap->SetPixel(nX, nY); - } - } - } - } - - return pBitmap; - } - - void JBIG2Stream::ReadPageInfoSegment(unsigned int unLength) - { - unsigned int unResX, unResY, unFlags, unStriping; - - if (!ReadULong(&m_unPageW) || !ReadULong(&m_unPageH) || !ReadULong(&unResX) || !ReadULong(&unResY) || !ReadUByte(&unFlags) || !ReadUWord(&unStriping)) - { - return; - } - m_unPageDefPixel = (unFlags >> 2) & 1; - m_unDefCombOp = (unFlags >> 3) & 3; - - if (0xffffffff == m_unPageH) - { - m_unCurPageH = unStriping & 0x7fff; - } - else - { - m_unCurPageH = m_unPageH; - } - m_pPageBitmap = new JBIG2Bitmap(0, m_unPageW, m_unPageH); - - // Очищаем картинку - if (m_unPageDefPixel) - { - m_pPageBitmap->ClearToOne(); - } - else - { - m_pPageBitmap->ClearToZero(); - } - - return; - } - - void JBIG2Stream::ReadEndOfStripeSegment(unsigned int unLength) - { - // Пропускаем данный сегмент - for (unsigned int unIndex = 0; unIndex < unLength; ++unIndex) - { - m_pCurStream->GetChar(); - } - } - - void JBIG2Stream::ReadProfilesSegment(unsigned int unLength) - { - // Пропускаем данный сегмент - for (unsigned int unIndex = 0; unIndex < unLength; ++unIndex) - { - m_pCurStream->GetChar(); - } - } - void JBIG2Stream::ReadCodeTableSegment(unsigned int unSegNum, unsigned int unLength) - { - unsigned int unFlags; - int nLowVal, nHighVal; - if (!ReadUByte(&unFlags) || !ReadLong(&nLowVal) || !ReadLong(&nHighVal)) - { - return; - } - unsigned int unOOB = unFlags & 1; - unsigned int unPrefixBits = ((unFlags >> 1) & 7) + 1; - unsigned int unRangeBits = ((unFlags >> 4) & 7) + 1; - - m_pHuffDecoder->Reset(); - - unsigned int unHuffTabSize = 8; - JBIG2HuffmanTable *pHuffTable = (JBIG2HuffmanTable *)MemUtilsMallocArray(unHuffTabSize, sizeof(JBIG2HuffmanTable)); - - unsigned int unIndex = 0; - int nVal = nLowVal; - while (nVal < nHighVal) - { - if (unIndex == unHuffTabSize) - { - unHuffTabSize *= 2; - pHuffTable = (JBIG2HuffmanTable *)MemUtilsReallocArray(pHuffTable, unHuffTabSize, sizeof(JBIG2HuffmanTable)); - } - pHuffTable[unIndex].nValue = nVal; - pHuffTable[unIndex].unPrefixLen = m_pHuffDecoder->ReadBits(unPrefixBits); - pHuffTable[unIndex].unRangeLen = m_pHuffDecoder->ReadBits(unRangeBits); - nVal += 1 << pHuffTable[unIndex].unRangeLen; - ++unIndex; - } - if (unIndex + unOOB + 3 > unHuffTabSize) - { - unHuffTabSize = unIndex + unOOB + 3; - pHuffTable = (JBIG2HuffmanTable *)MemUtilsReallocArray(pHuffTable, unHuffTabSize, sizeof(JBIG2HuffmanTable)); - } - pHuffTable[unIndex].nValue = nLowVal - 1; - pHuffTable[unIndex].unPrefixLen = m_pHuffDecoder->ReadBits(unPrefixBits); - pHuffTable[unIndex].unRangeLen = jbig2HuffmanLOW; - ++unIndex; - - pHuffTable[unIndex].nValue = nHighVal; - pHuffTable[unIndex].unPrefixLen = m_pHuffDecoder->ReadBits(unPrefixBits); - pHuffTable[unIndex].unRangeLen = 32; - ++unIndex; - - if (unOOB) - { - pHuffTable[unIndex].nValue = 0; - pHuffTable[unIndex].unPrefixLen = m_pHuffDecoder->ReadBits(unPrefixBits); - pHuffTable[unIndex].unRangeLen = jbig2HuffmanOOB; - ++unIndex; - } - - pHuffTable[unIndex].nValue = 0; - pHuffTable[unIndex].unPrefixLen = 0; - pHuffTable[unIndex].unRangeLen = jbig2HuffmanEOT; - m_pHuffDecoder->BuildTable(pHuffTable, unIndex); - - // Создаем и сохраняем новый сегмент таблицы - m_pSegments->Append(new JBIG2CodeTable(unSegNum, pHuffTable)); - - return; - } - - void JBIG2Stream::ReadExtensionSegment(unsigned int unLength) - { - // Пропускаем данный сегмент - for (unsigned int unIndex = 0; unIndex < unLength; ++unIndex) - { - m_pCurStream->GetChar(); - } - } - - JBIG2Segment *JBIG2Stream::FindSegment(unsigned int unSegNum) - { - JBIG2Segment *pSegment = NULL; - - for (int nIndex = 0; nIndex < m_pGlobalSegments->GetLength(); ++nIndex) - { - pSegment = (JBIG2Segment *)m_pGlobalSegments->GetByIndex(nIndex); - if (pSegment->GetSegNum() == unSegNum) - { - return pSegment; - } - } - - for (int nIndex = 0; nIndex < m_pSegments->GetLength(); ++nIndex) - { - pSegment = (JBIG2Segment *)m_pSegments->GetByIndex(nIndex); - if (pSegment->GetSegNum() == unSegNum) - { - return pSegment; - } - } - - return NULL; - } - - void JBIG2Stream::DiscardSegment(unsigned int unSegNum) - { - JBIG2Segment *pSegment = NULL; - - for (int nIndex = 0; nIndex < m_pGlobalSegments->GetLength(); ++nIndex) - { - pSegment = (JBIG2Segment *)m_pGlobalSegments->GetByIndex(nIndex); - if (pSegment->GetSegNum() == unSegNum) - { - m_pGlobalSegments->Delete(nIndex); - return; - } - } - for (int nIndex = 0; nIndex < m_pSegments->GetLength(); ++nIndex) - { - pSegment = (JBIG2Segment *)m_pSegments->GetByIndex(nIndex); - if (pSegment->GetSegNum() == unSegNum) - { - m_pSegments->Delete(nIndex); - return; - } - } - } - - void JBIG2Stream::ResetGenericStats(unsigned int unTempl, JArithmeticDecoderStats *pPrevStats) - { - int nSize = c_arrContextSize[unTempl]; - if (pPrevStats && pPrevStats->GetContextSize() == nSize) - { - if (m_pGenericRegionStats->GetContextSize() == nSize) - { - m_pGenericRegionStats->CopyFrom(pPrevStats); - } - else - { - delete m_pGenericRegionStats; - m_pGenericRegionStats = pPrevStats->Copy(); - } - } - else - { - if (m_pGenericRegionStats->GetContextSize() == nSize) - { - m_pGenericRegionStats->Reset(); - } - else - { - delete m_pGenericRegionStats; - m_pGenericRegionStats = new JArithmeticDecoderStats(1 << nSize); - } - } - } - - void JBIG2Stream::ResetRefinementStats(unsigned int unTempl, JArithmeticDecoderStats *pPrevStats) - { - int nSize = c_arrRefContextSize[unTempl]; - if (pPrevStats && pPrevStats->GetContextSize() == nSize) - { - if (m_pRefinementRegionStats->GetContextSize() == nSize) - { - m_pRefinementRegionStats->CopyFrom(pPrevStats); - } - else - { - delete m_pRefinementRegionStats; - m_pRefinementRegionStats = pPrevStats->Copy(); - } - } - else - { - if (m_pRefinementRegionStats->GetContextSize() == nSize) - { - m_pRefinementRegionStats->Reset(); - } - else - { - delete m_pRefinementRegionStats; - m_pRefinementRegionStats = new JArithmeticDecoderStats(1 << nSize); - } - } - } - - void JBIG2Stream::ResetIntStats(int nSymCodeLen) - { - m_pIadhStats->Reset(); - m_pIadwStats->Reset(); - m_pIaexStats->Reset(); - m_pIaaiStats->Reset(); - m_pIadtStats->Reset(); - m_pIaitStats->Reset(); - m_pIafsStats->Reset(); - m_pIadsStats->Reset(); - m_pIardxStats->Reset(); - m_pIardyStats->Reset(); - m_pIardwStats->Reset(); - m_pIardhStats->Reset(); - m_pIariStats->Reset(); - - if (m_pIaidStats->GetContextSize() == 1 << (nSymCodeLen + 1)) - { - m_pIaidStats->Reset(); - } - else - { - delete m_pIaidStats; - m_pIaidStats = new JArithmeticDecoderStats(1 << (nSymCodeLen + 1)); - } - } - - bool JBIG2Stream::ReadUByte(unsigned int *pBuffer) - { - int nChar; - - if (EOF == (nChar = m_pCurStream->GetChar())) - { - return false; - } - *pBuffer = (unsigned int)nChar; - - return true; - } - - bool JBIG2Stream::ReadByte(int *pBuffer) - { - int nChar; - - if (EOF == (nChar = m_pCurStream->GetChar())) - { - return false; - } - - *pBuffer = nChar; - if (nChar & 0x80) - { - *pBuffer |= -1 - 0xff; - } - - return true; - } - - bool JBIG2Stream::ReadUWord(unsigned int *pBuffer) - { - int nChar0, nChar1; - - if (EOF == (nChar0 = m_pCurStream->GetChar()) || EOF == (nChar1 = m_pCurStream->GetChar())) - { - return false; - } - - *pBuffer = (unsigned int)((nChar0 << 8) | nChar1); - - return true; - } - - bool JBIG2Stream::ReadULong(unsigned int *pBuffer) - { - int nChar0, nChar1, nChar2, nChar3; - - if (EOF == (nChar0 = m_pCurStream->GetChar()) || EOF == (nChar1 = m_pCurStream->GetChar()) || - EOF == (nChar2 = m_pCurStream->GetChar()) || EOF == (nChar3 = m_pCurStream->GetChar())) - { - return false; - } - - *pBuffer = (unsigned int)((nChar0 << 24) | (nChar1 << 16) | (nChar2 << 8) | nChar3); - - return true; - } - - bool JBIG2Stream::ReadLong(int *pBuffer) - { - int nChar0, nChar1, nChar2, nChar3; - - if (EOF == (nChar0 = m_pCurStream->GetChar()) || EOF == (nChar1 = m_pCurStream->GetChar()) || - EOF == (nChar2 = m_pCurStream->GetChar()) || EOF == (nChar3 = m_pCurStream->GetChar())) - { - return false; - } - - *pBuffer = ((nChar0 << 24) | (nChar1 << 16) | (nChar2 << 8) | nChar3); - if (nChar0 & 0x80) - { - *pBuffer |= -1 - (int)0xffffffff; - } - - return true; - } -} diff --git a/PdfReader/old/JBIG2Stream.h b/PdfReader/old/JBIG2Stream.h deleted file mode 100644 index 69d300ff3b..0000000000 --- a/PdfReader/old/JBIG2Stream.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_JBIG2STREAM_H -#define _PDF_READER_JBIG2STREAM_H - -#include "Object.h" -#include "Stream.h" - -namespace PdfReader -{ - class CList; - class JBIG2Segment; - class JBIG2Bitmap; - class JArithmeticDecoder; - class JArithmeticDecoderStats; - class JBIG2HuffmanDecoder; - struct JBIG2HuffmanTable; - class JBIG2MMRDecoder; - - //------------------------------------------------------------------------ - - class JBIG2Stream : public FilterStream - { - public: - - JBIG2Stream(Stream *pStream, Object *pGlobalsStream); - virtual ~JBIG2Stream(); - virtual StreamType GetType() - { - return strJBIG2; - } - virtual void Reset(); - virtual void Close(); - virtual int GetChar(); - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - void ReadSegments(); - bool ReadSymbolDictSegment(unsigned int unSegNum, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount); - void ReadTextRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount); - JBIG2Bitmap *ReadTextRegion(bool bHuff, bool bRefine, int nW, int nH, unsigned int nNumInstances, unsigned int unLogStrips, int nNumSyms, JBIG2HuffmanTable *pSymCodeTab, unsigned int unSymCodeLen, JBIG2Bitmap **ppSyms, unsigned int unDefPixel, unsigned int unCombOp, unsigned int unTransposed, unsigned int unRefCorner, int nSOffset, JBIG2HuffmanTable *pHuffFSTable, JBIG2HuffmanTable *pHuffDSTable, JBIG2HuffmanTable *pHuffDTTable, JBIG2HuffmanTable *pHuffRDWTable, JBIG2HuffmanTable *pHuffRDHTable, JBIG2HuffmanTable *pHuffRDXTable, JBIG2HuffmanTable *pHuffRDYTable, JBIG2HuffmanTable *pHuffRSizeTable, unsigned int unTempl, int *pnATx, int *pnATy); - void ReadPatternDictSegment(unsigned int unSegNum, unsigned int unLength); - void ReadHalftoneRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount); - void ReadGenericRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength); - JBIG2Bitmap *ReadGenericBitmap(bool bMMr, int nW, int nH, int unTempl, bool bTpgdOn, bool bUseSkip, JBIG2Bitmap *pSkip, int *pATx, int *pATy, int nMMrDataLength); - void ReadGenericRefinementRegionSegment(unsigned int unSegNum, bool bImm, bool bLossless, unsigned int unLength, unsigned int *punRefSegs, unsigned int unRefSegsCount); - JBIG2Bitmap *ReadGenericRefinementRegion(int nW, int nH, int nTempl, bool bTpgrOn, JBIG2Bitmap *pRefBitmap, int nRefDX, int nRefDY, int *pnAtx, int *pnAty); - - void ReadPageInfoSegment(unsigned int unLength); - void ReadEndOfStripeSegment(unsigned int unLength); - void ReadProfilesSegment(unsigned int unLength); - void ReadCodeTableSegment(unsigned int unSegNum, unsigned int unLength); - void ReadExtensionSegment(unsigned int unLength); - - JBIG2Segment *FindSegment(unsigned int unSegNum); - void DiscardSegment(unsigned int unSegNum); - - void ResetGenericStats(unsigned int unTempl, JArithmeticDecoderStats *pPrevStats); - void ResetRefinementStats(unsigned int unTempl, JArithmeticDecoderStats *pPrevStats); - void ResetIntStats(int nSymCodeLen); - - bool ReadUByte(unsigned int *pBuffer); - bool ReadByte(int *pBuffer); - bool ReadUWord(unsigned int *pBuffer); - bool ReadULong(unsigned int *pBuffer); - bool ReadLong(int *pBuffer); - - private: - - Object m_oGlobalsStream; - unsigned int m_unPageW; - unsigned int m_unPageH; - unsigned int m_unCurPageH; - unsigned int m_unPageDefPixel; - JBIG2Bitmap *m_pPageBitmap; - unsigned int m_unDefCombOp; - CList *m_pSegments; // [JBIG2Segment] - CList *m_pGlobalSegments; // [JBIG2Segment] - Stream *m_pCurStream; - unsigned char *m_pDataPtr; - unsigned char *m_pDataEnd; - - JArithmeticDecoder *m_pArithDecoder; - JArithmeticDecoderStats *m_pGenericRegionStats; - JArithmeticDecoderStats *m_pRefinementRegionStats; - JArithmeticDecoderStats *m_pIadhStats; - JArithmeticDecoderStats *m_pIadwStats; - JArithmeticDecoderStats *m_pIaexStats; - JArithmeticDecoderStats *m_pIaaiStats; - JArithmeticDecoderStats *m_pIadtStats; - JArithmeticDecoderStats *m_pIaitStats; - JArithmeticDecoderStats *m_pIafsStats; - JArithmeticDecoderStats *m_pIadsStats; - JArithmeticDecoderStats *m_pIardxStats; - JArithmeticDecoderStats *m_pIardyStats; - JArithmeticDecoderStats *m_pIardwStats; - JArithmeticDecoderStats *m_pIardhStats; - JArithmeticDecoderStats *m_pIariStats; - JArithmeticDecoderStats *m_pIaidStats; - JBIG2HuffmanDecoder *m_pHuffDecoder; - JBIG2MMRDecoder *m_pMMrDecoder; - }; -} - -#endif // _PDF_READER_JBIG2STREAM_H diff --git a/PdfReader/old/JPXStream.cpp b/PdfReader/old/JPXStream.cpp deleted file mode 100644 index 12017313da..0000000000 --- a/PdfReader/old/JPXStream.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "MemoryUtils.h" -#include "JPXStream.h" -#include "File.h" - -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" - -#include "../../DesktopEditor/raster/Jp2/J2kFile.h" - -namespace PdfReader -{ - JPXStream::JPXStream(Stream *pStream) : - FilterStream(pStream) - { - m_lCurPos = 0; - m_lBufferSize = 0; - m_pSourceBuffer = NULL; - } - - JPXStream::~JPXStream() - { - Close(); - delete m_pStream; - } - - void JPXStream::Reset() - { - m_pStream->Reset(); - - // Инизиализация - m_lCurPos = 0; - m_lBufferSize = 0; - m_pSourceBuffer = NULL; - - // Создаем темповый файл, в который сбрасываем картинку - FILE *pTempFile = NULL; - - std::wstring wsTempFile = L""; - if (!NSFile::CFileBinary::OpenTempFile(&wsTempFile, &pTempFile, L"wb", NULL, NULL)) - { - NSFile::CFileBinary::Remove(wsTempFile); - return; - } - - int nChar = 0; - unsigned char *pBuffer = (unsigned char*)MemUtilsMalloc(32); - if (pBuffer) - { - int nSize = 32, nLen = 0; - while (EOF != (nChar = m_pStream->GetChar())) - { - if (nLen >= nSize) - { - nSize *= 2; - pBuffer = (unsigned char*)MemUtilsRealloc(pBuffer, nSize); - } - - pBuffer[nLen] = nChar; - nLen++; - } - fwrite(pBuffer, 1, nLen, pTempFile); - fclose(pTempFile); - MemUtilsFree(pBuffer); - } - else - { - while (EOF != (nChar = m_pStream->GetChar())) - { - fputc(nChar, pTempFile); - } - fclose(pTempFile); - } - - BYTE* pBufferPointer; - int nHeight = 0; - int nWidth = 0; - int nComponentsCount = 0; - - Jpeg2000::CJ2kFile oJ2; - if (!oJ2.Open(&pBufferPointer, nComponentsCount, nWidth, nHeight, wsTempFile, std::wstring(L"")) || !pBufferPointer) - { - NSFile::CFileBinary::Remove(wsTempFile); - return; - } - - m_lBufferSize = nWidth * nHeight * nComponentsCount; - m_pSourceBuffer = (unsigned char*)MemUtilsMalloc(m_lBufferSize); - if (!m_pSourceBuffer) - { - delete[] pBufferPointer; - NSFile::CFileBinary::Remove(wsTempFile); - m_lBufferSize = 0; - return; - } - - int nStride = nWidth * nComponentsCount; - unsigned char* pDst = m_pSourceBuffer; - for (int nY = 0; nY < nHeight; nY++) - { - unsigned char* pSrc = pBufferPointer + nStride * (nHeight - 1 - nY); - ::memcpy(pDst, pSrc, nStride); - pDst += nStride; - } - - delete[] pBufferPointer; - NSFile::CFileBinary::Remove(wsTempFile); - } - - void JPXStream::Close() - { - MemUtilsFree(m_pSourceBuffer); - m_pSourceBuffer = NULL; - - FilterStream::Close(); - } - - int JPXStream::GetChar() - { - int nChar = 0; - - if (m_lCurPos < m_lBufferSize) - { - nChar = m_pSourceBuffer[m_lCurPos]; - m_lCurPos++; - } - else - return EOF; - - return nChar; - } - - int JPXStream::LookChar() - { - if (m_lBufferSize > 0 && m_lCurPos < m_lBufferSize) - return m_pSourceBuffer[m_lCurPos]; - - return EOF; - } - StringExt *JPXStream::GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - - bool JPXStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - void JPXStream::GetImageParams(int *pBitsPerComponent, StreamColorSpaceMode *peModeCS) - { - *pBitsPerComponent = 8; - *peModeCS = streamCSDeviceRGB; - } -} diff --git a/PdfReader/old/JPXStream.h b/PdfReader/old/JPXStream.h deleted file mode 100644 index 51ec7fdd7b..0000000000 --- a/PdfReader/old/JPXStream.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_JPXSTREAM_H -#define _PDF_READER_JPXSTREAM_H - -#include "Object.h" -#include "Stream.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // JPXStream - //------------------------------------------------------------------------------------------------------------------------------- - - class JPXStream : public FilterStream - { - public: - - JPXStream(Stream *pStream); - virtual ~JPXStream(); - virtual StreamType GetType() - { - return strJPX; - } - virtual void Reset(); - virtual void Close(); - virtual int GetChar(); - virtual int LookChar(); - virtual StringExt *GetPSFilter(int psLevel, char *indent); - virtual bool IsBinary(bool bLast = true); - virtual void GetImageParams(int *pBitsPerComponent, StreamColorSpaceMode *peModeCS); - - private: - - long m_lBufferSize; - unsigned char* m_pSourceBuffer; - long m_lCurPos; - - }; -} - -#endif // _PDF_READER_JPXSTREAM_H diff --git a/PdfReader/old/Lexer.cpp b/PdfReader/old/Lexer.cpp deleted file mode 100644 index 220010b15d..0000000000 --- a/PdfReader/old/Lexer.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "Lexer.h" - -namespace PdfReader -{ - // '1' - означает пробел. '1' или '2' означает, что данным символом заканчивается - // имя или команда. - - static char c_sSpecialChars[256] = - { - // 0x 1x 2x 3x 4x 5x 6x 7x 8x 9x ax bx cx dx ex fx - - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x - 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx - }; - - //------------------------------------------------------------------------ - // Lexer - //------------------------------------------------------------------------ - - Lexer::Lexer(XRef *pXref, Stream *pStream) - { - Object oTemp; - - m_oCurStream.InitStream(pStream); - m_pStreams = new Array(pXref); - m_pStreams->Add(m_oCurStream.Copy(&oTemp)); - m_nCurStreamIndex = 0; - m_bFreeArray = true; - m_oCurStream.StreamReset(); - } - - Lexer::Lexer(XRef *pXref, Object *pObject) - { - // Предполагаем, что в pObject либо поток, либо массив потоков - Object oTemp; - - if (pObject->IsStream()) - { - m_pStreams = new Array(pXref); - m_bFreeArray = true; - m_pStreams->Add(pObject->Copy(&oTemp)); - } - else - { - m_pStreams = pObject->GetArray(); - m_bFreeArray = false; - } - - m_nCurStreamIndex = 0; - - if (m_pStreams->GetCount() > 0) - { - m_pStreams->Get(m_nCurStreamIndex, &m_oCurStream); - m_oCurStream.StreamReset(); - } - } - - Lexer::~Lexer() - { - if (!m_oCurStream.IsNone()) - { - m_oCurStream.StreamClose(); - m_oCurStream.Free(); - } - if (m_bFreeArray) - { - delete m_pStreams; - } - } - - int Lexer::GetChar() - { - int nChar = EOF; - while (!m_oCurStream.IsNone() && (nChar = m_oCurStream.StreamGetChar()) == EOF) - { - m_oCurStream.StreamClose(); - m_oCurStream.Free(); - ++m_nCurStreamIndex; - if (m_nCurStreamIndex < m_pStreams->GetCount()) - { - m_pStreams->Get(m_nCurStreamIndex, &m_oCurStream); - m_oCurStream.StreamReset(); - } - } - return nChar; - } - - int Lexer::LookChar() - { - if (m_oCurStream.IsNone()) - { - return EOF; - } - return m_oCurStream.StreamLookChar(); - } - - Object *Lexer::GetObject(Object *pObject) - { - char *pCurPointer; - int nChar, nTempChar; - bool bNegative = false, bDone = false; - int nBracketCount = 0; - int nInt = 0; - double dFloat = 0, dScale = 0; - StringExt *seString; - int nCount = 0, nHexCharLen = 0; - - // Пропускаем комментарии и пробелы - bool bComment = false; - while (1) - { - if ((nChar = GetChar()) == EOF) - { - return pObject->InitEOF(); - } - if (bComment) - { - if (nChar == '\r' || nChar == '\n') - bComment = false; - } - else if (nChar == '%') - { - bComment = true; - } - else if (c_sSpecialChars[nChar] != 1) - { - break; - } - } - - // начинаем чтение объекта - switch (nChar) - { - - // Число - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': case '.': - bNegative = false; - nInt = 0; - if (nChar == '-') - { - bNegative = true; - } - else if (nChar == '.') - { - goto doReal; - } - else - { - nInt = nChar - '0'; - } - while (1) - { - nChar = LookChar(); - if (isdigit(nChar)) - { - GetChar(); - nInt = nInt * 10 + (nChar - '0'); - } - else if (nChar == '.') - { - GetChar(); - goto doReal; - } - else - { - break; - } - } - if (bNegative) - nInt = -nInt; - pObject->InitInt(nInt); - break; - doReal: - dFloat = nInt; - dScale = 0.1; - while (1) - { - nChar = LookChar(); - if (nChar == '-') - { - // игнорируем знаки минус, появляющиеся по середине числа - // (Adobe игнорирует такие ситуации) - - // TO DO: Error "Badly formatted number" - GetChar(); - continue; - } - if (!isdigit(nChar)) - { - break; - } - GetChar(); - dFloat = dFloat + dScale * (nChar - '0'); - dScale *= 0.1; - } - if (bNegative) - dFloat = -dFloat; - pObject->InitReal(dFloat); - break; - - // Строка - case '(': - pCurPointer = m_sTempBuffer; - nCount = 0; - nBracketCount = 1; // счетчик собок - bDone = false; - seString = NULL; - do { - nTempChar = EOF; - switch (nChar = GetChar()) - { - - case EOF: -#if 0 - // This breaks some PDF files, e.g., ones from Photoshop. - case '\r': - case '\n': -#endif - // TO DO: Error "Unterminated string" - bDone = true; - break; - - case '(': - ++nBracketCount; - nTempChar = nChar; - break; - - case ')': - if (--nBracketCount == 0) - { - bDone = true; - } - else - { - nTempChar = nChar; - } - break; - case '\\': - switch (nChar = GetChar()) - { - case 'n': nTempChar = '\n'; break; - case 'r': nTempChar = '\r'; break; - case 't': nTempChar = '\t'; break; - case 'b': nTempChar = '\b'; break; - case 'f': nTempChar = '\f'; break; - case '\\': - case '(': - case ')': nTempChar = nChar; break; - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - nTempChar = nChar - '0'; - nChar = LookChar(); - if (nChar >= '0' && nChar <= '7') - { - GetChar(); - nTempChar = (nTempChar << 3) + (nChar - '0'); - nChar = LookChar(); - if (nChar >= '0' && nChar <= '7') - { - GetChar(); - nTempChar = (nTempChar << 3) + (nChar - '0'); - } - } - break; - case '\r': - nChar = LookChar(); - if (nChar == '\n') - { - GetChar(); - } - break; - case '\n': - break; - case EOF: - // TO DO: Error "Unterminated string" - bDone = true; - break; - default: - nTempChar = nChar; - break; - } - break; - - default: - nTempChar = nChar; - break; - } - - if (nTempChar != EOF) - { - if (nCount == TokenBufferSize) - { - if (!seString) - seString = new StringExt(m_sTempBuffer, TokenBufferSize); - else - seString->Append(m_sTempBuffer, TokenBufferSize); - pCurPointer = m_sTempBuffer; - nCount = 0; - } - *pCurPointer++ = (char)nTempChar; - ++nCount; - } - } while (!bDone); - - if (!seString) - seString = new StringExt(m_sTempBuffer, nCount); - else - seString->Append(m_sTempBuffer, nCount); - pObject->InitString(seString); - break; - // Имя - case '/': - pCurPointer = m_sTempBuffer; - nCount = 0; - while ((nChar = LookChar()) != EOF && !c_sSpecialChars[nChar]) - { - GetChar(); - if (nChar == '#') - { - nTempChar = LookChar(); - if (nTempChar >= '0' && nTempChar <= '9') - { - nChar = nTempChar - '0'; - } - else if (nTempChar >= 'A' && nTempChar <= 'F') - { - nChar = nTempChar - 'A' + 10; - } - else if (nTempChar >= 'a' && nTempChar <= 'f') - { - nChar = nTempChar - 'a' + 10; - } - else - { - goto notEscChar; - } - GetChar(); - nChar <<= 4; - nTempChar = GetChar(); - if (nTempChar >= '0' && nTempChar <= '9') - { - nChar += nTempChar - '0'; - } - else if (nTempChar >= 'A' && nTempChar <= 'F') - { - nChar += nTempChar - 'A' + 10; - } - else if (nTempChar >= 'a' && nTempChar <= 'f') - { - nChar += nTempChar - 'a' + 10; - } - else - { - // TO DO: Error "Illegal digit in hex char in name" - } - } - notEscChar: - if (++nCount == TokenBufferSize) - { - // TO DO: Error "Name token too long" - break; - } - *pCurPointer++ = nChar; - } - *pCurPointer = '\0'; - pObject->InitName(m_sTempBuffer); - break; - - // Массив - case '[': - case ']': - m_sTempBuffer[0] = nChar; - m_sTempBuffer[1] = '\0'; - pObject->InitCommand(m_sTempBuffer); - break; - - // Hex или Dictionary - case '<': - nChar = LookChar(); - - // Dictionary - if (nChar == '<') - { - GetChar(); - m_sTempBuffer[0] = m_sTempBuffer[1] = '<'; - m_sTempBuffer[2] = '\0'; - pObject->InitCommand(m_sTempBuffer); - } - else // Hex string - { - pCurPointer = m_sTempBuffer; - nHexCharLen = nCount = 0; - nTempChar = 0; - seString = NULL; - while (1) - { - nChar = GetChar(); - if (nChar == '>') - { - break; - } - else if (nChar == EOF) - { - // TO DO: Error "Unterminated hex string" - break; - } - else if (c_sSpecialChars[nChar] != 1) - { - nTempChar = nTempChar << 4; - if (nChar >= '0' && nChar <= '9') - nTempChar += nChar - '0'; - else if (nChar >= 'A' && nChar <= 'F') - nTempChar += nChar - 'A' + 10; - else if (nChar >= 'a' && nChar <= 'f') - nTempChar += nChar - 'a' + 10; - else - { - // TO DO: Error "Illegal character in hex string" - } - if (++nHexCharLen == 2) - { - if (nCount == TokenBufferSize) - { - if (!seString) - seString = new StringExt(m_sTempBuffer, TokenBufferSize); - else - seString->Append(m_sTempBuffer, TokenBufferSize); - pCurPointer = m_sTempBuffer; - nCount = 0; - } - *pCurPointer++ = (char)nTempChar; - ++nCount; - nTempChar = 0; - nHexCharLen = 0; - } - } - } - if (!seString) - seString = new StringExt(m_sTempBuffer, nCount); - else - seString->Append(m_sTempBuffer, nCount); - if (nHexCharLen == 1) - seString->Append((char)(nTempChar << 4)); - pObject->InitString(seString); - } - break; - - // Dictionary - case '>': - nChar = LookChar(); - if (nChar == '>') - { - GetChar(); - m_sTempBuffer[0] = m_sTempBuffer[1] = '>'; - m_sTempBuffer[2] = '\0'; - pObject->InitCommand(m_sTempBuffer); - } - else - { - // TO DO: Error "Illegal character '>'" - pObject->InitError(); - } - break; - - // Error - case ')': - case '{': - case '}': - // TO DO: Error "Illegal character " - pObject->InitError(); - break; - - // Command (это просто какое нибудь зарезервированное слово, например 'obj' или 'stream') - default: - pCurPointer = m_sTempBuffer; - *pCurPointer++ = nChar; - nCount = 1; - while ((nChar = LookChar()) != EOF && !c_sSpecialChars[nChar]) - { - GetChar(); - if (++nCount == TokenBufferSize) - { - // TO DO: Error "Command token too long" - break; - } - *pCurPointer++ = nChar; - } - *pCurPointer = '\0'; - if (m_sTempBuffer[0] == 't' && !strcmp(m_sTempBuffer, "true")) - { - pObject->InitBool(true); - } - else if (m_sTempBuffer[0] == 'f' && !strcmp(m_sTempBuffer, "false")) - { - pObject->InitBool(false); - } - else if (m_sTempBuffer[0] == 'n' && !strcmp(m_sTempBuffer, "null")) - { - pObject->InitNull(); - } - else - { - pObject->InitCommand(m_sTempBuffer); - } - break; - } - - return pObject; - } - - void Lexer::SkipToNextLine() - { - while (1) - { - int nChar = GetChar(); - if (nChar == EOF || nChar == '\n') - { - return; - } - if (nChar == '\r') - { - if ((nChar = LookChar()) == '\n') - { - GetChar(); - } - return; - } - } - } - - bool Lexer::IsSpace(int nChar) - { - return nChar >= 0 && nChar <= 0xff && c_sSpecialChars[nChar] == 1; - } -} \ No newline at end of file diff --git a/PdfReader/old/Lexer.h b/PdfReader/old/Lexer.h deleted file mode 100644 index 3a548c4e6c..0000000000 --- a/PdfReader/old/Lexer.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_LEXER_H -#define _PDF_READER_LEXER_H - -#include "Object.h" -#include "Stream.h" - -namespace PdfReader -{ - class XRef; - -#define TokenBufferSize 128 - - //------------------------------------------------------------------------ - // Lexer - //------------------------------------------------------------------------ - - class Lexer - { - public: - - // Конструктор для одного потока. Удаляем этот поток в деструкторе. - Lexer(XRef *pXref, Stream *pStream); - - // Конструкор для одного потока или массива потоков. - Lexer(XRef *pXref, Object *pObject); - - ~Lexer(); - - // Считваем следующий объект из потока. - Object *GetObject(Object *obj); - - // Переходим к началу новой строки. - void SkipToNextLine(); - - // Переходим к следующему символу. - void SkipChar() - { - GetChar(); - } - - - Stream *GetStream() - { - return m_oCurStream.IsNone() ? (Stream *)NULL : m_oCurStream.GetStream(); - } - - // Текущая позиция. Используется только для сообщений об ошибке, поэтому - // возвращаемое значение типа int, а не unsigned int. - int GetPos() - { - return m_oCurStream.IsNone() ? -1 : (int)m_oCurStream.StreamGetPos(); - } - - - void SetPos(unsigned int unPos, int nDir = 0) - { - if (!m_oCurStream.IsNone()) - m_oCurStream.StreamSetPos(unPos, nDir); - } - - // Проверяем является ли nChar пробелом. - static bool IsSpace(int nChar); - - private: - - int GetChar(); - int LookChar(); - - private: - - Array *m_pStreams; // Массив потоков - int m_nCurStreamIndex; // Номер текущего потока - Object m_oCurStream; // Текущий поток - bool m_bFreeArray; // Должны ли мы в данном классе осовбождать массив потоков? - char m_sTempBuffer[TokenBufferSize]; // Buffer - }; -} - -#endif // _PDF_READER_LEXER_H diff --git a/PdfReader/old/Link.cpp b/PdfReader/old/Link.cpp deleted file mode 100644 index e11a8c0fcf..0000000000 --- a/PdfReader/old/Link.cpp +++ /dev/null @@ -1,950 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "StringExt.h" -#include "Object.h" -#include "Array.h" -#include "Dict.h" -#include "Link.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // LinkAction - //------------------------------------------------------------------------------------------------------------------------------- - - LinkAction *LinkAction::ParseDestination(Object *pObject) - { - LinkAction *pAction = new LinkGoTo(pObject); - - if (!pAction->CheckValidate()) - { - delete pAction; - return NULL; - } - return pAction; - } - - LinkAction *LinkAction::ParseAction(Object *pObject, StringExt *seBaseURI) - { - LinkAction *pAction = NULL; - - if (!pObject->IsDict()) - { - // TO DO: Error "Bad annotation action" - return NULL; - } - - // S (тип Action) - Object oType; - pObject->DictLookup("S", &oType); - - // GoTo action - if (oType.IsName("GoTo")) - { - Object oD; - pObject->DictLookup("D", &oD); - pAction = new LinkGoTo(&oD); - oD.Free(); - } - else if (oType.IsName("GoToR")) // GoToR action - { - Object oF, oD; - pObject->DictLookup("F", &oF); - pObject->DictLookup("D", &oD); - pAction = new LinkGoToR(&oF, &oD); - oF.Free(); - oD.Free(); - } - else if (oType.IsName("Launch")) // Launch action - { - pAction = new LinkLaunch(pObject); - } - else if (oType.IsName("URI")) // URI action - { - Object oURI; - pObject->DictLookup("URI", &oURI); - pAction = new LinkURI(&oURI, seBaseURI); - oURI.Free(); - } - else if (oType.IsName("Named")) // Named action - { - Object oN; - pObject->DictLookup("N", &oN); - pAction = new LinkNamed(&oN); - oN.Free(); - } - else if (oType.IsName("Movie")) // Movie action - { - Object oAnnot, oT; - pObject->DictLookupAndCopy("Annot", &oAnnot); - pObject->DictLookup("T", &oT); - pAction = new LinkMovie(&oAnnot, &oT); - oAnnot.Free(); - oT.Free(); - } - else if (oType.IsName()) // unknown action - { - pAction = new LinkUnknown(oType.GetName()); - } - else - { - // TO DO: Error "Bad annotation action" - pAction = NULL; - } - - oType.Free(); - - if (pAction && !pAction->CheckValidate()) - { - delete pAction; - return NULL; - } - return pAction; - } - - StringExt *LinkAction::GetFileSpecName(Object *pFileSpecObject) - { - StringExt *seName = NULL; - - if (pFileSpecObject->IsString()) - { - seName = pFileSpecObject->GetString()->Copy(); - } - else if (pFileSpecObject->IsDict()) - { - Object oTemp; - if (!pFileSpecObject->DictLookup("DOS", &oTemp)->IsString()) - { - oTemp.Free(); - pFileSpecObject->DictLookup("F", &oTemp); - } - if (oTemp.IsString()) - { - seName = oTemp.GetString()->Copy(); - } - else - { - // TO DO: Error "Illegal file spec in link" - } - oTemp.Free(); - } - else - { - // TO DO: Error "Illegal file spec in link" - } - - if (seName) - { - // Производим преобразования, связанные с формой записи путей - - // "//...." --> "\...." - // "/x/...." --> "x:\...." - // "/server/share/...." --> "\\server\share\...." - - int nCurIndex = 0; - if (seName->GetAt(0) == '/') - { - if (seName->GetLength() >= 2 && seName->GetAt(1) == '/') - { - seName->Delete(0); - nCurIndex = 0; - } - else if (seName->GetLength() >= 2 && ((seName->GetAt(1) >= 'a' && seName->GetAt(1) <= 'z') || (seName->GetAt(1) >= 'A' && seName->GetAt(1) <= 'Z')) && (seName->GetLength() == 2 || seName->GetAt(2) == '/')) - { - seName->SetAt(0, seName->GetAt(1)); - seName->SetAt(1, ':'); - nCurIndex = 2; - } - else - { - int nJ; - for (nJ = 2; nJ < seName->GetLength(); ++nJ) - { - if (seName->GetAt(nJ - 1) != '\\' && seName->GetAt(nJ) == '/') - { - break; - } - } - if (nJ < seName->GetLength()) - { - seName->SetAt(0, '\\'); - seName->Insert(0, '\\'); - nCurIndex = 2; - } - } - } - for (; nCurIndex < seName->GetLength(); ++nCurIndex) - { - if (seName->GetAt(nCurIndex) == '/') - { - seName->SetAt(nCurIndex, '\\'); - } - else if (seName->GetAt(nCurIndex) == '\\' && nCurIndex + 1 < seName->GetLength() && seName->GetAt(nCurIndex + 1) == '/') - { - seName->Delete(nCurIndex); - } - } - } - - return seName; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkDest - //------------------------------------------------------------------------------------------------------------------------------- - - LinkDestination::LinkDestination(Array *pArray) - { - m_dLeft = m_dBottom = m_dRight = m_dTop = m_dZoom = 0; - m_bValidate = false; - - if (pArray->GetCount() < 2) - { - // TO DO: Error "Annotation destination array is too short" - return; - } - - Object oArrayItem; - pArray->GetCopy(0, &oArrayItem); - - if (oArrayItem.IsInt()) - { - m_nPageNum = oArrayItem.GetInt() + 1; - m_bPageIsRef = false; - } - else if (oArrayItem.IsRef()) - { - m_oPageRef.nNum = oArrayItem.GetRefNum(); - m_oPageRef.nGen = oArrayItem.GetRefGen(); - m_bPageIsRef = true; - } - else - { - // TO DO: Error "Bad annotation destination" - oArrayItem.Free(); - return; - } - oArrayItem.Free(); - - // Destination type - pArray->Get(1, &oArrayItem); - - if (oArrayItem.IsName("XYZ")) - { - m_eType = destXYZ; - Object oTemp; - if (pArray->GetCount() < 3) - { - m_bChangeLeft = false; - } - else - { - pArray->Get(2, &oTemp); - if (oTemp.IsNull()) - { - m_bChangeLeft = false; - } - else if (oTemp.IsNum()) - { - m_bChangeLeft = true; - m_dLeft = oTemp.GetNum(); - } - else - { - // TO DO: Error "Bad annotation destination position" - oTemp.Free(); - oArrayItem.Free(); - return; - } - oTemp.Free(); - } - if (pArray->GetCount() < 4) - { - m_bChangeTop = false; - } - else - { - pArray->Get(3, &oTemp); - if (oTemp.IsNull()) - { - m_bChangeTop = false; - } - else if (oTemp.IsNum()) - { - m_bChangeTop = true; - m_dTop = oTemp.GetNum(); - } - else - { - // TO DO: Error "Bad annotation destination position" - oTemp.Free(); - oArrayItem.Free(); - return; - } - oTemp.Free(); - } - if (pArray->GetCount() < 5) - { - m_bChangeZoom = false; - } - else - { - pArray->Get(4, &oTemp); - if (oTemp.IsNull()) - { - m_bChangeZoom = false; - } - else if (oTemp.IsNum()) - { - m_bChangeZoom = true; - m_dZoom = oTemp.GetNum(); - } - else - { - // TO DO: Error "Bad annotation destination position" - oTemp.Free(); - oArrayItem.Free(); - return; - } - oTemp.Free(); - } - } - else if (oArrayItem.IsName("Fit")) - { - if (pArray->GetCount() < 2) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFit; - } - else if (oArrayItem.IsName("FitH")) - { - if (pArray->GetCount() < 3) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitH; - - Object oTemp; - if (!pArray->Get(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dTop = oTemp.GetNum(); - oTemp.Free(); - } - else if (oArrayItem.IsName("FitV")) - { - if (pArray->GetCount() < 3) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitV; - - Object oTemp; - if (!pArray->Get(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dLeft = oTemp.GetNum(); - oTemp.Free(); - } - else if (oArrayItem.IsName("FitR")) - { - if (pArray->GetCount() < 6) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitR; - - Object oTemp; - if (!pArray->Get(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dLeft = oTemp.GetNum(); - oTemp.Free(); - - if (!pArray->Get(3, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dBottom = oTemp.GetNum(); - oTemp.Free(); - - if (!pArray->Get(4, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dRight = oTemp.GetNum(); - oTemp.Free(); - - if (!pArray->Get(5, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dTop = oTemp.GetNum(); - oTemp.Free(); - } - else if (oArrayItem.IsName("FitB")) - { - if (pArray->GetCount() < 2) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitB; - } - else if (oArrayItem.IsName("FitBH")) - { - if (pArray->GetCount() < 3) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitBH; - - Object oTemp; - if (!pArray->Get(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dTop = oTemp.GetNum(); - oTemp.Free(); - } - else if (oArrayItem.IsName("FitBV")) - { - if (pArray->GetCount() < 3) - { - // TO DO: Error "Annotation destination array is too short" - oArrayItem.Free(); - return; - } - m_eType = destFitBV; - - Object oTemp; - if (!pArray->Get(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation destination position" - m_eType = destFit; - } - m_dLeft = oTemp.GetNum(); - oTemp.Free(); - } - else - { - // TO DO: Error "Unknown annotation destination type" - oArrayItem.Free(); - return; - } - - oArrayItem.Free(); - m_bValidate = true; - return; - } - - LinkDestination::LinkDestination(LinkDestination *pDest) - { - m_eType = pDest->m_eType; - m_bPageIsRef = pDest->m_bPageIsRef; - - if (m_bPageIsRef) - m_oPageRef = pDest->m_oPageRef; - else - m_nPageNum = pDest->m_nPageNum; - - m_dLeft = pDest->m_dLeft; - m_dBottom = pDest->m_dBottom; - m_dRight = pDest->m_dRight; - m_dTop = pDest->m_dTop; - m_dZoom = pDest->m_dZoom; - m_bChangeLeft = pDest->m_bChangeLeft; - m_bChangeTop = pDest->m_bChangeTop; - m_bChangeZoom = pDest->m_bChangeZoom; - m_bValidate = true; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkGoTo - //------------------------------------------------------------------------------------------------------------------------------- - - LinkGoTo::LinkGoTo(Object *pDestObject) - { - m_pDestination = NULL; - m_pNamedDestination = NULL; - - if (pDestObject->IsName()) - { - m_pNamedDestination = new StringExt(pDestObject->GetName()); - } - else if (pDestObject->IsString()) - { - m_pNamedDestination = pDestObject->GetString()->Copy(); - } - else if (pDestObject->IsArray()) - { - m_pDestination = new LinkDestination(pDestObject->GetArray()); - if (!m_pDestination->CheckValidate()) - { - delete m_pDestination; - m_pDestination = NULL; - } - } - else - { - // TO DO: Error "Illegal annotation destination" - } - } - - LinkGoTo::~LinkGoTo() - { - if (m_pDestination) - delete m_pDestination; - if (m_pNamedDestination) - delete m_pNamedDestination; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkGoToR - //------------------------------------------------------------------------------------------------------------------------------- - - LinkGoToR::LinkGoToR(Object *pFileSpecObject, Object *pDestObject) - { - m_pDestination = NULL; - m_pNamedDestination = NULL; - - m_seFileName = GetFileSpecName(pFileSpecObject); - - if (pDestObject->IsName()) - { - m_pNamedDestination = new StringExt(pDestObject->GetName()); - } - else if (pDestObject->IsString()) - { - m_pNamedDestination = pDestObject->GetString()->Copy(); - } - else if (pDestObject->IsArray()) - { - m_pDestination = new LinkDestination(pDestObject->GetArray()); - if (!m_pDestination->CheckValidate()) - { - delete m_pDestination; - m_pDestination = NULL; - } - } - else - { - // TO DO: Error "Illegal annotation destination" - } - } - - LinkGoToR::~LinkGoToR() - { - if (m_seFileName) - delete m_seFileName; - if (m_pDestination) - delete m_pDestination; - if (m_pNamedDestination) - delete m_pNamedDestination; - } - - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkLaunch - //------------------------------------------------------------------------------------------------------------------------------- - - LinkLaunch::LinkLaunch(Object *pActionObject) - { - m_seFileName = NULL; - m_pParameters = NULL; - - if (pActionObject->IsDict()) - { - Object oSpecObject; - if (!pActionObject->DictLookup("F", &oSpecObject)->IsNull()) - { - m_seFileName = GetFileSpecName(&oSpecObject); - } - else - { - oSpecObject.Free(); - if (pActionObject->DictLookup("Win", &oSpecObject)->IsDict()) - { - Object oTemp; - oSpecObject.DictLookup("F", &oTemp); - m_seFileName = GetFileSpecName(&oTemp); - oTemp.Free(); - if (oSpecObject.DictLookup("P", &oTemp)->IsString()) - { - m_pParameters = oTemp.GetString()->Copy(); - } - oTemp.Free(); - } - else - { - // TO DO: Error "Bad launch-type link action" - } - } - oSpecObject.Free(); - } - } - - LinkLaunch::~LinkLaunch() - { - if (m_seFileName) - delete m_seFileName; - if (m_pParameters) - delete m_pParameters; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkURI - //------------------------------------------------------------------------------------------------------------------------------- - - LinkURI::LinkURI(Object *pUriObject, StringExt *seBaseURI) - { - m_seURI = NULL; - if (pUriObject->IsString()) - { - StringExt *seTempURI = pUriObject->GetString()->Copy(); - if (seBaseURI && seBaseURI->GetLength() > 0) - { - int nCount = strcspn(seTempURI->GetBuffer(), "/:"); - if (nCount == seTempURI->GetLength() || seTempURI->GetAt(nCount) == '/') - { - m_seURI = seBaseURI->Copy(); - int nChar = m_seURI->GetAt(m_seURI->GetLength() - 1); - if (nChar == '/' || nChar == '?') - { - if (seTempURI->GetAt(0) == '/') - { - seTempURI->Delete(0); - } - } - else - { - if (seTempURI->GetAt(0) != '/') - { - m_seURI->Append('/'); - } - } - m_seURI->Append(seTempURI); - delete seTempURI; - } - else - { - m_seURI = seTempURI; - } - } - else - { - m_seURI = seTempURI; - } - } - else - { - // TO DO: Error "Illegal URI-type link" - } - } - - LinkURI::~LinkURI() - { - if (m_seURI) - delete m_seURI; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkNamed - //------------------------------------------------------------------------------------------------------------------------------- - - LinkNamed::LinkNamed(Object *pNameObject) - { - m_seName = NULL; - if (pNameObject->IsName()) - { - m_seName = new StringExt(pNameObject->GetName()); - } - } - - LinkNamed::~LinkNamed() - { - if (m_seName) - { - delete m_seName; - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkMovie - //------------------------------------------------------------------------------------------------------------------------------- - - LinkMovie::LinkMovie(Object *pAnnotObject, Object *pTitleObject) - { - m_oAnnotRef.nNum = -1; - m_seTitle = NULL; - if (pAnnotObject->IsRef()) - { - m_oAnnotRef = pAnnotObject->GetRef(); - } - else if (pTitleObject->IsString()) - { - m_seTitle = pTitleObject->GetString()->Copy(); - } - else - { - // TO DO: Error "Movie action is missing both the Annot and T keys" - } - } - - LinkMovie::~LinkMovie() - { - if (m_seTitle) - { - delete m_seTitle; - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkUnknown - //------------------------------------------------------------------------------------------------------------------------------- - - LinkUnknown::LinkUnknown(char *sAction) - { - m_seAction = new StringExt(sAction); - } - - LinkUnknown::~LinkUnknown() - { - if (m_seAction) - delete m_seAction; - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Link - //------------------------------------------------------------------------------------------------------------------------------- - - Link::Link(Dict *pDict, StringExt *seBaseURI) - { - m_pAction = NULL; - m_bValid = false; - - // Rect - Object oDictItem; - if (!pDict->Search("Rect", &oDictItem)->IsArray()) - { - // TO DO: Error "Annotation rectangle is wrong type" - oDictItem.Free(); - return; - } - - Object oTemp; - if (!oDictItem.ArrayGet(0, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation rectangle" - oTemp.Free(); - oDictItem.Free(); - return; - } - m_dLeft = oTemp.GetNum(); - oTemp.Free(); - - if (!oDictItem.ArrayGet(1, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation rectangle" - oTemp.Free(); - oDictItem.Free(); - return; - } - m_dBottom = oTemp.GetNum(); - oTemp.Free(); - - if (!oDictItem.ArrayGet(2, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation rectangle" - oTemp.Free(); - oDictItem.Free(); - return; - } - m_dRight = oTemp.GetNum(); - oTemp.Free(); - - if (!oDictItem.ArrayGet(3, &oTemp)->IsNum()) - { - // TO DO: Error "Bad annotation rectangle" - oTemp.Free(); - oDictItem.Free(); - return; - } - m_dTop = oTemp.GetNum(); - oTemp.Free(); - oDictItem.Free(); - - if (m_dLeft > m_dRight) - { - double dTemp = m_dLeft; - m_dLeft = m_dRight; - m_dRight = dTemp; - } - if (m_dBottom > m_dTop) - { - double dTemp = m_dBottom; - m_dBottom = m_dTop; - m_dTop = dTemp; - } - - // Dest - if (!pDict->Search("Dest", &oDictItem)->IsNull()) - { - m_pAction = LinkAction::ParseDestination(&oDictItem); - } - else // A (Action) - { - oDictItem.Free(); - if (pDict->Search("A", &oDictItem)->IsDict()) - { - m_pAction = LinkAction::ParseAction(&oDictItem, seBaseURI); - } - } - oDictItem.Free(); - - if (m_pAction) - { - m_bValid = true; - } - - return; - } - - Link::~Link() - { - if (m_pAction) - { - delete m_pAction; - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // Links - //------------------------------------------------------------------------------------------------------------------------------- - - Links::Links(Object *pAnnots, StringExt *seBaseURI) - { - m_ppLinks = NULL; - m_nLinksCount = 0; - - int nSize = 0; - - if (pAnnots->IsArray()) - { - for (int nIndex = 0; nIndex < pAnnots->ArrayGetLength(); ++nIndex) - { - Object oArrayItem; - if (pAnnots->ArrayGet(nIndex, &oArrayItem)->IsDict()) - { - Object oTemp; - if (oArrayItem.DictLookup("Subtype", &oTemp)->IsName("Link")) - { - Link *pLink = new Link(oArrayItem.GetDict(), seBaseURI); - if (pLink->CheckValidate()) - { - if (m_nLinksCount >= nSize) - { - nSize += 16; - m_ppLinks = (Link **)MemUtilsReallocArray(m_ppLinks, nSize, sizeof(Link *)); - } - m_ppLinks[m_nLinksCount++] = pLink; - } - else - { - if (pLink) - delete pLink; - } - } - oTemp.Free(); - } - oArrayItem.Free(); - } - } - } - - Links::~Links() - { - for (int nIndex = 0; nIndex < m_nLinksCount; ++nIndex) - { - if (m_ppLinks[nIndex]) - delete m_ppLinks[nIndex]; - } - MemUtilsFree(m_ppLinks); - } - - LinkAction *Links::Find(double dX, double dY) - { - for (int nIndex = m_nLinksCount - 1; nIndex >= 0; --nIndex) - { - if (m_ppLinks[nIndex]->InRect(dX, dY)) - { - return m_ppLinks[nIndex]->GetAction(); - } - } - return NULL; - } - - bool Links::OnLink(double dX, double dY) - { - for (int nIndex = 0; nIndex < m_nLinksCount; ++nIndex) - { - if (m_ppLinks[nIndex]->InRect(dX, dY)) - return true; - } - return false; - } -} \ No newline at end of file diff --git a/PdfReader/old/Link.h b/PdfReader/old/Link.h deleted file mode 100644 index e6bea7ace7..0000000000 --- a/PdfReader/old/Link.h +++ /dev/null @@ -1,524 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_LINK_H -#define _PDF_READER_LINK_H - -#include "Object.h" - -namespace PdfReader -{ - class StringExt; - class Array; - class Dict; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkAction - //------------------------------------------------------------------------------------------------------------------------------- - - enum LinkActionType - { - actionGoTo, // Go to destination - actionGoToR, // Go to destination в новом файле - actionLaunch, // Запускаем приложение (или открываем документ) - actionURI, // URI - actionNamed, // Named - actionMovie, // Movie - actionUnknown // - }; - - class LinkAction - { - public: - - virtual ~LinkAction() {} - - // Нормально ли создался объект LinkAction? - virtual bool CheckValidate() = 0; - - // Тип LinkAction. - virtual LinkActionType GetType() = 0; - - // Парсим Destination (старый вариант Аction) Name, String или Array. - static LinkAction *ParseDestination(Object *pObject); - - // Парсим Action dictionary. - static LinkAction *ParseAction(Object *pObject, StringExt *seBaseURI = NULL); - - // Достаем название файла для File specification. - static StringExt *GetFileSpecName(Object *pFileSpecObject); - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkDestination - //------------------------------------------------------------------------------------------------------------------------------- - - enum LinkDestinationType - { - destXYZ, - destFit, - destFitH, - destFitV, - destFitR, - destFitB, - destFitBH, - destFitBV - }; - - class LinkDestination - { - public: - - LinkDestination(Array *pArray); - - LinkDestination *Copy() - { - return new LinkDestination(this); - } - - - bool CheckValidate() - { - return m_bValidate; - } - - LinkDestinationType GetType() - { - return m_eType; - } - bool IsPageRef() - { - return m_bPageIsRef; - } - int GetPageNum() - { - return m_nPageNum; - } - Ref GetPageRef() - { - return m_oPageRef; - } - double GetLeft() - { - return m_dLeft; - } - double GetBottom() - { - return m_dBottom; - } - double GetRight() - { - return m_dRight; - } - double GetTop() - { - return m_dTop; - } - double GetZoom() - { - return m_dZoom; - } - bool GetChangeLeft() - { - return m_bChangeLeft; - } - bool GetChangeTop() - { - return m_bChangeTop; - } - bool GetChangeZoom() - { - return m_bChangeZoom; - } - - private: - - LinkDestination(LinkDestination *pDest); - - private: - - LinkDestinationType m_eType; // Тип - bool m_bPageIsRef; // Страница задана ссылкой или номером? - union - { - Ref m_oPageRef; // Ссылка на страницу - int m_nPageNum; // Относительный номер страницы - }; - - double m_dLeft; // - double m_dBottom; // Позиция - double m_dRight; // - double m_dTop; // - - double m_dZoom; // Zoom - - bool m_bChangeLeft; // Для destXYZ. В данном случае может измениться - bool m_bChangeTop; // как позиция, так и зуммирование - bool m_bChangeZoom; // - - bool m_bValidate; // - - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkGoTo - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkGoTo : public LinkAction - { - public: - - LinkGoTo(Object *pDestObject); - - virtual ~LinkGoTo(); - - virtual bool CheckValidate() - { - return m_pDestination || m_pNamedDestination; - } - - virtual LinkActionType GetType() - { - return actionGoTo; - } - LinkDestination *GetDestination() - { - return m_pDestination; - } - StringExt *GetNamedDestination() - { - return m_pNamedDestination; - } - - private: - - LinkDestination *m_pDestination; - StringExt *m_pNamedDestination; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkGoToR - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkGoToR : public LinkAction - { - public: - - LinkGoToR(Object *pFileSpecObject, Object *pDestObject); - virtual ~LinkGoToR(); - - virtual bool CheckValidate() - { - return m_seFileName && (m_pDestination || m_pNamedDestination); - } - - virtual LinkActionType GetType() - { - return actionGoToR; - } - StringExt *GetFileName() - { - return m_seFileName; - } - LinkDestination *GetDestination() - { - return m_pDestination; - } - StringExt *GetNamedDestination() - { - return m_pNamedDestination; - } - - private: - - StringExt *m_seFileName; - LinkDestination *m_pDestination; - StringExt *m_pNamedDestination; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkLaunch - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkLaunch : public LinkAction - { - public: - - LinkLaunch(Object *pActionObject); - - virtual ~LinkLaunch(); - - virtual bool CheckValidate() - { - return m_seFileName != NULL; - } - - virtual LinkActionType GetType() - { - return actionLaunch; - } - StringExt *GetFileName() - { - return m_seFileName; - } - StringExt *GetParameters() - { - return m_pParameters; - } - - private: - - StringExt *m_seFileName; - StringExt *m_pParameters; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkURI - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkURI : public LinkAction - { - public: - - LinkURI(Object *pURIObject, StringExt *seBaseURI); - - virtual ~LinkURI(); - - virtual bool CheckValidate() - { - return m_seURI != NULL; - } - - virtual LinkActionType GetType() - { - return actionURI; - } - StringExt *GetURI() - { - return m_seURI; - } - - private: - - StringExt *m_seURI; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkNamed - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkNamed : public LinkAction - { - public: - - LinkNamed(Object *pNameObject); - - virtual ~LinkNamed(); - - virtual bool CheckValidate() - { - return m_seName != NULL; - } - - virtual LinkActionType GetType() - { - return actionNamed; - } - - StringExt *GetName() - { - return m_seName; - } - - private: - - StringExt *m_seName; - - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkMovie - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkMovie : public LinkAction - { - public: - - LinkMovie(Object *pAnnotObject, Object *pTitleObject); - - virtual ~LinkMovie(); - - virtual bool CheckValidate() - { - return m_oAnnotRef.nNum >= 0 || m_seTitle != NULL; - } - - virtual LinkActionType GetType() - { - return actionMovie; - } - - bool HasAnnotRef() - { - return m_oAnnotRef.nNum >= 0; - } - Ref *GetAnnotRef() - { - return &m_oAnnotRef; - } - StringExt *GetTitle() - { - return m_seTitle; - } - - private: - - Ref m_oAnnotRef; - StringExt *m_seTitle; - - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // LinkUnknown - //------------------------------------------------------------------------------------------------------------------------------- - - class LinkUnknown : public LinkAction - { - public: - - LinkUnknown(char *sAction); - - virtual ~LinkUnknown(); - - virtual bool CheckValidate() - { - return m_seAction != NULL; - } - - virtual LinkActionType GetType() - { - return actionUnknown; - } - - StringExt *GetAction() - { - return m_seAction; - } - - private: - - StringExt *m_seAction; - - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Link - //------------------------------------------------------------------------------------------------------------------------------- - - class Link - { - public: - - Link(Dict *pDict, StringExt *seBaseURI); - - ~Link(); - - bool CheckValidate() - { - return m_bValid; - } - - // Попала ли точка в рект - bool InRect(double dX, double dY) - { - return m_dLeft <= dX && dX <= m_dRight && m_dBottom <= dY && dY <= m_dTop; - } - - LinkAction *GetAction() - { - return m_pAction; - } - - void GetRect(double *pdLeft, double *pdBottom, double *pdRight, double *pdTop) - { - *pdLeft = m_dLeft; - *pdBottom = m_dBottom; - *pdRight = m_dRight; - *pdTop = m_dTop; - } - - private: - - double m_dLeft; - double m_dBottom; - double m_dRight; - double m_dTop; - - LinkAction *m_pAction; - bool m_bValid; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // Links - //------------------------------------------------------------------------------------------------------------------------------- - - class Links - { - public: - - Links(Object *pAnnots, StringExt *seBaseURI); - - ~Links(); - - int GetLinksCount() - { - return m_nLinksCount; - } - Link *GetLink(int nIndex) - { - return m_ppLinks[nIndex]; - } - - - // Если точка (dX, dY) попадает в Link, тогда возвращаем соответствующий Action. - LinkAction *Find(double dX, double dY); - - // Проверяем попадает ли точка в Link. - bool OnLink(double dX, double dY); - - private: - - Link **m_ppLinks; - int m_nLinksCount; - }; -} - -#endif // _PDF_READER_LINK_H diff --git a/PdfReader/old/List.cpp b/PdfReader/old/List.cpp deleted file mode 100644 index 34033115b8..0000000000 --- a/PdfReader/old/List.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "List.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // CList - //------------------------------------------------------------------------ - - CList::CList() - { - m_nItemSize = 8; - m_ppData = (void **)MemUtilsMallocArray(m_nItemSize, sizeof(void*)); - m_nCount = 0; - m_nIncreament = 0; - } - - CList::CList(int nSize) - { - m_nItemSize = nSize; - m_ppData = (void **)MemUtilsMallocArray(m_nItemSize, sizeof(void*)); - m_nCount = 0; - m_nIncreament = 0; - } - - CList::~CList() - { - MemUtilsFree(m_ppData); - } - - void CList::Append(void *pItem) - { - if (m_nCount >= m_nItemSize) - Expand(); - m_ppData[m_nCount++] = pItem; - } - - void CList::Append(CList *pList) - { - while (m_nCount + pList->m_nCount > m_nItemSize) - Expand(); - for (int nIndex = 0; nIndex < pList->m_nCount; ++nIndex) - m_ppData[m_nCount++] = pList->m_ppData[nIndex]; - } - - void CList::Insert(int nIndex, void *pItem) - { - if (0 > nIndex || nIndex > m_nCount) - return; - if (m_nCount >= m_nItemSize) - Expand(); - if (nIndex < m_nCount) - memmove(m_ppData + nIndex + 1, m_ppData + nIndex, (m_nCount - nIndex) * sizeof(void *)); - m_ppData[nIndex] = pItem; - ++m_nCount; - } - - void *CList::Delete(int nIndex) - { - void *pItem = m_ppData[nIndex]; - if (nIndex < m_nCount - 1) - memmove(m_ppData + nIndex, m_ppData + nIndex + 1, (m_nCount - nIndex - 1) * sizeof(void *)); - --m_nCount; - if (m_nItemSize - m_nCount >= ((m_nIncreament > 0) ? m_nIncreament : m_nItemSize / 2)) - Shrink(); - return pItem; - } - - void CList::Sort(int(*CompareFunc)(const void *pItem1, const void *pItem2)) - { - qsort(m_ppData, m_nCount, sizeof(void *), CompareFunc); - } - - void CList::Expand() - { - m_nItemSize += (m_nIncreament > 0) ? m_nIncreament : m_nItemSize; - m_ppData = (void **)MemUtilsReallocArray(m_ppData, m_nItemSize, sizeof(void*)); - } - - void CList::Shrink() - { - m_nItemSize -= (m_nIncreament > 0) ? m_nIncreament : m_nItemSize / 2; - m_ppData = (void **)MemUtilsReallocArray(m_ppData, m_nItemSize, sizeof(void*)); - } -} \ No newline at end of file diff --git a/PdfReader/old/List.h b/PdfReader/old/List.h deleted file mode 100644 index e5ec461ce7..0000000000 --- a/PdfReader/old/List.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_LIST_H -#define _PDF_READER_LIST_H - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // CList - //------------------------------------------------------------------------ - - class CList - { - - public: - - // Создаем пустой список. - CList(); - - // Создаем пустой список с с выделенной памятью под элементов. - CList(int nSize); - - // Деструктор. - ~CList(); - - int GetLength() - { - return m_nCount; - } - - // Возвращает Ый элемент. - // Если 0 <= nIndex < m_nCount, возвращает NULL. - void *GetByIndex(int nIndex) - { - if (nIndex < 0 || nIndex >= m_nCount) - return NULL; - return m_ppData[nIndex]; - } - - // Добавляем элемент в окнец списка. - void Append(void *pItem); - - // Добавляем другой список в конец данного. - void Append(CList *pList); - - // Вставляем элемент на место . - // Если !(0 <= nIndex <= m_nCount), ничего не делаем. - void Insert(int nIndex, void *pItem); - - // Удаляем из списка и возвращаем ссылку на элемент. - // Если !(0 <= nIndex <= m_nCount), ничего не делаем. - void *Delete(int nIndex); - - // Сортируем список, в соответствии с данной функцией - // сранвения. - void Sort(int(*CompareFunc)(const void *pItem1, const void *pItem2)); - - // Если m_nIncreament > 0, тогда при расширении списка ровно - // m_nIncreament элементов будет добавляться. Если m_nIncreament <= 0, - // тогда список будем удваивать при расширении. - void SetAllocationIncreament(int nIncreament) - { - m_nIncreament = nIncreament; - } - - private: - - void Expand(); - void Shrink(); - - private: - - void **m_ppData; // список элементов - int m_nItemSize; // размер данных в массиве - int m_nCount; // количестов элементов в списке - int m_nIncreament; // на сколько будем увеличивать список - }; - -#define DeleteCList(list, T) \ - do { \ - CList *_list = (list); \ - { \ - int _i; \ - for (_i = 0; _i < _list->GetLength(); ++_i) { \ - delete (T*)_list->GetByIndex(_i); \ - } \ - delete _list; \ - } \ - } while (0) - -} -#endif // _PDF_READER_LIST_H diff --git a/PdfReader/old/MemoryUtils.h b/PdfReader/old/MemoryUtils.h deleted file mode 100644 index a46884ed68..0000000000 --- a/PdfReader/old/MemoryUtils.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_MEMORY_UTILS_H -#define _PDF_READER_MEMORY_UTILS_H - -#include -#include -#include - -#ifndef INT_MAX -#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */ -#define INT_MAX 2147483647 /* maximum (signed) int value */ -#endif - - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Аналогично malloc, но с обработкой ошибок. - static void *MemUtilsMalloc(int nSize) - { - void *pResult; - - if (nSize <= 0) - return NULL; - - if (!(pResult = malloc(nSize))) - { - // TO DO: Выдать ошибку выделения памяти - } - return pResult; - } - - - // Тоже что и realloc, но с обработкой ошибок. - // Если NULL, вызывается функция malloc вместо realloc. - static void *MemUtilsRealloc(void *pData, int nSize) - { - void *pResult; - - if (nSize <= 0) - { - if (pData) - free(pData); - return NULL; - } - if (pData) - pResult = realloc(pData, nSize); - else - pResult = malloc(nSize); - if (!pResult) - { - // TO DO: Выдать ошибку выделения памяти - } - return pResult; - } - - - // Тоже самое, что и MemUtilsMalloc and MemUtilsRelloc, толькоt - // учитывает количество элементов и размер элемента. В результате - // выделяется память размером nObjectsCount * nObjectSize байт. - // Кроме того присутствует обработка ошибок и проверка того, чтобы - // суммарный размер не превышал предел для int. - static void *MemUtilsMallocArray(int nObjectsCount, int nObjectSize) - { - if (0 == nObjectsCount) - return NULL; - - int nSize = nObjectsCount * nObjectSize; - if (nObjectSize <= 0 || nObjectsCount < 0 || nObjectsCount >= INT_MAX / nObjectSize) - { - // TO DO: Выдать ошибку выделения памяти - } - return MemUtilsMalloc(nSize); - } - - // Тоже что и free, но проверяет и игнорирует NULL-указатели. - static void MemUtilsFree(void *pData) - { - if (pData) - free(pData); - } - - static void *MemUtilsReallocArray(void *pData, int nObjectsCount, int nObjectSize) - { - if (0 == nObjectsCount) - { - if (pData) - MemUtilsFree(pData); - return NULL; - } - int nSize = nObjectsCount * nObjectSize; - - if (nObjectSize <= 0 || nObjectsCount < 0 || nObjectsCount >= INT_MAX / nObjectSize) - { - // TO DO: Выдать ошибку выделения памяти - } - return MemUtilsRealloc(pData, nSize); - } - - // Выделяем память и копируем туда строку. - static char *CopyString(char *sString) - { - char *sResult = (char *)MemUtilsMalloc((int)strlen(sString) + 1); - strcpy(sResult, sString); - return sResult; - } -} - -#endif // _PDF_READER_MEMORY_UTILS_H diff --git a/PdfReader/old/NameToCharCode.cpp b/PdfReader/old/NameToCharCode.cpp deleted file mode 100644 index b6e9f07059..0000000000 --- a/PdfReader/old/NameToCharCode.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "MemoryUtils.h" -#include "NameToCharCode.h" - -namespace PdfReader -{ - struct NameToCharCodeEntry - { - char *sName; - CharCode nCode; - }; - - //------------------------------------------------------------------------ - - NameToCharCode::NameToCharCode() - { - m_nSize = 31; - m_nLen = 0; - m_pTable = (NameToCharCodeEntry *)MemUtilsMallocArray(m_nSize, sizeof(NameToCharCodeEntry)); - - for (int nIndex = 0; nIndex < m_nSize; ++nIndex) - { - m_pTable[nIndex].sName = NULL; - } - } - - NameToCharCode::~NameToCharCode() - { - for (int nIndex = 0; nIndex < m_nSize; ++nIndex) - { - if (m_pTable[nIndex].sName) - { - MemUtilsFree(m_pTable[nIndex].sName); - } - } - MemUtilsFree(m_pTable); - } - - void NameToCharCode::Add(char *sName, CharCode nCode) - { - // Увеличиваем таблицу, в случае необходимости - if (m_nLen >= m_nSize / 2) - { - int nOldSize = m_nSize; - NameToCharCodeEntry *pOldTable = m_pTable; - m_nSize = 2 * m_nSize + 1; - m_pTable = (NameToCharCodeEntry *)MemUtilsMallocArray(m_nSize, sizeof(NameToCharCodeEntry)); - for (int nIndex = 0; nIndex < m_nSize; ++nIndex) - { - m_pTable[nIndex].sName = NULL; - } - for (int nIndex = 0; nIndex < nOldSize; ++nIndex) - { - if (pOldTable[nIndex].sName) - { - int nHash = Hash(pOldTable[nIndex].sName); - while (m_pTable[nHash].sName) - { - if (++nHash == m_nSize) - { - nHash = 0; - } - } - m_pTable[nHash] = pOldTable[nIndex]; - } - } - MemUtilsFree(pOldTable); - } - - // Добавляем новое имя - int nHash = Hash(sName); - while (m_pTable[nHash].sName && strcmp(m_pTable[nHash].sName, sName)) - { - if (++nHash == m_nSize) - { - nHash = 0; - } - } - if (!m_pTable[nHash].sName) - { - m_pTable[nHash].sName = CopyString(sName); - } - m_pTable[nHash].nCode = nCode; - - ++m_nLen; - } - - CharCode NameToCharCode::Lookup(char *sName) - { - int nHash = Hash(sName); - while (m_pTable[nHash].sName) - { - if (!strcmp(m_pTable[nHash].sName, sName)) - { - return m_pTable[nHash].nCode; - } - if (++nHash == m_nSize) - { - nHash = 0; - } - } - return 0; - } - - int NameToCharCode::Hash(char *sName) - { - char *pCur; - unsigned int unHash = 0; - for (pCur = sName; *pCur; ++pCur) - { - unHash = 17 * unHash + (int)(*pCur & 0xff); - } - return (int)(unHash % m_nSize); - } -} \ No newline at end of file diff --git a/PdfReader/old/NameToCharCode.h b/PdfReader/old/NameToCharCode.h deleted file mode 100644 index f700800cc8..0000000000 --- a/PdfReader/old/NameToCharCode.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_NAME_TO_CHAR_CODE_H -#define _PDF_READER_NAME_TO_CHAR_CODE_H - -#include "CharTypes.h" - -namespace PdfReader -{ - struct NameToCharCodeEntry; - - //------------------------------------------------------------------------------------------------------------------------------- - // NameToCharCode - //------------------------------------------------------------------------------------------------------------------------------- - - class NameToCharCode - { - public: - - NameToCharCode(); - ~NameToCharCode(); - - void Add(char *sName, CharCode nCode); - CharCode Lookup(char *sName); - - private: - - int Hash(char *sName); - - private: - - NameToCharCodeEntry *m_pTable; - int m_nSize; - int m_nLen; - }; -} - -#endif // _PDF_READER_NAME_TO_CHAR_CODE_H diff --git a/PdfReader/old/NameToUnicodeTable.h b/PdfReader/old/NameToUnicodeTable.h deleted file mode 100644 index e5f504ed50..0000000000 --- a/PdfReader/old/NameToUnicodeTable.h +++ /dev/null @@ -1,1130 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_NAME_TO_UNICODE_TABLE -#define _PDF_READER_NAME_TO_UNICODE_TABLE - -namespace PdfReader -{ - static struct - { - Unicode nUnicode; - char *sName; - } c_arrNameToUnicodeTable[] = - { - { 0x0021, "!" }, - { 0x0023, "#" }, - { 0x0024, "$" }, - { 0x0025, "%" }, - { 0x0026, "&" }, - { 0x0027, "'" }, - { 0x0028, "(" }, - { 0x0029, ")" }, - { 0x002a, "*" }, - { 0x002b, "+" }, - { 0x002c, "," }, - { 0x002d, "-" }, - { 0x002e, "." }, - { 0x002f, "/" }, - { 0x0030, "0" }, - { 0x0031, "1" }, - { 0x0032, "2" }, - { 0x0033, "3" }, - { 0x0034, "4" }, - { 0x0035, "5" }, - { 0x0036, "6" }, - { 0x0037, "7" }, - { 0x0038, "8" }, - { 0x0039, "9" }, - { 0x003a, ":" }, - { 0x003b, ";" }, - { 0x003c, "<" }, - { 0x003d, "=" }, - { 0x003e, ">" }, - { 0x003f, "?" }, - { 0x0040, "@" }, - { 0x0041, "A" }, - { 0x00c6, "AE" }, - { 0x01fc, "AEacute" }, - { 0xf7e6, "AEsmall" }, - { 0x00c1, "Aacute" }, - { 0xf7e1, "Aacutesmall" }, - { 0x0102, "Abreve" }, - { 0x00c2, "Acircumflex" }, - { 0xf7e2, "Acircumflexsmall" }, - { 0xf6c9, "Acute" }, - { 0xf7b4, "Acutesmall" }, - { 0x00c4, "Adieresis" }, - { 0xf7e4, "Adieresissmall" }, - { 0x00c0, "Agrave" }, - { 0xf7e0, "Agravesmall" }, - { 0x0391, "Alpha" }, - { 0x0386, "Alphatonos" }, - { 0x0100, "Amacron" }, - { 0x0104, "Aogonek" }, - { 0x00c5, "Aring" }, - { 0x01fa, "Aringacute" }, - { 0xf7e5, "Aringsmall" }, - { 0xf761, "Asmall" }, - { 0x00c3, "Atilde" }, - { 0xf7e3, "Atildesmall" }, - { 0x0042, "B" }, - { 0x0392, "Beta" }, - { 0xf6f4, "Brevesmall" }, - { 0xf762, "Bsmall" }, - { 0x0043, "C" }, - { 0x0106, "Cacute" }, - { 0xf6ca, "Caron" }, - { 0xf6f5, "Caronsmall" }, - { 0x010c, "Ccaron" }, - { 0x00c7, "Ccedilla" }, - { 0xf7e7, "Ccedillasmall" }, - { 0x0108, "Ccircumflex" }, - { 0x010a, "Cdotaccent" }, - { 0xf7b8, "Cedillasmall" }, - { 0x03a7, "Chi" }, - { 0xf6f6, "Circumflexsmall" }, - { 0xf763, "Csmall" }, - { 0x0044, "D" }, - { 0x010e, "Dcaron" }, - { 0x0110, "Dcroat" }, - { 0x2206, "Delta" }, - { 0xf6cb, "Dieresis" }, - { 0xf6cc, "DieresisAcute" }, - { 0xf6cd, "DieresisGrave" }, - { 0xf7a8, "Dieresissmall" }, - { 0xf6f7, "Dotaccentsmall" }, - { 0xf764, "Dsmall" }, - { 0x0045, "E" }, - { 0x00c9, "Eacute" }, - { 0xf7e9, "Eacutesmall" }, - { 0x0114, "Ebreve" }, - { 0x011a, "Ecaron" }, - { 0x00ca, "Ecircumflex" }, - { 0xf7ea, "Ecircumflexsmall" }, - { 0x00cb, "Edieresis" }, - { 0xf7eb, "Edieresissmall" }, - { 0x0116, "Edotaccent" }, - { 0x00c8, "Egrave" }, - { 0xf7e8, "Egravesmall" }, - { 0x0112, "Emacron" }, - { 0x014a, "Eng" }, - { 0x0118, "Eogonek" }, - { 0x0395, "Epsilon" }, - { 0x0388, "Epsilontonos" }, - { 0xf765, "Esmall" }, - { 0x0397, "Eta" }, - { 0x0389, "Etatonos" }, - { 0x00d0, "Eth" }, - { 0xf7f0, "Ethsmall" }, - { 0x20ac, "Euro" }, - { 0x0046, "F" }, - { 0xf766, "Fsmall" }, - { 0x0047, "G" }, - { 0x0393, "Gamma" }, - { 0x011e, "Gbreve" }, - { 0x01e6, "Gcaron" }, - { 0x011c, "Gcircumflex" }, - { 0x0122, "Gcommaaccent" }, - { 0x0120, "Gdotaccent" }, - { 0xf6ce, "Grave" }, - { 0xf760, "Gravesmall" }, - { 0xf767, "Gsmall" }, - { 0x0048, "H" }, - { 0x25cf, "H18533" }, - { 0x25aa, "H18543" }, - { 0x25ab, "H18551" }, - { 0x25a1, "H22073" }, - { 0x0126, "Hbar" }, - { 0x0124, "Hcircumflex" }, - { 0xf768, "Hsmall" }, - { 0xf6cf, "Hungarumlaut" }, - { 0xf6f8, "Hungarumlautsmall" }, - { 0x0049, "I" }, - { 0x0132, "IJ" }, - { 0x00cd, "Iacute" }, - { 0xf7ed, "Iacutesmall" }, - { 0x012c, "Ibreve" }, - { 0x00ce, "Icircumflex" }, - { 0xf7ee, "Icircumflexsmall" }, - { 0x00cf, "Idieresis" }, - { 0xf7ef, "Idieresissmall" }, - { 0x0130, "Idotaccent" }, - { 0x2111, "Ifraktur" }, - { 0x00cc, "Igrave" }, - { 0xf7ec, "Igravesmall" }, - { 0x012a, "Imacron" }, - { 0x012e, "Iogonek" }, - { 0x0399, "Iota" }, - { 0x03aa, "Iotadieresis" }, - { 0x038a, "Iotatonos" }, - { 0xf769, "Ismall" }, - { 0x0128, "Itilde" }, - { 0x004a, "J" }, - { 0x0134, "Jcircumflex" }, - { 0xf76a, "Jsmall" }, - { 0x004b, "K" }, - { 0x039a, "Kappa" }, - { 0x0136, "Kcommaaccent" }, - { 0xf76b, "Ksmall" }, - { 0x004c, "L" }, - { 0xf6bf, "LL" }, - { 0x0139, "Lacute" }, - { 0x039b, "Lambda" }, - { 0x013d, "Lcaron" }, - { 0x013b, "Lcommaaccent" }, - { 0x013f, "Ldot" }, - { 0x0141, "Lslash" }, - { 0xf6f9, "Lslashsmall" }, - { 0xf76c, "Lsmall" }, - { 0x004d, "M" }, - { 0xf6d0, "Macron" }, - { 0xf7af, "Macronsmall" }, - { 0xf76d, "Msmall" }, - { 0x039c, "Mu" }, - { 0x004e, "N" }, - { 0x0143, "Nacute" }, - { 0x0147, "Ncaron" }, - { 0x0145, "Ncommaaccent" }, - { 0xf76e, "Nsmall" }, - { 0x00d1, "Ntilde" }, - { 0xf7f1, "Ntildesmall" }, - { 0x039d, "Nu" }, - { 0x004f, "O" }, - { 0x0152, "OE" }, - { 0xf6fa, "OEsmall" }, - { 0x00d3, "Oacute" }, - { 0xf7f3, "Oacutesmall" }, - { 0x014e, "Obreve" }, - { 0x00d4, "Ocircumflex" }, - { 0xf7f4, "Ocircumflexsmall" }, - { 0x00d6, "Odieresis" }, - { 0xf7f6, "Odieresissmall" }, - { 0xf6fb, "Ogoneksmall" }, - { 0x00d2, "Ograve" }, - { 0xf7f2, "Ogravesmall" }, - { 0x01a0, "Ohorn" }, - { 0x0150, "Ohungarumlaut" }, - { 0x014c, "Omacron" }, - { 0x2126, "Omega" }, - { 0x038f, "Omegatonos" }, - { 0x039f, "Omicron" }, - { 0x038c, "Omicrontonos" }, - { 0x00d8, "Oslash" }, - { 0x01fe, "Oslashacute" }, - { 0xf7f8, "Oslashsmall" }, - { 0xf76f, "Osmall" }, - { 0x00d5, "Otilde" }, - { 0xf7f5, "Otildesmall" }, - { 0x0050, "P" }, - { 0x03a6, "Phi" }, - { 0x03a0, "Pi" }, - { 0x03a8, "Psi" }, - { 0xf770, "Psmall" }, - { 0x0051, "Q" }, - { 0xf771, "Qsmall" }, - { 0x0052, "R" }, - { 0x0154, "Racute" }, - { 0x0158, "Rcaron" }, - { 0x0156, "Rcommaaccent" }, - { 0x211c, "Rfraktur" }, - { 0x03a1, "Rho" }, - { 0xf6fc, "Ringsmall" }, - { 0xf772, "Rsmall" }, - { 0x0053, "S" }, - { 0x250c, "SF010000" }, - { 0x2514, "SF020000" }, - { 0x2510, "SF030000" }, - { 0x2518, "SF040000" }, - { 0x253c, "SF050000" }, - { 0x252c, "SF060000" }, - { 0x2534, "SF070000" }, - { 0x251c, "SF080000" }, - { 0x2524, "SF090000" }, - { 0x2500, "SF100000" }, - { 0x2502, "SF110000" }, - { 0x2561, "SF190000" }, - { 0x2562, "SF200000" }, - { 0x2556, "SF210000" }, - { 0x2555, "SF220000" }, - { 0x2563, "SF230000" }, - { 0x2551, "SF240000" }, - { 0x2557, "SF250000" }, - { 0x255d, "SF260000" }, - { 0x255c, "SF270000" }, - { 0x255b, "SF280000" }, - { 0x255e, "SF360000" }, - { 0x255f, "SF370000" }, - { 0x255a, "SF380000" }, - { 0x2554, "SF390000" }, - { 0x2569, "SF400000" }, - { 0x2566, "SF410000" }, - { 0x2560, "SF420000" }, - { 0x2550, "SF430000" }, - { 0x256c, "SF440000" }, - { 0x2567, "SF450000" }, - { 0x2568, "SF460000" }, - { 0x2564, "SF470000" }, - { 0x2565, "SF480000" }, - { 0x2559, "SF490000" }, - { 0x2558, "SF500000" }, - { 0x2552, "SF510000" }, - { 0x2553, "SF520000" }, - { 0x256b, "SF530000" }, - { 0x256a, "SF540000" }, - { 0x015a, "Sacute" }, - { 0x0160, "Scaron" }, - { 0xf6fd, "Scaronsmall" }, - { 0x015e, "Scedilla" }, - { 0x015c, "Scircumflex" }, - { 0x0218, "Scommaaccent" }, - { 0x03a3, "Sigma" }, - { 0xf773, "Ssmall" }, - { 0x0054, "T" }, - { 0x03a4, "Tau" }, - { 0x0166, "Tbar" }, - { 0x0164, "Tcaron" }, - { 0x0162, "Tcommaaccent" }, - { 0x0398, "Theta" }, - { 0x00de, "Thorn" }, - { 0xf7fe, "Thornsmall" }, - { 0xf6fe, "Tildesmall" }, - { 0xf774, "Tsmall" }, - { 0x0055, "U" }, - { 0x00da, "Uacute" }, - { 0xf7fa, "Uacutesmall" }, - { 0x016c, "Ubreve" }, - { 0x00db, "Ucircumflex" }, - { 0xf7fb, "Ucircumflexsmall" }, - { 0x00dc, "Udieresis" }, - { 0xf7fc, "Udieresissmall" }, - { 0x00d9, "Ugrave" }, - { 0xf7f9, "Ugravesmall" }, - { 0x01af, "Uhorn" }, - { 0x0170, "Uhungarumlaut" }, - { 0x016a, "Umacron" }, - { 0x0172, "Uogonek" }, - { 0x03a5, "Upsilon" }, - { 0x03d2, "Upsilon1" }, - { 0x03ab, "Upsilondieresis" }, - { 0x038e, "Upsilontonos" }, - { 0x016e, "Uring" }, - { 0xf775, "Usmall" }, - { 0x0168, "Utilde" }, - { 0x0056, "V" }, - { 0xf776, "Vsmall" }, - { 0x0057, "W" }, - { 0x1e82, "Wacute" }, - { 0x0174, "Wcircumflex" }, - { 0x1e84, "Wdieresis" }, - { 0x1e80, "Wgrave" }, - { 0xf777, "Wsmall" }, - { 0x0058, "X" }, - { 0x039e, "Xi" }, - { 0xf778, "Xsmall" }, - { 0x0059, "Y" }, - { 0x00dd, "Yacute" }, - { 0xf7fd, "Yacutesmall" }, - { 0x0176, "Ycircumflex" }, - { 0x0178, "Ydieresis" }, - { 0xf7ff, "Ydieresissmall" }, - { 0x1ef2, "Ygrave" }, - { 0xf779, "Ysmall" }, - { 0x005a, "Z" }, - { 0x0179, "Zacute" }, - { 0x017d, "Zcaron" }, - { 0xf6ff, "Zcaronsmall" }, - { 0x017b, "Zdotaccent" }, - { 0x0396, "Zeta" }, - { 0xf77a, "Zsmall" }, - { 0x0022, "\"" }, - { 0x005c, "\\" }, - { 0x005d, "]" }, - { 0x005e, "^" }, - { 0x005f, "_" }, - { 0x0060, "`" }, - { 0x0061, "a" }, - { 0x00e1, "aacute" }, - { 0x0103, "abreve" }, - { 0x00e2, "acircumflex" }, - { 0x00b4, "acute" }, - { 0x0301, "acutecomb" }, - { 0x00e4, "adieresis" }, - { 0x00e6, "ae" }, - { 0x01fd, "aeacute" }, - { 0x2015, "afii00208" }, - { 0x0410, "afii10017" }, - { 0x0411, "afii10018" }, - { 0x0412, "afii10019" }, - { 0x0413, "afii10020" }, - { 0x0414, "afii10021" }, - { 0x0415, "afii10022" }, - { 0x0401, "afii10023" }, - { 0x0416, "afii10024" }, - { 0x0417, "afii10025" }, - { 0x0418, "afii10026" }, - { 0x0419, "afii10027" }, - { 0x041a, "afii10028" }, - { 0x041b, "afii10029" }, - { 0x041c, "afii10030" }, - { 0x041d, "afii10031" }, - { 0x041e, "afii10032" }, - { 0x041f, "afii10033" }, - { 0x0420, "afii10034" }, - { 0x0421, "afii10035" }, - { 0x0422, "afii10036" }, - { 0x0423, "afii10037" }, - { 0x0424, "afii10038" }, - { 0x0425, "afii10039" }, - { 0x0426, "afii10040" }, - { 0x0427, "afii10041" }, - { 0x0428, "afii10042" }, - { 0x0429, "afii10043" }, - { 0x042a, "afii10044" }, - { 0x042b, "afii10045" }, - { 0x042c, "afii10046" }, - { 0x042d, "afii10047" }, - { 0x042e, "afii10048" }, - { 0x042f, "afii10049" }, - { 0x0490, "afii10050" }, - { 0x0402, "afii10051" }, - { 0x0403, "afii10052" }, - { 0x0404, "afii10053" }, - { 0x0405, "afii10054" }, - { 0x0406, "afii10055" }, - { 0x0407, "afii10056" }, - { 0x0408, "afii10057" }, - { 0x0409, "afii10058" }, - { 0x040a, "afii10059" }, - { 0x040b, "afii10060" }, - { 0x040c, "afii10061" }, - { 0x040e, "afii10062" }, - { 0xf6c4, "afii10063" }, - { 0xf6c5, "afii10064" }, - { 0x0430, "afii10065" }, - { 0x0431, "afii10066" }, - { 0x0432, "afii10067" }, - { 0x0433, "afii10068" }, - { 0x0434, "afii10069" }, - { 0x0435, "afii10070" }, - { 0x0451, "afii10071" }, - { 0x0436, "afii10072" }, - { 0x0437, "afii10073" }, - { 0x0438, "afii10074" }, - { 0x0439, "afii10075" }, - { 0x043a, "afii10076" }, - { 0x043b, "afii10077" }, - { 0x043c, "afii10078" }, - { 0x043d, "afii10079" }, - { 0x043e, "afii10080" }, - { 0x043f, "afii10081" }, - { 0x0440, "afii10082" }, - { 0x0441, "afii10083" }, - { 0x0442, "afii10084" }, - { 0x0443, "afii10085" }, - { 0x0444, "afii10086" }, - { 0x0445, "afii10087" }, - { 0x0446, "afii10088" }, - { 0x0447, "afii10089" }, - { 0x0448, "afii10090" }, - { 0x0449, "afii10091" }, - { 0x044a, "afii10092" }, - { 0x044b, "afii10093" }, - { 0x044c, "afii10094" }, - { 0x044d, "afii10095" }, - { 0x044e, "afii10096" }, - { 0x044f, "afii10097" }, - { 0x0491, "afii10098" }, - { 0x0452, "afii10099" }, - { 0x0453, "afii10100" }, - { 0x0454, "afii10101" }, - { 0x0455, "afii10102" }, - { 0x0456, "afii10103" }, - { 0x0457, "afii10104" }, - { 0x0458, "afii10105" }, - { 0x0459, "afii10106" }, - { 0x045a, "afii10107" }, - { 0x045b, "afii10108" }, - { 0x045c, "afii10109" }, - { 0x045e, "afii10110" }, - { 0x040f, "afii10145" }, - { 0x0462, "afii10146" }, - { 0x0472, "afii10147" }, - { 0x0474, "afii10148" }, - { 0xf6c6, "afii10192" }, - { 0x045f, "afii10193" }, - { 0x0463, "afii10194" }, - { 0x0473, "afii10195" }, - { 0x0475, "afii10196" }, - { 0xf6c7, "afii10831" }, - { 0xf6c8, "afii10832" }, - { 0x04d9, "afii10846" }, - { 0x200e, "afii299" }, - { 0x200f, "afii300" }, - { 0x200d, "afii301" }, - { 0x066a, "afii57381" }, - { 0x060c, "afii57388" }, - { 0x0660, "afii57392" }, - { 0x0661, "afii57393" }, - { 0x0662, "afii57394" }, - { 0x0663, "afii57395" }, - { 0x0664, "afii57396" }, - { 0x0665, "afii57397" }, - { 0x0666, "afii57398" }, - { 0x0667, "afii57399" }, - { 0x0668, "afii57400" }, - { 0x0669, "afii57401" }, - { 0x061b, "afii57403" }, - { 0x061f, "afii57407" }, - { 0x0621, "afii57409" }, - { 0x0622, "afii57410" }, - { 0x0623, "afii57411" }, - { 0x0624, "afii57412" }, - { 0x0625, "afii57413" }, - { 0x0626, "afii57414" }, - { 0x0627, "afii57415" }, - { 0x0628, "afii57416" }, - { 0x0629, "afii57417" }, - { 0x062a, "afii57418" }, - { 0x062b, "afii57419" }, - { 0x062c, "afii57420" }, - { 0x062d, "afii57421" }, - { 0x062e, "afii57422" }, - { 0x062f, "afii57423" }, - { 0x0630, "afii57424" }, - { 0x0631, "afii57425" }, - { 0x0632, "afii57426" }, - { 0x0633, "afii57427" }, - { 0x0634, "afii57428" }, - { 0x0635, "afii57429" }, - { 0x0636, "afii57430" }, - { 0x0637, "afii57431" }, - { 0x0638, "afii57432" }, - { 0x0639, "afii57433" }, - { 0x063a, "afii57434" }, - { 0x0640, "afii57440" }, - { 0x0641, "afii57441" }, - { 0x0642, "afii57442" }, - { 0x0643, "afii57443" }, - { 0x0644, "afii57444" }, - { 0x0645, "afii57445" }, - { 0x0646, "afii57446" }, - { 0x0648, "afii57448" }, - { 0x0649, "afii57449" }, - { 0x064a, "afii57450" }, - { 0x064b, "afii57451" }, - { 0x064c, "afii57452" }, - { 0x064d, "afii57453" }, - { 0x064e, "afii57454" }, - { 0x064f, "afii57455" }, - { 0x0650, "afii57456" }, - { 0x0651, "afii57457" }, - { 0x0652, "afii57458" }, - { 0x0647, "afii57470" }, - { 0x06a4, "afii57505" }, - { 0x067e, "afii57506" }, - { 0x0686, "afii57507" }, - { 0x0698, "afii57508" }, - { 0x06af, "afii57509" }, - { 0x0679, "afii57511" }, - { 0x0688, "afii57512" }, - { 0x0691, "afii57513" }, - { 0x06ba, "afii57514" }, - { 0x06d2, "afii57519" }, - { 0x06d5, "afii57534" }, - { 0x20aa, "afii57636" }, - { 0x05be, "afii57645" }, - { 0x05c3, "afii57658" }, - { 0x05d0, "afii57664" }, - { 0x05d1, "afii57665" }, - { 0x05d2, "afii57666" }, - { 0x05d3, "afii57667" }, - { 0x05d4, "afii57668" }, - { 0x05d5, "afii57669" }, - { 0x05d6, "afii57670" }, - { 0x05d7, "afii57671" }, - { 0x05d8, "afii57672" }, - { 0x05d9, "afii57673" }, - { 0x05da, "afii57674" }, - { 0x05db, "afii57675" }, - { 0x05dc, "afii57676" }, - { 0x05dd, "afii57677" }, - { 0x05de, "afii57678" }, - { 0x05df, "afii57679" }, - { 0x05e0, "afii57680" }, - { 0x05e1, "afii57681" }, - { 0x05e2, "afii57682" }, - { 0x05e3, "afii57683" }, - { 0x05e4, "afii57684" }, - { 0x05e5, "afii57685" }, - { 0x05e6, "afii57686" }, - { 0x05e7, "afii57687" }, - { 0x05e8, "afii57688" }, - { 0x05e9, "afii57689" }, - { 0x05ea, "afii57690" }, - { 0xfb2a, "afii57694" }, - { 0xfb2b, "afii57695" }, - { 0xfb4b, "afii57700" }, - { 0xfb1f, "afii57705" }, - { 0x05f0, "afii57716" }, - { 0x05f1, "afii57717" }, - { 0x05f2, "afii57718" }, - { 0xfb35, "afii57723" }, - { 0x05b4, "afii57793" }, - { 0x05b5, "afii57794" }, - { 0x05b6, "afii57795" }, - { 0x05bb, "afii57796" }, - { 0x05b8, "afii57797" }, - { 0x05b7, "afii57798" }, - { 0x05b0, "afii57799" }, - { 0x05b2, "afii57800" }, - { 0x05b1, "afii57801" }, - { 0x05b3, "afii57802" }, - { 0x05c2, "afii57803" }, - { 0x05c1, "afii57804" }, - { 0x05b9, "afii57806" }, - { 0x05bc, "afii57807" }, - { 0x05bd, "afii57839" }, - { 0x05bf, "afii57841" }, - { 0x05c0, "afii57842" }, - { 0x02bc, "afii57929" }, - { 0x2105, "afii61248" }, - { 0x2113, "afii61289" }, - { 0x2116, "afii61352" }, - { 0x202c, "afii61573" }, - { 0x202d, "afii61574" }, - { 0x202e, "afii61575" }, - { 0x200c, "afii61664" }, - { 0x066d, "afii63167" }, - { 0x02bd, "afii64937" }, - { 0x00e0, "agrave" }, - { 0x2135, "aleph" }, - { 0x03b1, "alpha" }, - { 0x03ac, "alphatonos" }, - { 0x0101, "amacron" }, - { 0x0026, "ampersand" }, - { 0xf726, "ampersandsmall" }, - { 0x2220, "angle" }, - { 0x2329, "angleleft" }, - { 0x232a, "angleright" }, - { 0x0387, "anoteleia" }, - { 0x0105, "aogonek" }, - { 0x2248, "approxequal" }, - { 0x00e5, "aring" }, - { 0x01fb, "aringacute" }, - { 0x2194, "arrowboth" }, - { 0x21d4, "arrowdblboth" }, - { 0x21d3, "arrowdbldown" }, - { 0x21d0, "arrowdblleft" }, - { 0x21d2, "arrowdblright" }, - { 0x21d1, "arrowdblup" }, - { 0x2193, "arrowdown" }, - { 0xf8e7, "arrowhorizex" }, - { 0x2190, "arrowleft" }, - { 0x2192, "arrowright" }, - { 0x2191, "arrowup" }, - { 0x2195, "arrowupdn" }, - { 0x21a8, "arrowupdnbse" }, - { 0xf8e6, "arrowvertex" }, - { 0x005e, "asciicircum" }, - { 0x007e, "asciitilde" }, - { 0x002a, "asterisk" }, - { 0x2217, "asteriskmath" }, - { 0xf6e9, "asuperior" }, - { 0x0040, "at" }, - { 0x00e3, "atilde" }, - { 0x0062, "b" }, - { 0x005c, "backslash" }, - { 0x007c, "bar" }, - { 0x03b2, "beta" }, - { 0x2588, "block" }, - { 0xf8f4, "braceex" }, - { 0x007b, "braceleft" }, - { 0xf8f3, "braceleftbt" }, - { 0xf8f2, "braceleftmid" }, - { 0xf8f1, "bracelefttp" }, - { 0x007d, "braceright" }, - { 0xf8fe, "bracerightbt" }, - { 0xf8fd, "bracerightmid" }, - { 0xf8fc, "bracerighttp" }, - { 0x005b, "bracketleft" }, - { 0xf8f0, "bracketleftbt" }, - { 0xf8ef, "bracketleftex" }, - { 0xf8ee, "bracketlefttp" }, - { 0x005d, "bracketright" }, - { 0xf8fb, "bracketrightbt" }, - { 0xf8fa, "bracketrightex" }, - { 0xf8f9, "bracketrighttp" }, - { 0x02d8, "breve" }, - { 0x00a6, "brokenbar" }, - { 0xf6ea, "bsuperior" }, - { 0x2022, "bullet" }, - { 0x0063, "c" }, - { 0x0107, "cacute" }, - { 0x02c7, "caron" }, - { 0x21b5, "carriagereturn" }, - { 0x010d, "ccaron" }, - { 0x00e7, "ccedilla" }, - { 0x0109, "ccircumflex" }, - { 0x010b, "cdotaccent" }, - { 0x00b8, "cedilla" }, - { 0x00a2, "cent" }, - { 0xf6df, "centinferior" }, - { 0xf7a2, "centoldstyle" }, - { 0xf6e0, "centsuperior" }, - { 0x03c7, "chi" }, - { 0x25cb, "circle" }, - { 0x2297, "circlemultiply" }, - { 0x2295, "circleplus" }, - { 0x02c6, "circumflex" }, - { 0x2663, "club" }, - { 0x003a, "colon" }, - { 0x20a1, "colonmonetary" }, - { 0x002c, "comma" }, - { 0xf6c3, "commaaccent" }, - { 0xf6e1, "commainferior" }, - { 0xf6e2, "commasuperior" }, - { 0x2245, "congruent" }, - { 0x00a9, "copyright" }, - { 0x00a9, "copyrightsans" }, - { 0x00a9, "copyrightserif" }, - { 0x00a4, "currency" }, - { 0xf6d1, "cyrBreve" }, - { 0xf6d2, "cyrFlex" }, - { 0xf6d4, "cyrbreve" }, - { 0xf6d5, "cyrflex" }, - { 0x0064, "d" }, - { 0x2020, "dagger" }, - { 0x2021, "daggerdbl" }, - { 0xf6d3, "dblGrave" }, - { 0xf6d6, "dblgrave" }, - { 0x010f, "dcaron" }, - { 0x0111, "dcroat" }, - { 0x00b0, "degree" }, - { 0x03b4, "delta" }, - { 0x2666, "diamond" }, - { 0x00a8, "dieresis" }, - { 0xf6d7, "dieresisacute" }, - { 0xf6d8, "dieresisgrave" }, - { 0x0385, "dieresistonos" }, - { 0x00f7, "divide" }, - { 0x2593, "dkshade" }, - { 0x2584, "dnblock" }, - { 0x0024, "dollar" }, - { 0xf6e3, "dollarinferior" }, - { 0xf724, "dollaroldstyle" }, - { 0xf6e4, "dollarsuperior" }, - { 0x20ab, "dong" }, - { 0x02d9, "dotaccent" }, - { 0x0323, "dotbelowcomb" }, - { 0x0131, "dotlessi" }, - { 0xf6be, "dotlessj" }, - { 0x22c5, "dotmath" }, - { 0xf6eb, "dsuperior" }, - { 0x0065, "e" }, - { 0x00e9, "eacute" }, - { 0x0115, "ebreve" }, - { 0x011b, "ecaron" }, - { 0x00ea, "ecircumflex" }, - { 0x00eb, "edieresis" }, - { 0x0117, "edotaccent" }, - { 0x00e8, "egrave" }, - { 0x0038, "eight" }, - { 0x2088, "eightinferior" }, - { 0xf738, "eightoldstyle" }, - { 0x2078, "eightsuperior" }, - { 0x2208, "element" }, - { 0x2026, "ellipsis" }, - { 0x0113, "emacron" }, - { 0x2014, "emdash" }, - { 0x2205, "emptyset" }, - { 0x2013, "endash" }, - { 0x014b, "eng" }, - { 0x0119, "eogonek" }, - { 0x03b5, "epsilon" }, - { 0x03ad, "epsilontonos" }, - { 0x003d, "equal" }, - { 0x2261, "equivalence" }, - { 0x212e, "estimated" }, - { 0xf6ec, "esuperior" }, - { 0x03b7, "eta" }, - { 0x03ae, "etatonos" }, - { 0x00f0, "eth" }, - { 0x0021, "exclam" }, - { 0x203c, "exclamdbl" }, - { 0x00a1, "exclamdown" }, - { 0xf7a1, "exclamdownsmall" }, - { 0x0021, "exclamleft" }, - { 0xf721, "exclamsmall" }, - { 0x2203, "existential" }, - { 0x0066, "f" }, - { 0x2640, "female" }, - { 0xfb00, "ff" }, - { 0xfb03, "ffi" }, - { 0xfb04, "ffl" }, - { 0xfb01, "fi" }, - { 0x2012, "figuredash" }, - { 0x25a0, "filledbox" }, - { 0x25ac, "filledrect" }, - { 0x0035, "five" }, - { 0x215d, "fiveeighths" }, - { 0x2085, "fiveinferior" }, - { 0xf735, "fiveoldstyle" }, - { 0x2075, "fivesuperior" }, - { 0xfb02, "fl" }, - { 0x0192, "florin" }, - { 0x0034, "four" }, - { 0x2084, "fourinferior" }, - { 0xf734, "fouroldstyle" }, - { 0x2074, "foursuperior" }, - { 0x2044, "fraction" }, - { 0x20a3, "franc" }, - { 0x0067, "g" }, - { 0x03b3, "gamma" }, - { 0x011f, "gbreve" }, - { 0x01e7, "gcaron" }, - { 0x011d, "gcircumflex" }, - { 0x0123, "gcommaaccent" }, - { 0x0121, "gdotaccent" }, - { 0x00df, "germandbls" }, - { 0x2207, "gradient" }, - { 0x0060, "grave" }, - { 0x0300, "gravecomb" }, - { 0x003e, "greater" }, - { 0x2265, "greaterequal" }, - { 0x00ab, "guillemotleft" }, - { 0x00bb, "guillemotright" }, - { 0x2039, "guilsinglleft" }, - { 0x203a, "guilsinglright" }, - { 0x0068, "h" }, - { 0x0127, "hbar" }, - { 0x0125, "hcircumflex" }, - { 0x2665, "heart" }, - { 0x0309, "hookabovecomb" }, - { 0x2302, "house" }, - { 0x02dd, "hungarumlaut" }, - { 0x002d, "hyphen" }, - { 0xf6e5, "hypheninferior" }, - { 0xf6e6, "hyphensuperior" }, - { 0x0069, "i" }, - { 0x00ed, "iacute" }, - { 0x012d, "ibreve" }, - { 0x00ee, "icircumflex" }, - { 0x00ef, "idieresis" }, - { 0x00ec, "igrave" }, - { 0x0133, "ij" }, - { 0x012b, "imacron" }, - { 0x221e, "infinity" }, - { 0x222b, "integral" }, - { 0x2321, "integralbt" }, - { 0xf8f5, "integralex" }, - { 0x2320, "integraltp" }, - { 0x2229, "intersection" }, - { 0x25d8, "invbullet" }, - { 0x25d9, "invcircle" }, - { 0x263b, "invsmileface" }, - { 0x012f, "iogonek" }, - { 0x03b9, "iota" }, - { 0x03ca, "iotadieresis" }, - { 0x0390, "iotadieresistonos" }, - { 0x03af, "iotatonos" }, - { 0xf6ed, "isuperior" }, - { 0x0129, "itilde" }, - { 0x006a, "j" }, - { 0x0135, "jcircumflex" }, - { 0x006b, "k" }, - { 0x03ba, "kappa" }, - { 0x0137, "kcommaaccent" }, - { 0x0138, "kgreenlandic" }, - { 0x006c, "l" }, - { 0x013a, "lacute" }, - { 0x03bb, "lambda" }, - { 0x013e, "lcaron" }, - { 0x013c, "lcommaaccent" }, - { 0x0140, "ldot" }, - { 0x003c, "less" }, - { 0x2264, "lessequal" }, - { 0x258c, "lfblock" }, - { 0x20a4, "lira" }, - { 0xf6c0, "ll" }, - { 0x2227, "logicaland" }, - { 0x00ac, "logicalnot" }, - { 0x2228, "logicalor" }, - { 0x017f, "longs" }, - { 0x25ca, "lozenge" }, - { 0x0142, "lslash" }, - { 0xf6ee, "lsuperior" }, - { 0x2591, "ltshade" }, - { 0x006d, "m" }, - { 0x00af, "macron" }, - { 0x2642, "male" }, - { 0x2212, "minus" }, - { 0x2032, "minute" }, - { 0xf6ef, "msuperior" }, - { 0x00b5, "mu" }, - { 0x00d7, "multiply" }, - { 0x266a, "musicalnote" }, - { 0x266b, "musicalnotedbl" }, - { 0x006e, "n" }, - { 0x0144, "nacute" }, - { 0x0149, "napostrophe" }, - { 0x00a0, "nbspace" }, - { 0x0148, "ncaron" }, - { 0x0146, "ncommaaccent" }, - { 0x0039, "nine" }, - { 0x2089, "nineinferior" }, - { 0xf739, "nineoldstyle" }, - { 0x2079, "ninesuperior" }, - { 0x00a0, "nonbreakingspace" }, - { 0x2209, "notelement" }, - { 0x2260, "notequal" }, - { 0x2284, "notsubset" }, - { 0x207f, "nsuperior" }, - { 0x00f1, "ntilde" }, - { 0x03bd, "nu" }, - { 0x0023, "numbersign" }, - { 0x006f, "o" }, - { 0x00f3, "oacute" }, - { 0x014f, "obreve" }, - { 0x00f4, "ocircumflex" }, - { 0x00f6, "odieresis" }, - { 0x0153, "oe" }, - { 0x02db, "ogonek" }, - { 0x00f2, "ograve" }, - { 0x01a1, "ohorn" }, - { 0x0151, "ohungarumlaut" }, - { 0x014d, "omacron" }, - { 0x03c9, "omega" }, - { 0x03d6, "omega1" }, - { 0x03ce, "omegatonos" }, - { 0x03bf, "omicron" }, - { 0x03cc, "omicrontonos" }, - { 0x0031, "one" }, - { 0x2024, "onedotenleader" }, - { 0x215b, "oneeighth" }, - { 0xf6dc, "onefitted" }, - { 0x00bd, "onehalf" }, - { 0x2081, "oneinferior" }, - { 0xf731, "oneoldstyle" }, - { 0x00bc, "onequarter" }, - { 0x00b9, "onesuperior" }, - { 0x2153, "onethird" }, - { 0x25e6, "openbullet" }, - { 0x00aa, "ordfeminine" }, - { 0x00ba, "ordmasculine" }, - { 0x221f, "orthogonal" }, - { 0x00f8, "oslash" }, - { 0x01ff, "oslashacute" }, - { 0xf6f0, "osuperior" }, - { 0x00f5, "otilde" }, - { 0x0070, "p" }, - { 0x00b6, "paragraph" }, - { 0x0028, "parenleft" }, - { 0xf8ed, "parenleftbt" }, - { 0xf8ec, "parenleftex" }, - { 0x208d, "parenleftinferior" }, - { 0x207d, "parenleftsuperior" }, - { 0xf8eb, "parenlefttp" }, - { 0x0029, "parenright" }, - { 0xf8f8, "parenrightbt" }, - { 0xf8f7, "parenrightex" }, - { 0x208e, "parenrightinferior" }, - { 0x207e, "parenrightsuperior" }, - { 0xf8f6, "parenrighttp" }, - { 0x2202, "partialdiff" }, - { 0x0025, "percent" }, - { 0x002e, "period" }, - { 0x00b7, "periodcentered" }, - { 0xf6e7, "periodinferior" }, - { 0xf6e8, "periodsuperior" }, - { 0x22a5, "perpendicular" }, - { 0x2030, "perthousand" }, - { 0x20a7, "peseta" }, - { 0x03c6, "phi" }, - { 0x03d5, "phi1" }, - { 0x03c0, "pi" }, - { 0x002b, "plus" }, - { 0x00b1, "plusminus" }, - { 0x211e, "prescription" }, - { 0x220f, "product" }, - { 0x2282, "propersubset" }, - { 0x2283, "propersuperset" }, - { 0x221d, "proportional" }, - { 0x03c8, "psi" }, - { 0x0071, "q" }, - { 0x003f, "question" }, - { 0x00bf, "questiondown" }, - { 0xf7bf, "questiondownsmall" }, - { 0xf73f, "questionsmall" }, - { 0x0022, "quotedbl" }, - { 0x201e, "quotedblbase" }, - { 0x201c, "quotedblleft" }, - { 0x201d, "quotedblright" }, - { 0x2018, "quoteleft" }, - { 0x201b, "quotereversed" }, - { 0x2019, "quoteright" }, - { 0x201a, "quotesinglbase" }, - { 0x0027, "quotesingle" }, - { 0x0072, "r" }, - { 0x0155, "racute" }, - { 0x221a, "radical" }, - { 0xf8e5, "radicalex" }, - { 0x0159, "rcaron" }, - { 0x0157, "rcommaaccent" }, - { 0x2286, "reflexsubset" }, - { 0x2287, "reflexsuperset" }, - { 0x00ae, "registered" }, - { 0x00ae, "registersans" }, - { 0x00ae, "registerserif" }, - { 0x2310, "revlogicalnot" }, - { 0x03c1, "rho" }, - { 0x02da, "ring" }, - { 0xf6f1, "rsuperior" }, - { 0x2590, "rtblock" }, - { 0xf6dd, "rupiah" }, - { 0x0073, "s" }, - { 0x015b, "sacute" }, - { 0x0161, "scaron" }, - { 0x015f, "scedilla" }, - { 0x015d, "scircumflex" }, - { 0x0219, "scommaaccent" }, - { 0x2033, "second" }, - { 0x00a7, "section" }, - { 0x003b, "semicolon" }, - { 0x0037, "seven" }, - { 0x215e, "seveneighths" }, - { 0x2087, "seveninferior" }, - { 0xf737, "sevenoldstyle" }, - { 0x2077, "sevensuperior" }, - { 0x2592, "shade" }, - { 0x03c3, "sigma" }, - { 0x03c2, "sigma1" }, - { 0x223c, "similar" }, - { 0x0036, "six" }, - { 0x2086, "sixinferior" }, - { 0xf736, "sixoldstyle" }, - { 0x2076, "sixsuperior" }, - { 0x002f, "slash" }, - { 0x263a, "smileface" }, - { 0x0020, "space" }, - { 0x2660, "spade" }, - { 0xf6f2, "ssuperior" }, - { 0x00a3, "sterling" }, - { 0x220b, "suchthat" }, - { 0x2211, "summation" }, - { 0x263c, "sun" }, - { 0x0074, "t" }, - { 0x03c4, "tau" }, - { 0x0167, "tbar" }, - { 0x0165, "tcaron" }, - { 0x0163, "tcommaaccent" }, - { 0x2234, "therefore" }, - { 0x03b8, "theta" }, - { 0x03d1, "theta1" }, - { 0x00fe, "thorn" }, - { 0x0033, "three" }, - { 0x215c, "threeeighths" }, - { 0x2083, "threeinferior" }, - { 0xf733, "threeoldstyle" }, - { 0x00be, "threequarters" }, - { 0xf6de, "threequartersemdash" }, - { 0x00b3, "threesuperior" }, - { 0x02dc, "tilde" }, - { 0x0303, "tildecomb" }, - { 0x0384, "tonos" }, - { 0x2122, "trademark" }, - { 0x2122, "trademarksans" }, - { 0x2122, "trademarkserif" }, - { 0x25bc, "triagdn" }, - { 0x25c4, "triaglf" }, - { 0x25ba, "triagrt" }, - { 0x25b2, "triagup" }, - { 0xf6f3, "tsuperior" }, - { 0x0032, "two" }, - { 0x2025, "twodotenleader" }, - { 0x2082, "twoinferior" }, - { 0xf732, "twooldstyle" }, - { 0x00b2, "twosuperior" }, - { 0x2154, "twothirds" }, - { 0x0075, "u" }, - { 0x00fa, "uacute" }, - { 0x016d, "ubreve" }, - { 0x00fb, "ucircumflex" }, - { 0x00fc, "udieresis" }, - { 0x00f9, "ugrave" }, - { 0x01b0, "uhorn" }, - { 0x0171, "uhungarumlaut" }, - { 0x016b, "umacron" }, - { 0x005f, "underscore" }, - { 0x2017, "underscoredbl" }, - { 0x222a, "union" }, - { 0x2200, "universal" }, - { 0x0173, "uogonek" }, - { 0x2580, "upblock" }, - { 0x03c5, "upsilon" }, - { 0x03cb, "upsilondieresis" }, - { 0x03b0, "upsilondieresistonos" }, - { 0x03cd, "upsilontonos" }, - { 0x016f, "uring" }, - { 0x0169, "utilde" }, - { 0x0076, "v" }, - { 0x0077, "w" }, - { 0x1e83, "wacute" }, - { 0x0175, "wcircumflex" }, - { 0x1e85, "wdieresis" }, - { 0x2118, "weierstrass" }, - { 0x1e81, "wgrave" }, - { 0x0078, "x" }, - { 0x03be, "xi" }, - { 0x0079, "y" }, - { 0x00fd, "yacute" }, - { 0x0177, "ycircumflex" }, - { 0x00ff, "ydieresis" }, - { 0x00a5, "yen" }, - { 0x1ef3, "ygrave" }, - { 0x007a, "z" }, - { 0x017a, "zacute" }, - { 0x017e, "zcaron" }, - { 0x017c, "zdotaccent" }, - { 0x0030, "zero" }, - { 0x2080, "zeroinferior" }, - { 0xf730, "zerooldstyle" }, - { 0x2070, "zerosuperior" }, - { 0x03b6, "zeta" }, - { 0x007b, "{" }, - { 0x007c, "|" }, - { 0x007d, "}" }, - { 0x007e, "~" }, - { 0, NULL } - }; -} - -#endif // _PDF_READER_NAME_TO_UNICODE_TABLE \ No newline at end of file diff --git a/PdfReader/old/Object.cpp b/PdfReader/old/Object.cpp deleted file mode 100644 index 115a22cfda..0000000000 --- a/PdfReader/old/Object.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "Object.h" -#include "Array.h" -#include "Dict.h" -#include "Stream.h" -#include "XRef.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Object - //------------------------------------------------------------------------ - - char *c_sObjectsTypeNames[NumObjTypes] = - { - "boolean", - "integer", - "real", - "string", - "name", - "null", - "array", - "dictionary", - "stream", - "ref", - "cmd", - "error", - "eof", - "none" - }; - - Object *Object::InitArray(XRef *pXref) - { - m_eType = objArray; - m_uArray = new Array(pXref); - return this; - } - - Object *Object::InitDict(XRef *pXref) - { - m_eType = objDict; - m_uDict = new Dict(pXref); - return this; - } - - Object *Object::InitDict(Dict *pDict) - { - m_eType = objDict; - m_uDict = pDict; - m_uDict->AddRef(); - return this; - } - - Object *Object::InitStream(Stream *pStream) - { - m_eType = objStream; - m_uStream = pStream; - return this; - } - - Object *Object::Copy(Object *pObject) - { - *pObject = *this; - switch (m_eType) - { - case objString: - pObject->m_uStringExt = m_uStringExt->Copy(); - break; - case objName: - pObject->m_uName = CopyString(m_uName); - break; - case objArray: - m_uArray->AddRef(); - break; - case objDict: - m_uDict->AddRef(); - break; - case objStream: - m_uStream->AddRef(); - break; - case objCommand: - pObject->m_uCommand = CopyString(m_uCommand); - break; - default: - break; - } - return pObject; - } - - Object *Object::Fetch(XRef *pXref, Object *pObject) - { - return (m_eType == objRef && pXref) ? pXref->Fetch(m_uRef.nNum, m_uRef.nGen, pObject) : Copy(pObject); - } - - void Object::Free() - { - switch (m_eType) - { - case objString: - delete m_uStringExt; - break; - case objName: - MemUtilsFree(m_uName); - break; - case objArray: - if (!m_uArray->Release()) - { - delete m_uArray; - } - break; - case objDict: - if (!m_uDict->Release()) - { - delete m_uDict; - } - break; - case objStream: - if (!m_uStream->Release()) - { - delete m_uStream; - } - break; - case objCommand: - MemUtilsFree(m_uCommand); - break; - default: - break; - } - m_eType = objNone; - } - - char *Object::GetTypeName() - { - return c_sObjectsTypeNames[m_eType]; - } - - void Object::Print(FILE *pFile) - { - Object oTemp; - - switch (m_eType) - { - case objBool: - fprintf(pFile, "%s", m_uBool ? "true" : "false"); - break; - case objInt: - fprintf(pFile, "%d", m_uInt); - break; - case objReal: - fprintf(pFile, "%g", m_uReal); - break; - case objString: - fprintf(pFile, "("); - fwrite(m_uStringExt->GetBuffer(), 1, m_uStringExt->GetLength(), pFile); - fprintf(pFile, ")"); - break; - case objName: - fprintf(pFile, "/%s", m_uName); - break; - case objNull: - fprintf(pFile, "null"); - break; - case objArray: - fprintf(pFile, "["); - for (int nIndex = 0; nIndex < ArrayGetLength(); ++nIndex) - { - if (nIndex > 0) - fprintf(pFile, " "); - ArrayGetCopy(nIndex, &oTemp); - oTemp.Print(pFile); - oTemp.Free(); - } - fprintf(pFile, "]"); - break; - case objDict: - fprintf(pFile, "<<"); - for (int nIndex = 0; nIndex < DictGetLength(); ++nIndex) - { - fprintf(pFile, " /%s ", DictGetKey(nIndex)); - DictGetValueCopy(nIndex, &oTemp); - oTemp.Print(pFile); - oTemp.Free(); - } - fprintf(pFile, " >>"); - break; - case objStream: - fprintf(pFile, ""); - break; - case objRef: - fprintf(pFile, "%d %d R", m_uRef.nNum, m_uRef.nGen); - break; - case objCommand: - fprintf(pFile, "%s", m_uCommand); - break; - case objError: - fprintf(pFile, ""); - break; - case objEOF: - fprintf(pFile, ""); - break; - case objNone: - fprintf(pFile, ""); - break; - } - } - void Object::ToXml(std::wstring& wsXml) - { - Object oTemp; - switch (m_eType) - { - case objBool: - wsXml += m_uBool ? L"true" : L"false"; - break; - case objInt: - wsXml += std::to_wstring(m_uInt); - break; - case objReal: - wsXml += std::to_wstring(m_uReal); - break; - case objString: - { - wsXml += L"("; - std::wstring wsValue = m_uStringExt->GetWString(); - ReplaceAll(wsValue, L"\"", L"""); - ReplaceAll(wsValue, L"&", L"&"); - ReplaceAll(wsValue, L"<", L"<"); - ReplaceAll(wsValue, L">", L">"); - wsXml += wsValue; - wsXml += L")"; - break; - } - case objName: - wsXml += L"/"; - AppendStringToXml(wsXml, m_uName); - break; - case objNull: - wsXml += L"null"; - break; - case objArray: - wsXml += L"["; - for (int nIndex = 0; nIndex < ArrayGetLength(); ++nIndex) - { - if (nIndex > 0) - wsXml += L" "; - - ArrayGetCopy(nIndex, &oTemp); - oTemp.ToXml(wsXml); - oTemp.Free(); - } - wsXml += L"]"; - break; - case objDict: - for (int nIndex = 0; nIndex < DictGetLength(); ++nIndex) - { - char* sKey = DictGetKey(nIndex); - wsXml += L"<"; - AppendStringToXml(wsXml, sKey); - wsXml += L">"; - DictGetValueCopy(nIndex, &oTemp); - oTemp.ToXml(wsXml); - oTemp.Free(); - wsXml += L""; - } - break; - case objStream: - wsXml += L""; - // TODO: Запись стрима - break; - case objRef: - wsXml += std::to_wstring(m_uRef.nNum); - wsXml += L" "; - wsXml += std::to_wstring(m_uRef.nGen); - wsXml += L" R"; - break; - case objCommand: - AppendStringToXml(wsXml, m_uCommand); - break; - case objError: - wsXml += L"error"; - break; - case objEOF: - wsXml += L"EOF"; - break; - case objNone: - wsXml += L"none"; - break; - } - } - void Object::AppendStringToXml(std::wstring& wsXml, const std::string& sString) - { - std::wstring wsTmp(sString.begin(), sString.end()); - wsXml += wsTmp; - } - - void Object::ReplaceAll(std::wstring& wsString, const std::wstring& wsFrom, const std::wstring& wsTo) - { - size_t nStartPos = 0; - while((nStartPos = wsString.find(wsFrom, nStartPos)) != std::wstring::npos) - { - wsString.replace(nStartPos, wsFrom.length(), wsTo); - nStartPos += wsTo.length(); - } - } - - - //------------------------------------------------------------------------ - // Array accessors. - //------------------------------------------------------------------------ - int Object::ArrayGetLength() - { - return m_uArray->GetCount(); - } - - void Object::ArrayAdd(Object *pItem) - { - m_uArray->Add(pItem); - } - - Object *Object::ArrayGet(int nIndex, Object *pObject) - { - return m_uArray->Get(nIndex, pObject); - } - - Object *Object::ArrayGetCopy(int nIndex, Object *pObject) - { - return m_uArray->GetCopy(nIndex, pObject); - } - - //------------------------------------------------------------------------ - // Dict accessors. - //------------------------------------------------------------------------ - int Object::DictGetLength() - { - return m_uDict->GetEntryCount(); - } - - void Object::DictAdd(char *sKey, Object *pItem) - { - m_uDict->AddItem(sKey, pItem); - } - - bool Object::DictCheckType(char *sDictType) - { - return m_uDict->CheckType(sDictType); - } - - bool Object::IsDict(char *sDictType) - { - return (m_eType == objDict && DictCheckType(sDictType)); - } - - Object *Object::DictLookup(char *sKey, Object *pObject) - { - return m_uDict->Search(sKey, pObject); - } - - Object *Object::DictLookupAndCopy(char *sKey, Object *pObject) - { - return m_uDict->SearchAndCopy(sKey, pObject); - } - - char *Object::DictGetKey(int nIndex) - { - return m_uDict->GetKey(nIndex); - } - - Object *Object::DictGetValue(int nIndex, Object *pObject) - { - return m_uDict->GetValue(nIndex, pObject); - } - - Object *Object::DictGetValueCopy(int nIndex, Object *pObject) - { - return m_uDict->GetValueCopy(nIndex, pObject); - } - - //------------------------------------------------------------------------ - // Stream accessors. - //------------------------------------------------------------------------ - - bool Object::StreamCheckType(char *sDictType) - { - return m_uStream->GetDict()->CheckType(sDictType); - } - - bool Object::IsStream(char *sDictType) - { - return (m_eType == objStream && StreamCheckType(sDictType)); - } - - void Object::StreamReset() - { - m_uStream->Reset(); - } - - void Object::StreamClose() - { - m_uStream->Close(); - } - - int Object::StreamGetChar() - { - return m_uStream->GetChar(); - } - - int Object::StreamLookChar() - { - return m_uStream->LookChar(); - } - - char *Object::StreamGetLine(char *sBuffer, int nSize) - { - return m_uStream->GetLine(sBuffer, nSize); - } - - unsigned int Object::StreamGetPos() - { - return m_uStream->GetPos(); - } - - void Object::StreamSetPos(unsigned int unPos, int nDirection) - { - m_uStream->SetPos(unPos, nDirection); - } - - Dict *Object::StreamGetDict() - { - return m_uStream->GetDict(); - } -} diff --git a/PdfReader/old/Object.h b/PdfReader/old/Object.h deleted file mode 100644 index 7ede7327ed..0000000000 --- a/PdfReader/old/Object.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_OBJECT_H -#define _PDF_READER_OBJECT_H - -#include -#include -#include "MemoryUtils.h" -#include "StringExt.h" -#include "Array.h" - -#ifdef GetObject -#undef GetObject -#endif - -namespace PdfReader -{ - class XRef; - class Array; - class Dict; - class Stream; - - //------------------------------------------------------------------------ - // Ref - //------------------------------------------------------------------------ - - struct Ref - { - int nNum; // Номер объекта - int nGen; // Номер версии объекта(generation number) - - public: - - bool operator ==(const Ref& oRight)const - { - if (nNum == oRight.nNum && nGen == oRight.nGen) - return true; - - return false; - } - bool operator <(const Ref& oRight)const - { - if (nNum < oRight.nNum) - return true; - else if (nNum == oRight.nNum) - return nGen < oRight.nGen; - else - return false; - } - bool operator >(const Ref& oRight)const - { - if (nNum > oRight.nNum) - return true; - else if (nNum == oRight.nNum) - return nGen > oRight.nGen; - else - return false; - } - bool operator <=(const Ref& oRight)const - { - if (*this == oRight) - return true; - - return (*this < oRight); - } - bool operator >=(const Ref& oRight)const - { - if (*this == oRight) - return true; - - return (*this > oRight); - } - }; - - //------------------------------------------------------------------------ - // Типы объектов - //------------------------------------------------------------------------ - - enum ObjType - { - // Простые объекты - objBool, // boolean - objInt, // integer - objReal, // real - objString, // string - objName, // name - objNull, // null - - // составные объекты - objArray, // array - objDict, // dictionary - objStream, // stream - objRef, // indirect reference - - // специальные объекты - objCommand, // command name - objError, // error return from Lexer - objEOF, // end of file return from Lexer - objNone // uninitialized object - }; - -#define NumObjTypes 14 - - //------------------------------------------------------------------------ - // Object - //------------------------------------------------------------------------ - - class Object - { - public: - - Object() : - m_eType(objNone) - { - } - - - Object *InitBool(bool bBool) - { - m_eType = objBool; - m_uBool = bBool; - return this; - } - Object *InitInt(int nInt) - { - m_eType = objInt; - m_uInt = nInt; - return this; - } - Object *InitReal(double dReal) - { - m_eType = objReal; - m_uReal = dReal; - return this; - } - Object *InitString(StringExt *seString) - { - m_eType = objString; - m_uStringExt = seString; - return this; - } - Object *InitName(char *sName) - { - m_eType = objName; - m_uName = CopyString(sName); - return this; - } - Object *InitNull() - { - m_eType = objNull; - return this; - } - Object *InitArray(XRef *pXref); - Object *InitDict(XRef *pXref); - Object *InitDict(Dict *pDict); - Object *InitStream(Stream *pStream); - Object *InitRef(int nNum, int nGen) - { - m_eType = objRef; - m_uRef.nNum = nNum; - m_uRef.nGen = nGen; - return this; - } - Object *InitCommand(char *sCommand) - { - m_eType = objCommand; - m_uCommand = CopyString(sCommand); - return this; - } - Object *InitError() - { - m_eType = objError; - return this; - } - Object *InitEOF() - { - m_eType = objEOF; - return this; - } - - - // Копируем объект. - Object *Copy(Object *pObject); - - // Если объект - ссылка, тогда получаем объект по ссылке, в противном случае копируем данный объект - Object *Fetch(XRef *pXref, Object *pObject); - - // - void Free(); - - // Проверка тип объекта. - ObjType GetType() - { - return m_eType; - } - bool IsBool() - { - return (m_eType == objBool); - } - bool IsInt() - { - return (m_eType == objInt); - } - bool IsReal() - { - return (m_eType == objReal); - } - bool IsNum() - { - return (m_eType == objInt || m_eType == objReal); - } - bool IsString() - { - return (m_eType == objString); - } - bool IsName() - { - return (m_eType == objName); - } - bool IsNull() - { - return (m_eType == objNull); - } - bool IsArray() - { - return (m_eType == objArray); - } - bool IsDict() - { - return (m_eType == objDict); - } - bool IsStream() - { - return (m_eType == objStream); - } - bool IsRef() - { - return (m_eType == objRef); - } - bool IsCommand() - { - return (m_eType == objCommand); - } - bool IsError() - { - return (m_eType == objError); - } - bool IsEOF() - { - return (m_eType == objEOF); - } - bool IsNone() - { - return (m_eType == objNone); - } - - // Сепциальные проверки. - bool IsName(char *sName) - { - return (m_eType == objName && !strcmp(m_uName, sName)); - } - bool IsDict(char *sDictType); - bool IsStream(char *sDictType); - bool IsCommand(char *sCommand) - { - return (m_eType == objCommand && !strcmp(m_uCommand, sCommand)); - } - // В следующих функциях предполагается, что тип объекта корректный. - // Т.е. соответствует типу запрашиваемого значения. - bool GetBool() - { - return m_uBool; - } - int GetInt() - { - return m_uInt; - } - double GetReal() - { - return m_uReal; - } - double GetNum() - { - return (m_eType == objInt) ? (double)m_uInt : m_uReal; - } - StringExt *GetString() - { - return m_uStringExt; - } - char *GetName() - { - return m_uName; - } - Array *GetArray() - { - return m_uArray; - } - Dict *GetDict() - { - return m_uDict; - } - Stream *GetStream() - { - return m_uStream; - } - Ref GetRef() - { - return m_uRef; - } - int GetRefNum() - { - return m_uRef.nNum; - } - int GetRefGen() - { - return m_uRef.nGen; - } - char *GetCommand() - { - return m_uCommand; - } - - - // Array - int ArrayGetLength(); - void ArrayAdd(Object *pItem); - Object *ArrayGet(int nIndex, Object *pObject); - Object *ArrayGetCopy(int nIndex, Object *pObject); - - // Dict - int DictGetLength(); - void DictAdd(char *sKey, Object *pItem); - bool DictCheckType(char *sDictType); - Object *DictLookup(char *sKey, Object *pObject); - Object *DictLookupAndCopy(char *sKey, Object *pObject); - char *DictGetKey(int nIndex); - Object *DictGetValue(int nIndex, Object *pObject); - Object *DictGetValueCopy(int nIndex, Object *pObject); - - // Stream - bool StreamCheckType(char *sDictType); - void StreamReset(); - void StreamClose(); - int StreamGetChar(); - int StreamLookChar(); - char *StreamGetLine(char *sBuffer, int nSize); - unsigned int StreamGetPos(); - void StreamSetPos(unsigned int unPos, int nDirection = 0); - Dict *StreamGetDict(); - - // Для записи - char *GetTypeName(); - void Print(FILE *pFile = stdout); - void ToXml(std::wstring& wsXml); - static void AppendStringToXml(std::wstring& wsXml, const std::string& sString); - static void ReplaceAll(std::wstring& wsString, const std::wstring& wsFrom, const std::wstring& wsTo); - - private: - - ObjType m_eType; // тип объекта - union - { - bool m_uBool; // boolean - int m_uInt; // integer - double m_uReal; // real - StringExt *m_uStringExt; // StringExt - char *m_uName; // имя - Array *m_uArray; // массив - Dict *m_uDict; // словарь - Stream *m_uStream; // поток - Ref m_uRef; // ссылка - char *m_uCommand; // команда - }; - }; -} -#endif // _PDF_READER_OBJECT_H diff --git a/PdfReader/old/Outline.cpp b/PdfReader/old/Outline.cpp deleted file mode 100644 index 0d4f941eb1..0000000000 --- a/PdfReader/old/Outline.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "MemoryUtils.h" -#include "StringExt.h" -#include "List.h" -#include "Link.h" -#include "PDFDocEncoding.h" -#include "Outline.h" -#include "Dict.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // Outline - //------------------------------------------------------------------------------------------------------------------------------- - - Outline::Outline(Object *pOutlineObject, XRef *pXref) - { - m_pItems = NULL; - - if (!pOutlineObject->IsDict()) - { - return; - } - - Object oFirst, oLast; - m_pItems = OutlineItem::ReadItemList(pOutlineObject->DictLookupAndCopy("First", &oFirst), pOutlineObject->DictLookupAndCopy("Last", &oLast), pXref); - oFirst.Free(); - oLast.Free(); - } - - Outline::~Outline() - { - if (m_pItems) - { - DeleteCList(m_pItems, OutlineItem); - } - } - - //------------------------------------------------------------------------------------------------------------------------------- - // OutlineItem - //------------------------------------------------------------------------------------------------------------------------------- - - OutlineItem::OutlineItem(Dict *pDict, XRef *pXref) - { - m_pXref = pXref; - m_pTitle = NULL; - m_pAction = NULL; - m_pKids = NULL; - - Object oDictItem; - if (pDict->Search("Title", &oDictItem)->IsString()) - { - StringExt *seTitle = oDictItem.GetString(); - if ((seTitle->GetAt(0) & 0xff) == 0xfe && (seTitle->GetAt(1) & 0xff) == 0xff) - { - m_nTitleLen = (seTitle->GetLength() - 2) / 2; - m_pTitle = (Unicode *)MemUtilsMallocArray(m_nTitleLen, sizeof(Unicode)); - for (int nIndex = 0; nIndex < m_nTitleLen; ++nIndex) - { - m_pTitle[nIndex] = ((seTitle->GetAt(2 + 2 * nIndex) & 0xff) << 8) | (seTitle->GetAt(3 + 2 * nIndex) & 0xff); - } - } - else - { - m_nTitleLen = seTitle->GetLength(); - m_pTitle = (Unicode *)MemUtilsMallocArray(m_nTitleLen, sizeof(Unicode)); - - for (int nIndex = 0; nIndex < m_nTitleLen; ++nIndex) - { - m_pTitle[nIndex] = c_arrPDFDocEncoding[seTitle->GetAt(nIndex) & 0xff]; - } - } - } - else - { - m_nTitleLen = 0; - } - oDictItem.Free(); - - if (!pDict->Search("Dest", &oDictItem)->IsNull()) - { - m_pAction = LinkAction::ParseDestination(&oDictItem); - } - else - { - oDictItem.Free(); - if (!pDict->Search("A", &oDictItem)->IsNull()) - { - m_pAction = LinkAction::ParseAction(&oDictItem); - } - } - oDictItem.Free(); - - pDict->SearchAndCopy("First", &m_oFirstRef); - pDict->SearchAndCopy("Last", &m_oLastRef); - pDict->SearchAndCopy("Next", &m_oNextRef); - - m_bOpen = false; - if (pDict->Search("Count", &oDictItem)->IsInt()) - { - if (oDictItem.GetInt() > 0) - { - m_bOpen = true; - } - } - oDictItem.Free(); - } - - OutlineItem::~OutlineItem() - { - Close(); - - if (m_pTitle) - { - MemUtilsFree(m_pTitle); - } - if (m_pAction) - { - delete m_pAction; - } - m_oFirstRef.Free(); - m_oLastRef.Free(); - m_oNextRef.Free(); - } - - CList *OutlineItem::ReadItemList(Object *pFirstItemRef, Object *pLastItemRef, XRef *pXref) - { - CList *pItems = new CList(); - Object *pCurItem = pFirstItemRef; - - while (pCurItem->IsRef()) - { - Object oTemp; - if (!pCurItem->Fetch(pXref, &oTemp)->IsDict()) - { - oTemp.Free(); - break; - } - OutlineItem *pItem = new OutlineItem(oTemp.GetDict(), pXref); - oTemp.Free(); - - pItems->Append(pItem); - if (pCurItem->GetRef().nNum == pLastItemRef->GetRef().nNum && pCurItem->GetRef().nGen == pLastItemRef->GetRef().nGen) - { - break; - } - pCurItem = &pItem->m_oNextRef; - } - return pItems; - } - - void OutlineItem::Open() - { - if (!m_pKids) - { - m_pKids = ReadItemList(&m_oFirstRef, &m_oLastRef, m_pXref); - } - } - - void OutlineItem::Close() - { - if (m_pKids) - { - DeleteCList(m_pKids, OutlineItem); - m_pKids = NULL; - } - } -} \ No newline at end of file diff --git a/PdfReader/old/Outline.h b/PdfReader/old/Outline.h deleted file mode 100644 index fadbb5c5f1..0000000000 --- a/PdfReader/old/Outline.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_OUTLINE_H -#define _PDF_READER_OUTLINE_H - -#include "Object.h" -#include "CharTypes.h" - -namespace PdfReader -{ - class StringExt; - class GList; - class XRef; - class LinkAction; - - //------------------------------------------------------------------------------------------------------------------------------- - // Outline - //------------------------------------------------------------------------------------------------------------------------------- - - class Outline - { - public: - - Outline(Object *pOutlineObject, XRef *pXref); - ~Outline(); - - CList *GetItems() - { - return m_pItems; - } - - private: - - CList *m_pItems; // NULL, если у документа нет Outline - // [OutlineItem] - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // OutlineItem - //------------------------------------------------------------------------------------------------------------------------------- - - class OutlineItem - { - public: - - OutlineItem(Dict *pDict, XRef *pXref); - ~OutlineItem(); - - static CList *ReadItemList(Object *pFirstItemRef, Object *pLastItemRef, XRef *pXref); - - void Open(); - void Close(); - - Unicode *GetTitle() - { - return m_pTitle; - } - int GetTitleLength() - { - return m_nTitleLen; - } - LinkAction *GetAction() - { - return m_pAction; - } - bool IsOpen() - { - return m_bOpen; - } - bool HasKids() - { - return m_oFirstRef.IsRef(); - } - CList *GetKids() - { - return m_pKids; - } - - private: - - XRef *m_pXref; // Таблица Xref данного PDF-документа - Unicode *m_pTitle; // Название данной закладки - int m_nTitleLen; // Длина названия - LinkAction *m_pAction; // LinkAction - - Object m_oFirstRef; // Ссылка(Ref) на First - Object m_oLastRef; // Ссылка(Ref) на Last - Object m_oNextRef; // Ссылка(Ref) на Next - - bool m_bOpen; // Будет ли вкладка открытой при открытии документа - CList *m_pKids; // NULL, если данный пункт не открыт [OutlineItem] - }; -} - -#endif // _PDF_READER_OUTLINE_H diff --git a/PdfReader/old/OutputDevice.cpp b/PdfReader/old/OutputDevice.cpp deleted file mode 100644 index c30a4a1151..0000000000 --- a/PdfReader/old/OutputDevice.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "Object.h" -#include "Stream.h" -#include "GState.h" -#include "OutputDevice.h" -#include "Graphics.h" -#include "../PdfReader.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // OutputDev - //------------------------------------------------------------------------------------------------------------------------------- - - void OutputDev::SetDefaultCTM(double *pCTM) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - m_arrDefaultCTM[nIndex] = pCTM[nIndex]; - } - - double dDet = 1 / (m_arrDefaultCTM[0] * m_arrDefaultCTM[3] - m_arrDefaultCTM[1] * m_arrDefaultCTM[2]); - - m_arrDefaultInvCTM[0] = m_arrDefaultCTM[3] * dDet; - m_arrDefaultInvCTM[1] = -m_arrDefaultCTM[1] * dDet; - m_arrDefaultInvCTM[2] = -m_arrDefaultCTM[2] * dDet; - m_arrDefaultInvCTM[3] = m_arrDefaultCTM[0] * dDet; - m_arrDefaultInvCTM[4] = (m_arrDefaultCTM[2] * m_arrDefaultCTM[5] - m_arrDefaultCTM[3] * m_arrDefaultCTM[4]) * dDet; - m_arrDefaultInvCTM[5] = (m_arrDefaultCTM[1] * m_arrDefaultCTM[4] - m_arrDefaultCTM[0] * m_arrDefaultCTM[5]) * dDet; - } - - void OutputDev::ConvertDeviceToUser(double dDevX, double dDevY, double *pdUserX, double *pdUserY) - { - *pdUserX = m_arrDefaultInvCTM[0] * dDevX + m_arrDefaultInvCTM[2] * dDevY + m_arrDefaultInvCTM[4]; - *pdUserY = m_arrDefaultInvCTM[1] * dDevX + m_arrDefaultInvCTM[3] * dDevY + m_arrDefaultInvCTM[5]; - } - - void OutputDev::ConvertUserToDevice(double dUserX, double dUserY, int *pnDevX, int *pnDevY) - { - *pnDevX = (int)(m_arrDefaultCTM[0] * dUserX + m_arrDefaultCTM[2] * dUserY + m_arrDefaultCTM[4] + 0.5); - *pnDevY = (int)(m_arrDefaultCTM[1] * dUserX + m_arrDefaultCTM[3] * dUserY + m_arrDefaultCTM[5] + 0.5); - } - - void OutputDev::UpdateAll(GrState *pGState) - { - UpdateLineDash(pGState); - UpdateFlatness(pGState); - UpdateLineJoin(pGState); - UpdateLineCap(pGState); - UpdateMiterLimit(pGState); - UpdateLineWidth(pGState); - UpdateStrokeAdjust(pGState); - UpdateFillColorSpace(pGState); - UpdateFillColor(pGState); - UpdateStrokeColorSpace(pGState); - UpdateStrokeColor(pGState); - UpdateBlendMode(pGState); - UpdateFillOpacity(pGState); - UpdateStrokeOpacity(pGState); - UpdateFillOverprint(pGState); - UpdateStrokeOverprint(pGState); - UpdateTransfer(pGState); - UpdateFont(pGState); - } - - bool OutputDev::BeginType3Char(GrState *pGState, double dX, double dY, double dDx, double dDy, CharCode nCode, Unicode *pnUnicode, int nUnLen) - { - return false; - } - - void OutputDev::DrawImageMask(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, bool bInvert, bool bInlineImage) - { - if (bInlineImage) - { - pStream->Reset(); - int nSize = nHeight * ((nWidth + 7) / 8); - for (int nIndex = 0; nIndex < nSize; ++nIndex) - pStream->GetChar(); - pStream->Close(); - } - } - - void OutputDev::DrawImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, int *pnMaskColors, bool bInlineImage) - { - if (bInlineImage) - { - pStream->Reset(); - int nSize = nHeight * ((nWidth * pColorMap->GetComponentsCount() * pColorMap->GetBitsPerComponent() + 7) / 8); - for (int nIndex = 0; nIndex < nSize; ++nIndex) - pStream->GetChar(); - pStream->Close(); - } - } - - void OutputDev::DrawMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, bool bMaskInvert) - { - DrawImage(pGState, pRef, pStream, nWidth, nHeight, pColorMap, NULL, false); - } - - void OutputDev::DrawSoftMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GrImageColorMap *pMaskColorMap, unsigned char *pMatte) - { - DrawImage(pGState, pRef, pStream, nWidth, nHeight, pColorMap, NULL, false); - } - -#if OPI_SUPPORT - void OutputDev::OpiBegin(GrState *pGState, Dict *pOpiDict) - { - } - void OutputDev::OpiEnd (GrState *pGState, Dict *pOpiDict) - { - } -#endif -} diff --git a/PdfReader/old/OutputDevice.h b/PdfReader/old/OutputDevice.h deleted file mode 100644 index 6861e8d96c..0000000000 --- a/PdfReader/old/OutputDevice.h +++ /dev/null @@ -1,340 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_OUTPUT_DEVICE_H -#define _PDF_READER_OUTPUT_DEVICE_H - -#include "CharTypes.h" -#include "GlobalParams.h" -#include "Graphics.h" -#include "../PdfReader.h" -#include "../../DesktopEditor/graphics/structures.h" -namespace PdfReader -{ - class StringExt; - class GrState; - class GrPath; - struct GrColor; - class GrColorSpace; - class GrImageColorMap; - class GrFunctionShading; - class GrAxialShading; - class GrRadialShading; - class Stream; - class Links; - class Link; - class Catalog; - class Page; - class Function; - - //------------------------------------------------------------------------------------------------------------------------------- - // OutputDev - //------------------------------------------------------------------------------------------------------------------------------- - - class OutputDev - { - public: - - OutputDev() {} - - virtual ~OutputDev() {} - - //------ Информация о выходном устройстве - - // True, если точка с координатой (0,0) находится в левом верхнем углу. - virtual bool UpSideDown() = 0; - - // Вывод текста с помощью функции DrawChar() или DrawString()? - virtual bool UseDrawChar() = 0; - - // Поддерживает ли данное устройство TilingPatternFill? Если нет, тогда - // TilingPatternFill будет рисоваться с помощью комбинации более простых - // графических примитивов. - virtual bool UseTilingPatternFill() - { - return false; - } - - // Поддерживает ли данное устройство SimpleTilingPatternFill? Если нет, тогда - // TilingPatternFill будет рисоваться с помощью комбинации более простых - // графических примитивов. - virtual bool UseSimpleTilingPatternFill() - { - return false; - } - - // Поддерживает ли данное устройство FunctionShadedFill? Если нет, тогда данные - // Shaded fills будут заменены комбинацией более простых графических примитивов. - virtual bool UseFunctionalShadedFills() - { - return false; - } - // Поддерживает ли данное устройство AxialShadedFill? Если нет, тогда данные - // Shaded fills будут заменены комбинацией более простых графических примитивов. - virtual bool UseAxialShadedFills() - { - return false; - } - // Поддерживает ли данное устройство RadialShadedFill? Если нет, тогда данные - // Shaded fills будут заменены комбинацией более простых графических примитивов. - virtual bool UseRadialShadedFills() - { - return false; - } - virtual bool UseGouraundTriangleFills() - { - return false; - } - virtual bool UsePatchMeshFills() - { - return false; - } - - // Поддерживается ли DrawForm()? - virtual bool UseDrawForm() - { - return false; - } - - // Используем команду ClipToPath для клипа или команды Clip, EoClip, ClipToPathStroke - virtual bool UseClipTo() - { - return false; - } - - - // Использует ли данное устройство методы BeginType3Char/EndType3Char? - // В противном случае тект в шрифте Type3 будет выводится с помощью - // функций DrawChar/DrawString. - virtual bool InterpretType3Chars() = 0; - - // Поддерживается ли данным устройством что-нибудь кроме текста? - virtual bool NeedNonText() - { - return true; - } - - // Поддерживается ли данным устройствой одновременные обводка и заливка Path - virtual bool UseFillAndStroke() - { - return false; - } - - // В каком виде мы используем группу прозрачных объектов - virtual bool UseSimpleTransparentGroup() - { - return false; - } - - //------ Информация о выходном устройстве - - // Устанавливаем стандартную матрицу преобразований. - virtual void SetDefaultCTM(double *pCTM); - - // Проверяем, должна ли мы показывать данную часть страницы. Если возращаемое - // значение False, показ страницы прерывается. Как правило, OutputDev будет - // использовать дополнительные средства, чтобы показать страницу, прежде чем - // вернет значение False. - virtual bool CheckPageSlice(Page *pPage, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, int nSliceX, int nSliceY, int nSliceW, int nSliceH, bool bPrinting, Catalog *pCatalog, bool(*pAbortCheckCallBack)(void *pData) = NULL, void *pAbortCheckData = NULL) - { - return true; - } - - // Новая страница. - virtual void StartPage(int nPageNum, GrState *pGState) {} - // Конец страницы. - virtual void EndPage() {} - - // Вывод содержимого страницы. - virtual void Dump() {} - - // Остановка вывода - virtual bool IsStopped() { return false; } - - //----- Системы координат (пользовательские и устройства) - - // Конвертации - virtual void ConvertDeviceToUser(double dDevX, double dDevY, double *pdUserX, double *pdUserY); - virtual void ConvertUserToDevice(double dUserX, double dUserY, int *pnDevX, int *pnDevY); - - double *GetDefaultCTM() - { - return m_arrDefaultCTM; - } - double *GetDefaultInvCTM() - { - return m_arrDefaultInvCTM; - } - - //----- Save/Restore GState - virtual void SaveGState(GrState *pGState) {} - virtual void RestoreGState(GrState *pGState) {} - - //----- Изменение параметров в GState - virtual void UpdateAll(GrState *pGState); - virtual void UpdateCTM(GrState *pGState, double dM11, double dM12, double dM21, double dM22, double dM31, double dM32) {} - virtual void UpdateLineDash(GrState *pGState) {} - virtual void UpdateFlatness(GrState *pGState) {} - virtual void UpdateLineJoin(GrState *pGState) {} - virtual void UpdateLineCap(GrState *pGtate) {} - virtual void UpdateMiterLimit(GrState *pGState) {} - virtual void UpdateLineWidth(GrState *pGState) {} - virtual void UpdateStrokeAdjust(GrState *pGState) {} - virtual void UpdateFillColorSpace(GrState *pGState) {} - virtual void UpdateStrokeColorSpace(GrState *pGState) {} - virtual void UpdateFillColor(GrState *pGState) {} - virtual void UpdateStrokeColor(GrState *pGState) {} - virtual void UpdateBlendMode(GrState *pGState) {} - virtual void UpdateFillOpacity(GrState *pGState) {} - virtual void UpdateStrokeOpacity(GrState *pGState) {} - virtual void UpdateFillOverprint(GrState *pGState) {} - virtual void UpdateStrokeOverprint(GrState *pGState) {} - virtual void UpdateTransfer(GrState *pGState) {} - - //----- Изменение текстовых параметров - virtual void UpdateFont(GrState *pGState) {} - virtual void UpdateTextMatrix(GrState *pGState) {} - virtual void UpdateCharSpace(GrState *pGState) {} - virtual void UpdateRender(GrState *pGState) {} - virtual void UpdateRise(GrState *pGState) {} - virtual void UpdateWordSpace(GrState *pGState) {} - virtual void UpdateHorizScaling(GrState *pGState) {} - virtual void UpdateTextPos(GrState *pGState) {} - virtual void UpdateTextShift(GrState *pGState, double dShift) {} - - //----- Рисование Path - virtual void Stroke(GrState *pGState) {} - virtual void Fill(GrState *pGState) {} - virtual void EoFill(GrState *pGState) {} - virtual void FillStroke(GrState *pGState) {} - virtual void EoFillStroke(GrState *pGState) {} - virtual void TilingPatternFill(GrState *pGState, Object *pStream, int nPaintType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep) {} - virtual void StartTilingFill(GrState *pGState) {} - virtual void EndTilingFill() {} - virtual bool FunctionShadedFill(GrState *pGState, GrFunctionShading *pShading) - { - return false; - } - virtual bool AxialShadedFill(GrState *pGState, GrAxialShading *pShading) - { - return false; - } - virtual bool RadialShadedFill(GrState *pGState, GrRadialShading *pShading) - { - return false; - } - virtual bool GouraundTriangleFill(GrState *pGState, const std::vector &colors, const std::vector &points) - { - return false; - } - virtual bool PatchMeshFill(GrState *pGState, GrPatch *patch) - { - return false; - } - - - virtual void StartTilingFillIteration() {} - virtual void EndTilingFillIteration() {} - virtual void StartSimpleTilingFill(GrState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix) {} - virtual void EndSimpleTilingFill() {} - - virtual void StartShadedFill(GrState *pGState) {} - virtual void EndShadedFill() {} - - //----- Path clipping - virtual void Clip(GrState *pGState) {} - virtual void ClipAttack(GrState *pGState) {} - virtual void EoClip(GrState *pGState) {} - virtual void ClipToStrokePath(GrState *pGState) {} - virtual void ClipToPath(GrState *pGState, GrPath *pPath, double *pMatrix, bool bEO) {} - - //----- Вывод текста - virtual void BeginStringOperator(GrState *pGState) {} - virtual void EndStringOperator(GrState *pGState) {} - virtual void BeginString(GrState *pGState, StringExt *seString) {} - virtual void EndString(GrState *pGState) {} - virtual void DrawChar(GrState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pnUnicode, int nUnLen) {} - virtual void DrawString(GrState *pGState, StringExt *seString) {} - virtual bool BeginType3Char(GrState *pGState, double dX, double dY, double dDx, double dDy, CharCode nCode, Unicode *pnUnicode, int nUnLen); - virtual void EndType3Char(GrState *pGState) {} - virtual void BegintTextObject(GrState *pGState){} - virtual void EndTextObject(GrState *pGState) {} - - //----- Вывод картинок - virtual void DrawImageMask(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, bool bInvert, bool bInlineImage); - virtual void DrawImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, int *pnMaskColors, bool bInlineImage); - virtual void DrawMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, bool bMaskInvert); - virtual void DrawSoftMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GrImageColorMap *pMaskColorMap, unsigned char *pMatte); - -#if OPI_SUPPORT - //----- OPI - virtual void OpiBegin(GrState *pGState, Dict *pOpiDict); - virtual void OpiEnd (GrState *pGState, Dict *pOpiDict); -#endif - - //----- Операторы Type 3 - шрифтов - virtual void Type3D0(GrState *pGState, double dWx, double dWy) {} - virtual void Type3D1(GrState *pGState, double dWx, double dWy, double dLLx, double dLLy, double dURx, double dURy) {} - - //----- Form XObjects - virtual void DrawForm(Ref oID) {} - - //----- PostScript XObjects - virtual void PSXObject(Stream *pPSStream, Stream *pLevel1Stream) {} - - //----- Transparency groups и SMasks - virtual void BeginTransparencyGroup(GrState *pGState, double *pBBox, GrColorSpace *pBlendingColorSpace, bool bIsolated, bool bKnockout, bool bForSoftMask) {} - virtual void EndTransparencyGroup(GrState *pGState) {} - virtual void PaintTransparencyGroup(GrState *pGState, double *pBBox) {} - virtual void SetSoftMask(GrState *pGState, double *pBBox, bool bAlpha, Function *pTransferFunction, GrColor *pBackdropColor) {} - virtual void ClearSoftMask(GrState *pGState) {} - - //----- Links - virtual void ProcessLink(Link *pLink, Catalog *pCatalog) {} - - virtual bool GetVectorAntialias() - { - return false; - } - virtual void SetVectorAntialias(bool bVectorAntiAlias) {} - - private: - - double m_arrDefaultCTM[6]; // Матрица преобразования по умолчанию - double m_arrDefaultInvCTM[6]; // Обратная матрица - - protected: - - GlobalParams *m_pGlobalParams; - }; -} - -#endif // _PDF_READER_OUTPUT_DEVICE_H diff --git a/PdfReader/old/PDFDoc.cpp b/PdfReader/old/PDFDoc.cpp deleted file mode 100644 index d8bf9e4c3f..0000000000 --- a/PdfReader/old/PDFDoc.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "../../DesktopEditor/common/File.h" - -#include -#include -#include -#include - -#include "StringExt.h" -#include "Constants.h" -#include "GlobalParams.h" -#include "Page.h" -#include "Catalog.h" -#include "Stream.h" -#include "XRef.h" -#include "Link.h" -#include "OutputDevice.h" -#include "ErrorConstants.h" -#include "Lexer.h" -#include "Parser.h" -#include "SecurityHandler.h" -#include "Outline.h" -#include "PageLabels.h" -#include "PDFDoc.h" - -#define HeaderSearchSize 1024 // Максимальное количество байт для считывания с начала файла, в которых мы ищем запись '%PDF' - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // PDFDoc - //------------------------------------------------------------------------------------------------------------------------------- - PDFDoc::PDFDoc(GlobalParams *pGlobalParams, const std::wstring &wsFileName, const std::wstring &ownerPassword, const std::wstring &userPassword) - { - m_pGlobalParams = pGlobalParams; - - m_bValid = false; - m_eErrorCode = errorNone; - - m_pFile = NULL; - m_pFileBuffer = NULL; - - m_pStream = NULL; - m_pXref = NULL; - m_pCatalog = NULL; - m_pOutline = NULL; - m_pPageLabels = NULL; - - m_wsFileName = wsFileName; - - NSFile::CFileBinary oFile; - oFile.OpenFile(wsFileName); - long lFileSize = oFile.GetFileSize(); - - m_pFileBuffer = new unsigned char[lFileSize]; - - if (!m_pFileBuffer) - { - oFile.CloseFile(); - // Не смогли выделить память под весь файл, тогда работаем непосредственно с самим файлом - m_pFileBuffer = NULL; - m_pFile = NSFile::CFileBinary::OpenFileNative(wsFileName, L"rb"); - - // Создаем поток - Object oTemp; - oTemp.InitNull(); - m_pStream = new FileStream(m_pFile, 0, false, 0, &oTemp); - } - else - { - DWORD lReadedSize; - DWORD lTotallReadedSize = 0; - DWORD lCounter = 0; - while (lTotallReadedSize != lFileSize) - { - oFile.ReadFile(m_pFileBuffer + lTotallReadedSize, lFileSize - lTotallReadedSize, lReadedSize); - lTotallReadedSize += lReadedSize; - lCounter++; - - if (lCounter > 0x0FFFFFFF) - { - lTotallReadedSize = 0; - break; - } - } - oFile.CloseFile(); - - if (lTotallReadedSize != lFileSize) - { - m_pFileBuffer = NULL; - m_bValid = false; - return; - } - - // Создаем поток - Object oTemp; - oTemp.InitNull(); - m_pStream = new MemoryStream((char*)m_pFileBuffer, 0, lFileSize, &oTemp); - } - - if (!m_pStream) - m_bValid = false; - - m_bValid = Setup(ownerPassword, userPassword); - } - bool PDFDoc::Setup(const std::wstring &ownerPassword, const std::wstring &userPassword) - { - m_pStream->Reset(); - - // Проверяем заголовок PDF файла - CheckHeader(); - - // Считываем таблицу Xref - m_pXref = new XRef(m_pStream); - if (!m_pXref->CheckValidate()) - { - // TO DO: Error "Couldn't read xref table" - m_eErrorCode = (EError)m_pXref->GetErrorCode(); - return false; - } - - // Проверяем зашифрован ли документ - if (!CheckEncryption(ownerPassword, userPassword)) - { - m_eErrorCode = errorEncrypted; - return false; - } - - // Считываем объект Catalog - m_pCatalog = new Catalog(m_pGlobalParams, m_pXref); - if (!m_pCatalog->CheckValidation()) - { - // TO DO: Error "Couldn't read page catalog" - m_eErrorCode = errorBadCatalog; - return false; - } - - // Считываем объект Outline - m_pOutline = new Outline(m_pCatalog->GetOutline(), m_pXref); - - m_pPageLabels = new PageLabels(m_pCatalog->GetPageLabels(), m_pXref); - - return true; - } - PDFDoc::~PDFDoc() - { - if (m_pOutline) - { - delete m_pOutline; - } - - if (m_pPageLabels) - { - delete m_pPageLabels; - } - - if (m_pCatalog) - { - delete m_pCatalog; - } - if (m_pXref) - { - delete m_pXref; - } - if (m_pStream) - { - delete m_pStream; - } - - if (m_pFileBuffer) - { - delete[] m_pFileBuffer; - } - - if (m_pFile) - { - fclose(m_pFile); - } - } - void PDFDoc::CheckHeader() - { - char hdrBuf[HeaderSearchSize + 1]; - char *p; - int nIndex = 0; - - m_dPDFVersion = 0; - - for (nIndex = 0; nIndex < HeaderSearchSize; ++nIndex) - { - hdrBuf[nIndex] = m_pStream->GetChar(); - } - hdrBuf[HeaderSearchSize] = '\0'; - - for (nIndex = 0; nIndex < HeaderSearchSize - 5; ++nIndex) - { - if (!strncmp(&hdrBuf[nIndex], "%PDF-", 5)) - { - break; - } - } - if (nIndex >= HeaderSearchSize - 5) - { - // TO DO: Error "May not be a PDF file" - return; - } - - m_pStream->SetStartPos(nIndex); - - if (!(p = strtok(&hdrBuf[nIndex + 5], " \t\n\r"))) - { - // TO DO: Error "May not be a PDF file" - return; - } - m_dPDFVersion = atof(p); - - if (!(hdrBuf[nIndex + 5] >= '0' && hdrBuf[nIndex + 5] <= '9') || m_dPDFVersion > SupportedPDFVersionNum + 0.0001) - { - // TO DO: Error "Unsupported PDF version" - } - } - bool PDFDoc::CheckEncryption(const std::wstring &ownerPassword, const std::wstring &userPassword) - { - bool bEncrypted = false; - bool bResult = true; - - Object oEncypt; - m_pXref->GetTrailerDict()->DictLookup("Encrypt", &oEncypt); - - if ((bEncrypted = oEncypt.IsDict())) - { - SecurityHandler *pSecurityHandler = NULL; - if ((pSecurityHandler = SecurityHandler::Make(this, &oEncypt))) - { - if (pSecurityHandler->CheckEncryption(ownerPassword, userPassword)) - { - // Авторизация пройдена - m_pXref->SetEncryption(pSecurityHandler->GetPermissionFlags(), pSecurityHandler->GetOwnerPasswordValid(), pSecurityHandler->GetFileKey(), pSecurityHandler->GetFileKeyLength(), pSecurityHandler->GetEncodingVersion(), pSecurityHandler->GetEncodingAlgorithm()); - bResult = true; - } - else - { - // Авторизация не пройдена - bResult = false; - } - delete pSecurityHandler; - } - else - { - bResult = false; - } - } - else - { - // Данный PDF файл не зашифрован - bResult = true; - } - oEncypt.Free(); - return bResult; - } - void PDFDoc::DisplayPage(OutputDev *pOut, int nPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, bool(*pAbortCheckCbk)(void *pData), void *pAbortCheckCbkData) - { - m_pCatalog->GetPage(nPageIndex)->Display(pOut, dHorDPI, dVerDPI, nRotate, bUseMediaBox, bCrop, bPrinting, m_pCatalog, pAbortCheckCbk, pAbortCheckCbkData); - } - void PDFDoc::DisplayPages(OutputDev *pOut, int nFirstPageIndex, int nLastPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, bool(*pAbortCheckCbk)(void *pData), void *pAbortCheckCbkData) - { - for (int nPageIndex = nFirstPageIndex; nPageIndex <= nLastPageIndex; ++nPageIndex) - { - DisplayPage(pOut, nPageIndex, dHorDPI, dVerDPI, nRotate, bUseMediaBox, bCrop, bPrinting, pAbortCheckCbk, pAbortCheckCbkData); - } - } - void PDFDoc::DisplayPageSlice(OutputDev *pOut, int nPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, int nSliceX, int nSliceY, int nSliceW, int nSliceH, bool(*pAbortCheckCbk)(void *pData), void *pAbortCheckCbkData) - { - m_pCatalog->GetPage(nPageIndex)->DisplaySlice(pOut, dHorDPI, dVerDPI, nRotate, bUseMediaBox, bCrop, nSliceX, nSliceY, nSliceW, nSliceH, bPrinting, m_pCatalog, pAbortCheckCbk, pAbortCheckCbkData); - } - Links *PDFDoc::GetLinks(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetLinks(m_pCatalog); - } - void PDFDoc::ProcessLinks(OutputDev *pOut, int nPageIndex) - { - m_pCatalog->GetPage(nPageIndex)->ProcessLinks(pOut, m_pCatalog); - } - bool PDFDoc::IsLinearized() - { - bool bLinearized = false; - Object oTemp; - oTemp.InitNull(); - Parser *pParser = new Parser(m_pXref, new Lexer(m_pXref, m_pStream->MakeSubStream(m_pStream->GetStartPos(), false, 0, &oTemp)), true); - if (!pParser) - { - // TO DO: Error "Can't allocate memory" - oTemp.Free(); - return false; - } - oTemp.Free(); - - Object oNum, oGen, oObj, oDict; - pParser->GetObject(&oNum); - pParser->GetObject(&oGen); - pParser->GetObject(&oObj); - pParser->GetObject(&oDict); - - if (oNum.IsInt() && oGen.IsInt() && oObj.IsCommand("obj") && oDict.IsDict()) - { - Object oVersion; - oDict.DictLookup("Linearized", &oVersion); - if (oVersion.IsNum() && oVersion.GetNum() > 0) - { - bLinearized = true; - } - oVersion.Free(); - } - oDict.Free(); - oObj.Free(); - oGen.Free(); - oNum.Free(); - - delete pParser; - return bLinearized; - } - std::wstring PDFDoc::ToXml() - { - std::wstring wsXml; - - wsXml = L""; - m_pXref->AllObjectsToXml(wsXml, true); - wsXml += L""; - - return wsXml; - } -} diff --git a/PdfReader/old/PDFDoc.h b/PdfReader/old/PDFDoc.h deleted file mode 100644 index 63b6bb7a62..0000000000 --- a/PdfReader/old/PDFDoc.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PDF_DOC_H -#define _PDF_READER_PDF_DOC_H - -#include -#include "XRef.h" -#include "Catalog.h" -#include "Page.h" -#include "ErrorConstants.h" - -namespace PdfReader -{ - class StringExt; - class BaseStream; - class OutputDev; - class Links; - class LinkAction; - class LinkDest; - class Outline; - class PageLabels; - //------------------------------------------------------------------------------------------------------------------------------- - // PDFDoc - //------------------------------------------------------------------------------------------------------------------------------- - - class PDFDoc - { - public: - - PDFDoc(GlobalParams *pGlobalParams, const std::wstring &wsFileName, const std::wstring &ownerPassword, const std::wstring &userPassword); - ~PDFDoc(); - - // Нормально ли открылся PDF файл? - bool CheckValidation() - { - return m_bValid; - } - - // Получаем код ошибки, если PDF файл не открылся. - EError GetErrorCode() - { - return m_eErrorCode; - } - - - // Считываем имя файла. - std::wstring GetFileName() - { - return m_wsFileName; - } - - - // Считываем таблицу Xref. - XRef *GetXRef() - { - return m_pXref; - } - - - // Считываем объект Сatalog. - Catalog *GetCatalog() - { - return m_pCatalog; - } - - - // Считываем поток. - BaseStream *GetBaseStream() - { - return m_pStream; - } - - - // Cчитываем параметры страницы. - double GetPageMediaWidth(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetMediaWidth(); - } - double GetPageMediaHeight(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetMediaHeight(); - } - double GetPageCropWidth(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetCropWidth(); - } - double GetPageCropHeight(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetCropHeight(); - } - int GetPageRotate(int nPageIndex) - { - return m_pCatalog->GetPage(nPageIndex)->GetRotate(); - } - - - // Считываем количество страниц. - int GetPagesCount() - { - return m_pCatalog->GetPagesCount(); - } - - - // Возвращаем содержимое потока метаданных объекта Catalog. - StringExt *ReadMetadata() - { - return m_pCatalog->ReadMetadata(); - } - - - // Возвращаем объект StructureTreeRoot. - Object *GetStructTreeRoot() - { - return m_pCatalog->GetStructTreeRoot(); - } - - - // Выводим данную страницу на устройство pOut. - void DisplayPage(OutputDev *pOut, int nPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, bool(*pAbortCheckCbk)(void *pData) = NULL, void *pAbortCheckCbkData = NULL); - // Выводим сразу несколько страниц. - void DisplayPages(OutputDev *pOut, int nFirstPageIndex, int nLastPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, bool(*pAbortCheckCbk)(void *pData) = NULL, void *pAbortCheckCbkData = NULL); - // Выводим часть страницы. - void DisplayPageSlice(OutputDev *pOut, int nPageIndex, double dHorDPI, double dVerDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, int nSliceX, int nSliceY, int nSliceW, int nSliceH, bool(*pAbortCheckCbk)(void *pData) = NULL, void *pAbortCheckCbkData = NULL); - // Ищем страницу по ее объектным номерам. Возвращаем 0, если страница не найдена. - int FindPage(int nNum, int nGen) - { - return m_pCatalog->FindPage(nNum, nGen); - } - - - // Возвращаем Links для текущей страницы. - Links *GetLinks(int nPageIndex); - // Ищем Destination по имени. Возвращаем Link destination или NULL, если не объект Destination. - LinkDestination *FindDest(StringExt *seName) - { - return m_pCatalog->FindDest(seName); - } - - - // Обрабатываем Links для данной страницы. - void ProcessLinks(OutputDev *pOut, int nPageIndex); - // Возвращаем объект Оutline. - Outline *GetOutline() - { - return m_pOutline; - } - PageLabels *GetPageLabels() - { - return m_pPageLabels; - } - // Зашифрован ли файл? - bool IsEncrypted() - { - return m_pXref->CheckEncrypted(); - } - - // Проверяем различные ограничения. - bool CheckPrint(bool bIgnoreOwnerPassword = false) - { - return m_pXref->CheckPrint(bIgnoreOwnerPassword); - } - bool CheckChange(bool bIgnoreOwnerPassword = false) - { - return m_pXref->CheckChange(bIgnoreOwnerPassword); - } - bool CheckCopy(bool bIgnoreOwnerPassword = false) - { - return m_pXref->CheckCopy(bIgnoreOwnerPassword); - } - bool CheckAddNotes(bool bIgnoreOwnerPassword = false) - { - return m_pXref->CheckAddNotes(bIgnoreOwnerPassword); - } - - // Данный PDF файл является линеаризированным (см. Linearized PDF) - bool IsLinearized(); - // Воозвращаем объек Info. - Object *GetDocInfo(Object *pObject) - { - return m_pXref->GetDocInfo(pObject); - } - Object *GetDocInfoCopy(Object *pObject) - { - return m_pXref->GetDocInfoCopy(pObject); - } - - // Возвращаем версию PDF файла. - double GetPDFVersion() - { - return m_dPDFVersion; - } - - std::wstring ToXml(); - - private: - - bool Setup(const std::wstring &ownerPassword, const std::wstring &userPasswordd); - void CheckHeader(); - bool CheckEncryption(const std::wstring &ownerPassword, const std::wstring &userPassword); - - std::wstring m_wsFileName; // Имя исходного файла. - FILE* m_pFile; // Указатель на файловый поток - unsigned char* m_pFileBuffer; // Буфер для файла - - BaseStream* m_pStream; // Поток, в который считан весь файл - double m_dPDFVersion; // Верисия PDF файла (1.1 - 1.7) - XRef* m_pXref; // Таблица Xref - Catalog* m_pCatalog; // Указатель на объект Catalog - Outline* m_pOutline; // Указатель на Outline (меню) - PageLabels* m_pPageLabels; // Метки для страниц - - bool m_bValid; // Нормально ли открылся PDF файл - EError m_eErrorCode; // Код ошибки - - GlobalParams* m_pGlobalParams; - }; -} -#endif // _PDF_READER_PDF_DOC_H diff --git a/PdfReader/old/PDFDocEncoding.h b/PdfReader/old/PDFDocEncoding.h deleted file mode 100644 index 0d9882cfe6..0000000000 --- a/PdfReader/old/PDFDocEncoding.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PDF_DOC_ENCODING_H -#define _PDF_READER_PDF_DOC_ENCODING_H - -#include "CharTypes.h" - -namespace PdfReader -{ - static Unicode c_arrPDFDocEncoding[256] = - { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0 - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, // 1 - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, // 2 - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, // 3 - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, // 4 - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, // 5 - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, // 6 - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, // 7 - 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, // 8 - 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, // 9 - 0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, // A - 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, // B - 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // C - 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, // D - 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // E - 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff // F - }; -} - -#endif // _PDF_READER_PDF_DOC_ENCODING_H diff --git a/PdfReader/old/PSLexer.cpp b/PdfReader/old/PSLexer.cpp deleted file mode 100644 index cbdd6c9a38..0000000000 --- a/PdfReader/old/PSLexer.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "PSLexer.h" - -namespace PdfReader -{ - // '1' - означает пробел. '1' или '2' означает, что данным символом заканчивается - // имя или команда. - - static char c_sSpecialChars[256] = - { - // 0x 1x 2x 3x 4x 5x 6x 7x 8x 9x ax bx cx dx ex fx - - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x - 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx - }; - - //------------------------------------------------------------------------ - - PSLexer::PSLexer(int(*GetCharFunc)(void *), void *pData) - { - GetCharFunction = GetCharFunc; - m_pData = pData; - m_nCharBuffer = -1; - } - - PSLexer::~PSLexer() - { - } - - bool PSLexer::GetToken(char *sBuffer, int nSize, int *pnLength) - { - int nChar = 0; - - // Пропускаем пробелы и комментарии - bool bComment = false; - while (1) - { - if ((nChar = GetChar()) == EOF) - { - sBuffer[0] = '\0'; - *pnLength = 0; - return false; - } - if (bComment) - { - if (nChar == '\x0a' || nChar == '\x0d') - { - bComment = false; - } - } - else if (nChar == '%') - { - bComment = true; - } - else if (c_sSpecialChars[nChar] != 1) - { - break; - } - } - int nLen = 0; - sBuffer[nLen++] = nChar; - if (nChar == '(') - { - bool bBackslash = false; - while ((nChar = LookChar()) != EOF) - { - if (nLen < nSize - 1) - { - sBuffer[nLen++] = nChar; - } - GetChar(); - if (nChar == '\\') - { - bBackslash = true; - } - else if (!bBackslash && nChar == ')') - { - break; - } - else - { - bBackslash = false; - } - } - } - else if (nChar == '<') - { - while ((nChar = LookChar()) != EOF) - { - GetChar(); - if (nLen < nSize - 1 && c_sSpecialChars[nChar] != 1) - { - sBuffer[nLen++] = nChar; - } - if (nChar == '>') - { - break; - } - } - } - else if (nChar != '[' && nChar != ']') - { - while ((nChar = LookChar()) != EOF && !c_sSpecialChars[nChar]) - { - GetChar(); - if (nLen < nSize - 1) - { - sBuffer[nLen++] = nChar; - } - } - } - sBuffer[nLen] = '\0'; - *pnLength = nLen; - - return true; - } - - int PSLexer::LookChar() - { - if (m_nCharBuffer < 0) - { - m_nCharBuffer = (*GetCharFunction)(m_pData); - } - return m_nCharBuffer; - } - - int PSLexer::GetChar() - { - if (m_nCharBuffer < 0) - { - m_nCharBuffer = (*GetCharFunction)(m_pData); - } - int nChar = m_nCharBuffer; - m_nCharBuffer = -1; - return nChar; - } -} \ No newline at end of file diff --git a/PdfReader/old/PSLexer.h b/PdfReader/old/PSLexer.h deleted file mode 100644 index 869a6f97f6..0000000000 --- a/PdfReader/old/PSLexer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PS_LEXER_H -#define _PDF_READER_PS_LEXER_H - -namespace PdfReader -{ - class PSLexer - { - public: - - PSLexer(int(*GetCharFunc)(void *), void *pData); - ~PSLexer(); - - // Некоторый аналог функции Lexer::GetObject. Но для чтения PS вставок в PDF файле. - // Здесь читаются данные заключенные между скобок "<>", "()" или какая-нибудь команда. - // Данные в квадратных скобках "[]" не читаются. - bool GetToken(char *sBuffer, int nSize, int *pnLength); - - private: - - int LookChar(); - int GetChar(); - - private: - - int(*GetCharFunction)(void *); // Указатель на функцию для считывания символа - void *m_pData; - int m_nCharBuffer; - }; -} - -#endif // _PDF_READER_PS_LEXER_H diff --git a/PdfReader/old/Page.cpp b/PdfReader/old/Page.cpp deleted file mode 100644 index 120dbad316..0000000000 --- a/PdfReader/old/Page.cpp +++ /dev/null @@ -1,564 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "GlobalParams.h" -#include "Object.h" -#include "Array.h" -#include "Dict.h" -#include "XRef.h" -#include "Link.h" -#include "RendererOutputDev.h" -#include "OutputDevice.h" -#include "Graphics.h" -#include "GState.h" -#include "Annot.h" -#include "Catalog.h" -#include "Page.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // PDFRectangle - //------------------------------------------------------------------------ - - void PDFRectangle::ClipTo(PDFRectangle *pRect) - { - if (m_dLeft < pRect->m_dLeft) - { - m_dLeft = pRect->m_dLeft; - } - else if (m_dLeft > pRect->m_dRight) - { - m_dLeft = pRect->m_dRight; - } - if (m_dRight < pRect->m_dLeft) - { - m_dRight = pRect->m_dLeft; - } - else if (m_dRight > pRect->m_dRight) - { - m_dRight = pRect->m_dRight; - } - if (m_dBottom < pRect->m_dBottom) - { - m_dBottom = pRect->m_dBottom; - } - else if (m_dBottom > pRect->m_dTop) - { - m_dBottom = pRect->m_dTop; - } - if (m_dTop < pRect->m_dBottom) - { - m_dTop = pRect->m_dBottom; - } - else if (m_dTop > pRect->m_dTop) - { - m_dTop = pRect->m_dTop; - } - } - - //------------------------------------------------------------------------ - // PageAttrs - //------------------------------------------------------------------------ - - PageAttrs::PageAttrs(PageAttrs *pAttrs, Dict *pDict) - { - Object obj1; - - if (pAttrs) // Предыдущие настройки - { - m_oMediaBox = pAttrs->m_oMediaBox; - m_pCropBox = pAttrs->m_pCropBox; - m_bHaveCropBox = pAttrs->m_bHaveCropBox; - m_nRotate = pAttrs->m_nRotate; - pAttrs->m_oResources.Copy(&m_oResources); - } - else // Настройки по умолчанию - { - m_oMediaBox.m_dLeft = 0; - m_oMediaBox.m_dBottom = 0; - m_oMediaBox.m_dRight = 612; - m_oMediaBox.m_dTop = 792; - - m_pCropBox.m_dLeft = m_pCropBox.m_dBottom = m_pCropBox.m_dRight = m_pCropBox.m_dTop = 0; - m_bHaveCropBox = false; - m_nRotate = 0; - m_oResources.InitNull(); - } - - // MediaBox - ReadBox(pDict, "MediaBox", &m_oMediaBox); - - // CropBox - if (ReadBox(pDict, "CropBox", &m_pCropBox)) - { - m_bHaveCropBox = true; - } - if (!m_bHaveCropBox) - { - m_pCropBox = m_oMediaBox; - } - - // Остальные - m_oBleedBox = m_pCropBox; - ReadBox(pDict, "BleedBox", &m_oBleedBox); - - m_oTrimBox = m_pCropBox; - ReadBox(pDict, "TrimBox", &m_oTrimBox); - - m_oArtBox = m_pCropBox; - ReadBox(pDict, "ArtBox", &m_oArtBox); - - // Подгоняем размеры под m_oMediaBox - m_pCropBox.ClipTo(&m_oMediaBox); - m_oBleedBox.ClipTo(&m_oMediaBox); - m_oTrimBox.ClipTo(&m_oMediaBox); - m_oArtBox.ClipTo(&m_oMediaBox); - - // Поворот - Object oTemp; - pDict->Search("Rotate", &oTemp); - if (oTemp.IsInt()) - { - m_nRotate = oTemp.GetInt(); - } - oTemp.Free(); - while (m_nRotate < 0) - { - m_nRotate += 360; - } - while (m_nRotate >= 360) - { - m_nRotate -= 360; - } - - pDict->Search("LastModified", &m_oLastModified); - pDict->Search("BoxColorInfo", &m_oBoxColorInfo); - pDict->Search("Group", &m_oGroup); - pDict->Search("Metadata", &m_oMetadata); - pDict->Search("PieceInfo", &m_oPieceInfo); - pDict->Search("SeparationInfo", &m_oSeparationInfo); - - // Resources - pDict->Search("Resources", &oTemp); - if (oTemp.IsDict()) - { - m_oResources.Free(); - oTemp.Copy(&m_oResources); - } - oTemp.Free(); - } - - PageAttrs::~PageAttrs() - { - m_oLastModified.Free(); - m_oBoxColorInfo.Free(); - m_oGroup.Free(); - m_oMetadata.Free(); - m_oPieceInfo.Free(); - m_oSeparationInfo.Free(); - m_oResources.Free(); - } - - bool PageAttrs::ReadBox(Dict *pDict, char *sKey, PDFRectangle *pBox) - { - PDFRectangle oTempBox; - bool bSuccess = false; - - Object oBox; - pDict->Search(sKey, &oBox); - if (oBox.IsArray() && oBox.ArrayGetLength() == 4) - { - bSuccess = true; - Object oTemp; - oBox.ArrayGet(0, &oTemp); - if (oTemp.IsNum()) - { - oTempBox.m_dLeft = oTemp.GetNum(); - } - else - { - bSuccess = false; - } - oTemp.Free(); - oBox.ArrayGet(1, &oTemp); - if (oTemp.IsNum()) - { - oTempBox.m_dBottom = oTemp.GetNum(); - } - else - { - bSuccess = false; - } - oTemp.Free(); - oBox.ArrayGet(2, &oTemp); - if (oTemp.IsNum()) - { - oTempBox.m_dRight = oTemp.GetNum(); - } - else - { - bSuccess = false; - } - oTemp.Free(); - oBox.ArrayGet(3, &oTemp); - if (oTemp.IsNum()) - { - oTempBox.m_dTop = oTemp.GetNum(); - } - else - { - bSuccess = false; - } - oTemp.Free(); - if (bSuccess) - { - if (oTempBox.m_dLeft > oTempBox.m_dRight) - { - double dTempValue = oTempBox.m_dLeft; - oTempBox.m_dLeft = oTempBox.m_dRight; - oTempBox.m_dRight = dTempValue; - } - if (oTempBox.m_dBottom > oTempBox.m_dTop) - { - double dTempValue = oTempBox.m_dBottom; - oTempBox.m_dBottom = oTempBox.m_dTop; - oTempBox.m_dTop = dTempValue; - } - *pBox = oTempBox; - } - } - else - { - bSuccess = false; - } - oBox.Free(); - return bSuccess; - } - - //------------------------------------------------------------------------ - // Page - //------------------------------------------------------------------------ - - Page::Page(GlobalParams *pGlobalParams, XRef *pXref, int nNum, Dict *pPageDict, PageAttrs *pAttrs) - { - m_pGlobalParams = pGlobalParams; - - m_bValid = true; - m_pXref = pXref; - m_nNumber = nNum; - - // Attributes - m_pAttrs = pAttrs; - - // Annotations - pPageDict->SearchAndCopy("Annots", &m_oAnnots); - if (!(m_oAnnots.IsRef() || m_oAnnots.IsArray() || m_oAnnots.IsNull())) - { - // TO DO: Error "Page annotations object is wrong type" - m_oAnnots.Free(); - m_oAnnots.InitNull(); - m_oContents.InitNull(); - m_bValid = false; - } - - // Contents - pPageDict->SearchAndCopy("Contents", &m_oContents); - if (!(m_oContents.IsRef() || m_oContents.IsArray() || m_oContents.IsNull())) - { - // TO DO: Error "Page contents object is wrong type" - m_oContents.Free(); - m_oContents.InitNull(); - m_bValid = false; - } - - ////---------------------------------------------------------------- - // - // Object oContent; - // m_oContents.Fetch( m_pXref, &oContent ); - // if ( oContent.IsArray() ) - // { - // int m_nStreamsCount = oContent.ArrayGetLength(); - // for ( int nIndex = 0; nIndex < oContent.ArrayGetLength(); ++nIndex ) - // { - // Object oTemp; - // oContent.ArrayGet( nIndex, &oTemp ); - // if ( oTemp.IsStream() ) - // { - // Stream *pStream = oTemp.GetStream(); - // pStream->Reset(); - // while ( EOF != pStream->GetChar() ); - // } - // oTemp.Free(); - // } - // } - // else if ( oContent.IsStream() ) - // { - // Stream *pStream = oContent.GetStream(); - // pStream->Reset(); - // - // int nSize = 128, nPos = 0; - // char *sBuffer = (char *)MemUtilsMalloc( nSize ); - // int nChar = 0; - // while ( EOF != ( nChar = pStream->GetChar() ) ) - // { - // if ( nPos + 1 >= nSize ) - // { - // nSize *= 2; - // sBuffer = (char *)MemUtilsRealloc( (void *)sBuffer, nSize ); - // } - // sBuffer[nPos] = nChar; - // nPos++; - // } - // sBuffer[nPos] = '\0'; - // - // Object oTemp; - // Stream *pNewStream = new MemoryStream( sBuffer, 0, nPos, &oTemp ); - // - // //int m_nStreamsCount = 1; - // //m_ppStreams = (Stream**)MemUtilsMalloc( sizeof(Stream*) ); - // //m_ppStreams[0] = oContent.GetStream(); - // //m_ppStreams[0]->Reset(); - // - // //while ( EOF != m_ppStreams[0]->GetChar() ); - // - // m_oContents2.InitStream( pNewStream ); - // } - // - // oContent.Free(); - //// - //////---------------------------------------------------------------- - return; - } - - Page::~Page() - { - delete m_pAttrs; - m_oAnnots.Free(); - m_oContents.Free(); - } - - Links *Page::GetLinks(Catalog *pCatalog) - { - Object oTemp; - - Links *pLinks = new Links(GetAnnots(&oTemp), pCatalog->GetBaseURI()); - oTemp.Free(); - return pLinks; - } - - void Page::Display(OutputDev *pOut, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, Catalog *pCatalog, bool(*abortCheckCbk)(void *pData), void *abortCheckCbkData) - { - DisplaySlice(pOut, dHorizDPI, dVertDPI, nRotate, bUseMediaBox, bCrop, -1, -1, -1, -1, bPrinting, pCatalog, abortCheckCbk, abortCheckCbkData); - } - - void Page::DisplaySlice(OutputDev *pOut, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bCrop, int nSliceX, int nSliceY, int nSliceW, int nSliceH, bool bPrinting, Catalog *pCatalog, bool(*abortCheckCbk)(void *pData), void *abortCheckCbkData) - { - if (!pOut->CheckPageSlice(this, dHorizDPI, dVertDPI, nRotate, bUseMediaBox, bCrop, nSliceX, nSliceY, nSliceW, nSliceH, bPrinting, pCatalog, abortCheckCbk, abortCheckCbkData)) - { - return; - } - - nRotate += GetRotate(); - if (nRotate >= 360) - { - nRotate -= 360; - } - else if (nRotate < 0) - { - nRotate += 360; - } - - PDFRectangle oBox; - MakeBox(dHorizDPI, dVertDPI, nRotate, bUseMediaBox, pOut->UpSideDown(), nSliceX, nSliceY, nSliceW, nSliceH, &oBox, &bCrop); - PDFRectangle *pCropBox = GetCropBox(); - - Graphics *pGraphics = new Graphics(m_pGlobalParams, m_pXref, pOut, m_nNumber, m_pAttrs->GetResourceDict(), dHorizDPI, dVertDPI, &oBox, bCrop ? pCropBox : (PDFRectangle *)NULL, nRotate, abortCheckCbk, abortCheckCbkData); - if (pGraphics) - { - Object oTemp; - m_oContents.Fetch(m_pXref, &oTemp); - if (!oTemp.IsNull()) - { - pGraphics->SaveGState(); - pGraphics->Display(&oTemp); - pGraphics->RestoreGState(); - } - oTemp.Free(); - - Annots *pAnnotList = new Annots(m_pGlobalParams, m_pXref, pCatalog, GetAnnots(&oTemp)); - oTemp.Free(); - if (pAnnotList) - { - Dict *pAcroForm = pCatalog->GetAcroForm()->IsDict() ? pCatalog->GetAcroForm()->GetDict() : NULL; - if (pAcroForm) - { - if (pAcroForm->Search("NeedAppearances", &oTemp)) - { - if (oTemp.IsBool() && oTemp.GetBool()) - { - pAnnotList->GenerateAppearances(pAcroForm); - } - } - oTemp.Free(); - } - if (pAnnotList->GetAnnotsCount() > 0) - { - for (int nIndex = 0; nIndex < pAnnotList->GetAnnotsCount(); ++nIndex) - { - pAnnotList->GetAnnot(nIndex)->Draw(pGraphics, bPrinting); - } - pOut->Dump(); - } - delete pAnnotList; - } - delete pGraphics; - } - } - - void Page::MakeBox(double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bUpSideDown, double dSliceX, double dSliceY, double dSliceW, double dSliceH, PDFRectangle *pBox, bool *pbCrop) - { - PDFRectangle *pMediaBox = GetMediaBox(); - PDFRectangle *pCropBox = GetCropBox(); - - if (dSliceW >= 0 && dSliceH >= 0) - { - PDFRectangle *pBaseBox = bUseMediaBox ? pMediaBox : pCropBox; - double dKoefX = 72.0 / dHorizDPI; - double dKoefY = 72.0 / dVertDPI; - if (nRotate == 90) - { - if (bUpSideDown) - { - pBox->m_dLeft = pBaseBox->m_dLeft + dKoefY * dSliceY; - pBox->m_dRight = pBaseBox->m_dLeft + dKoefY * (dSliceY + dSliceH); - } - else - { - pBox->m_dLeft = pBaseBox->m_dRight - dKoefY * (dSliceY + dSliceH); - pBox->m_dRight = pBaseBox->m_dRight - dKoefY * dSliceY; - } - pBox->m_dBottom = pBaseBox->m_dBottom + dKoefX * dSliceX; - pBox->m_dTop = pBaseBox->m_dBottom + dKoefX * (dSliceX + dSliceW); - } - else if (nRotate == 180) - { - pBox->m_dLeft = pBaseBox->m_dRight - dKoefX * (dSliceX + dSliceW); - pBox->m_dRight = pBaseBox->m_dRight - dKoefX * dSliceX; - if (bUpSideDown) - { - pBox->m_dBottom = pBaseBox->m_dBottom + dKoefY * dSliceY; - pBox->m_dTop = pBaseBox->m_dBottom + dKoefY * (dSliceY + dSliceH); - } - else - { - pBox->m_dBottom = pBaseBox->m_dTop - dKoefY * (dSliceY + dSliceH); - pBox->m_dTop = pBaseBox->m_dTop - dKoefY * dSliceY; - } - } - else if (nRotate == 270) - { - if (bUpSideDown) - { - pBox->m_dLeft = pBaseBox->m_dRight - dKoefY * (dSliceY + dSliceH); - pBox->m_dRight = pBaseBox->m_dRight - dKoefY * dSliceY; - } - else - { - pBox->m_dLeft = pBaseBox->m_dLeft + dKoefY * dSliceY; - pBox->m_dRight = pBaseBox->m_dLeft + dKoefY * (dSliceY + dSliceH); - } - pBox->m_dBottom = pBaseBox->m_dTop - dKoefX * (dSliceX + dSliceW); - pBox->m_dTop = pBaseBox->m_dTop - dKoefX * dSliceX; - } - else - { - pBox->m_dLeft = pBaseBox->m_dLeft + dKoefX * dSliceX; - pBox->m_dRight = pBaseBox->m_dLeft + dKoefX * (dSliceX + dSliceW); - if (bUpSideDown) - { - pBox->m_dBottom = pBaseBox->m_dTop - dKoefY * (dSliceY + dSliceH); - pBox->m_dTop = pBaseBox->m_dTop - dKoefY * dSliceY; - } - else - { - pBox->m_dBottom = pBaseBox->m_dBottom + dKoefY * dSliceY; - pBox->m_dTop = pBaseBox->m_dBottom + dKoefY * (dSliceY + dSliceH); - } - } - } - else if (bUseMediaBox) - { - *pBox = *pMediaBox; - } - else - { - *pBox = *pCropBox; - *pbCrop = false; - } - } - - void Page::ProcessLinks(OutputDev *pOut, Catalog *pCatalog) - { - Links *pLinks = GetLinks(pCatalog); - if (pLinks) - { - for (int nIndex = 0; nIndex < pLinks->GetLinksCount(); ++nIndex) - { - pOut->ProcessLink(pLinks->GetLink(nIndex), pCatalog); - } - delete pLinks; - } - } - - void Page::GetDefaultCTM(double *pCTM, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bUpSideDown) - { - nRotate += GetRotate(); - if (nRotate >= 360) - { - nRotate -= 360; - } - else if (nRotate < 0) - { - nRotate += 360; - } - GrState *pGState = new GrState(dHorizDPI, dVertDPI, bUseMediaBox ? GetMediaBox() : GetCropBox(), nRotate, bUpSideDown); - if (pGState) - { - for (int nIndex = 0; nIndex < 6; ++nIndex) - { - pCTM[nIndex] = pGState->GetCTM()[nIndex]; - } - delete pGState; - } - } -} diff --git a/PdfReader/old/Page.h b/PdfReader/old/Page.h deleted file mode 100644 index a79a465007..0000000000 --- a/PdfReader/old/Page.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PAGE_H -#define _PDF_READER_PAGE_H - -#include "Object.h" -#include "GlobalParams.h" - -namespace PdfReader -{ - class Dict; - class XRef; - class OutputDev; - class Links; - class Catalog; - - //------------------------------------------------------------------------ - - class PDFRectangle - { - public: - - PDFRectangle() - { - m_dLeft = m_dBottom = m_dRight = m_dTop = 0; - } - PDFRectangle(double dLeft, double dBottom, double dRight, double dTop) - { - m_dLeft = dLeft; - m_dBottom = dBottom; - m_dRight = dRight; - m_dTop = dTop; - } - bool IsValid() - { - return m_dLeft != 0 || m_dBottom != 0 || m_dRight != 0 || m_dTop != 0; - } - void ClipTo(PDFRectangle *pRect); - - public: - - double m_dLeft; - double m_dBottom; - double m_dRight; - double m_dTop; - }; - - //------------------------------------------------------------------------ - // PageAttrs - //------------------------------------------------------------------------ - - class PageAttrs - { - public: - - // Строим новый объект PageAttrs либо с начальными настройками из - // pAttrs, либо со стандартными начальными настройками(если pAttrs = - // NULL). - PageAttrs(PageAttrs *pAttrs, Dict *pDict); - - ~PageAttrs(); - - PDFRectangle *GetMediaBox() - { - return &m_oMediaBox; - } - PDFRectangle *GetCropBox() - { - return &m_pCropBox; - } - bool IsCropped() - { - return m_bHaveCropBox; - } - PDFRectangle *GetBleedBox() - { - return &m_oBleedBox; - } - PDFRectangle *GetTrimBox() - { - return &m_oTrimBox; - } - PDFRectangle *GetArtBox() - { - return &m_oArtBox; - } - int GetRotate() - { - return m_nRotate; - } - StringExt *GetLastModified() - { - return (m_oLastModified.IsString() ? m_oLastModified.GetString() : (StringExt *)NULL); - } - Dict *GetBoxColorInfo() - { - return (m_oBoxColorInfo.IsDict() ? m_oBoxColorInfo.GetDict() : (Dict *)NULL); - } - Dict *GetGroup() - { - return (m_oGroup.IsDict() ? m_oGroup.GetDict() : (Dict *)NULL); - } - Stream *GetMetadata() - { - return (m_oMetadata.IsStream() ? m_oMetadata.GetStream() : (Stream *)NULL); - } - Dict *GetPieceInfo() - { - return (m_oPieceInfo.IsDict() ? m_oPieceInfo.GetDict() : (Dict *)NULL); - } - Dict *GetSeparationInfo() - { - return (m_oSeparationInfo.IsDict() ? m_oSeparationInfo.GetDict() : (Dict *)NULL); - } - Dict *GetResourceDict() - { - return (m_oResources.IsDict() ? m_oResources.GetDict() : (Dict *)NULL); - } - - private: - - bool ReadBox(Dict *pDict, char *sKey, PDFRectangle *pBox); - - private: - - PDFRectangle m_oMediaBox; - PDFRectangle m_pCropBox; - bool m_bHaveCropBox; - PDFRectangle m_oBleedBox; - PDFRectangle m_oTrimBox; - PDFRectangle m_oArtBox; - - int m_nRotate; - - Object m_oLastModified; - Object m_oBoxColorInfo; - Object m_oGroup; - Object m_oMetadata; - Object m_oPieceInfo; - Object m_oSeparationInfo; - Object m_oResources; - }; - - //------------------------------------------------------------------------ - // Page - //------------------------------------------------------------------------ - - class Page - { - public: - - Page(GlobalParams *pGlobalParams, XRef *pXref, int nNum, Dict *pPageDict, PageAttrs *pAttrs); - - ~Page(); - - bool IsValid() - { - return m_bValid; - } - - int GetNum() - { - return m_nNumber; - } - PDFRectangle *GetMediaBox() - { - return m_pAttrs->GetMediaBox(); - } - PDFRectangle *GetCropBox() - { - return m_pAttrs->GetCropBox(); - } - bool IsCropped() - { - return m_pAttrs->IsCropped(); - } - double GetMediaWidth() - { - return m_pAttrs->GetMediaBox()->m_dRight - m_pAttrs->GetMediaBox()->m_dLeft; - } - double GetMediaHeight() - { - return m_pAttrs->GetMediaBox()->m_dTop - m_pAttrs->GetMediaBox()->m_dBottom; - } - double GetCropWidth() - { - return m_pAttrs->GetCropBox()->m_dRight - m_pAttrs->GetCropBox()->m_dLeft; - } - double GetCropHeight() - { - return m_pAttrs->GetCropBox()->m_dTop - m_pAttrs->GetCropBox()->m_dBottom; - } - PDFRectangle *GetBleedBox() - { - return m_pAttrs->GetBleedBox(); - } - PDFRectangle *GetTrimBox() - { - return m_pAttrs->GetTrimBox(); - } - PDFRectangle *GetArtBox() - { - return m_pAttrs->GetArtBox(); - } - int GetRotate() - { - return m_pAttrs->GetRotate(); - } - StringExt *GetLastModified() - { - return m_pAttrs->GetLastModified(); - } - Dict *GetBoxColorInfo() - { - return m_pAttrs->GetBoxColorInfo(); - } - Dict *GetGroup() - { - return m_pAttrs->GetGroup(); - } - Stream *GetMetadata() - { - return m_pAttrs->GetMetadata(); - } - Dict *GetPieceInfo() - { - return m_pAttrs->GetPieceInfo(); - } - Dict *GetSeparationInfo() - { - return m_pAttrs->GetSeparationInfo(); - } - - // Resource - Dict *GetResourceDict() - { - return m_pAttrs->GetResourceDict(); - } - - // Annotations - Object *GetAnnots(Object *pObject) - { - return m_oAnnots.Fetch(m_pXref, pObject); - } - - // Links - Links *GetLinks(Catalog *catalog); - - // Contents - Object *GetContents(Object *pObject) - { - return m_oContents.Fetch(m_pXref, pObject); - } - - // - void Display(OutputDev *pOut, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bCrop, bool bPrinting, Catalog *pCatalog, bool(*abortCheckCbk)(void *pData) = NULL, void *abortCheckCbkData = NULL); - - void DisplaySlice(OutputDev *pOut, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bCrop, int nSliceX, int nSliceY, int nSliceW, int nSliceH, bool bPrinting, Catalog *pCatalog, bool(*abortCheckCbk)(void *pData) = NULL, void *abortCheckCbkData = NULL); - - void MakeBox(double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bUpSideDown, double dSliceX, double dSliceY, double dSliceW, double dSliceH, PDFRectangle *pBox, bool *pbCrop); - - void ProcessLinks(OutputDev *pOut, Catalog *pCatalog); - - void GetDefaultCTM(double *pCTM, double dHorizDPI, double dVertDPI, int nRotate, bool bUseMediaBox, bool bUpSideDown); - - private: - - XRef *m_pXref; // Таблица xref для данного PDF документа - int m_nNumber; // Номер страницы - PageAttrs *m_pAttrs; // Page attributes - Object m_oAnnots; // Annotations - Object m_oContents; // Содержимое страницы - Object m_oContents2; - bool m_bValid; // - - GlobalParams *m_pGlobalParams; - }; -} - -#endif // _PDF_READER_PAGE_H diff --git a/PdfReader/old/PageLabels.cpp b/PdfReader/old/PageLabels.cpp deleted file mode 100644 index 91823333d1..0000000000 --- a/PdfReader/old/PageLabels.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ - -#include "PageLabels.h" -#include "Array.h" -#include "Dict.h" -#include "XRef.h" -#include "List.h" -#include "StringExt.h" - -namespace PdfReader -{ - PageLabels::PageLabels(Object* pPageLabelsObject, XRef* pXRef) - { - m_pNums = NULL; - - if (!pPageLabelsObject || !pPageLabelsObject->IsDict()) - return; - - Dict* pDict = pPageLabelsObject->GetDict(); - - Object oNums; - if (pDict->Search("Nums", &oNums)->IsArray()) - { - int nCount = oNums.ArrayGetLength(); - int nIndex = 0; - - while (nIndex < nCount) - { - Object oEntry; - oNums.ArrayGet(nIndex++, &oEntry); - - int nPageNum = 0, nStart = 1; - StringExt* sPrefix = NULL; - PageLabelStyle eLabelStyle = pageLabelNone; - - if (oEntry.IsInt()) - nPageNum = oEntry.GetInt(); - - oEntry.Free(); - - if (nIndex >= nCount) - break; - - oNums.ArrayGet(nIndex++, &oEntry); - if (!oEntry.IsDict()) - break; - - Dict* pEntryDict = oEntry.GetDict(); - - Object oEntry2; - pEntryDict->Search("S", &oEntry2); - if (oEntry2.IsName()) - { - if (oEntry2.IsName("D")) - eLabelStyle = pageLabelDecimal; - else if (oEntry2.IsName("R")) - eLabelStyle = pageLabelUpperRoman; - else if (oEntry2.IsName("r")) - eLabelStyle = pageLabelLowerRoman; - else if (oEntry2.IsName("A")) - eLabelStyle = pageLabelUpperLetter; - else if (oEntry2.IsName("a")) - eLabelStyle = pageLabelLowerLetter; - } - - oEntry2.Free(); - - pEntryDict->Search("P", &oEntry2); - if (oEntry2.IsString()) - sPrefix = oEntry2.GetString()->Copy(); - - oEntry2.Free(); - - pEntryDict->Search("St", &oEntry2); - if (oEntry2.IsInt()) - nStart = oEntry2.GetInt(); - - oEntry2.Free(); - oEntry.Free(); - - if (!m_pNums) - m_pNums = new CList(); - - m_pNums->Append(new PageLabelsEntry(nPageNum, nStart, eLabelStyle, sPrefix)); - } - } - } - PageLabels::~PageLabels() - { - if (m_pNums) - { - DeleteCList(m_pNums, PageLabelsEntry); - } - } - StringExt* PageLabels::GetLabel(int nPageIndex) - { - if (!m_pNums) - return NULL; - - StringExt* seResult = new StringExt(); - - for (int nIndex = m_pNums->GetLength() - 1; nIndex >= 0; --nIndex) - { - PageLabelsEntry* pEntry = (PageLabelsEntry*)m_pNums->GetByIndex(nIndex); - if (pEntry->m_nPageIndex <= nPageIndex) - { - if (pEntry->m_sPrefix) - seResult->Append(pEntry->m_sPrefix); - - int nValue = (nPageIndex - pEntry->m_nPageIndex) + pEntry->m_nStart; - - if (pageLabelDecimal == pEntry->m_eStyle) - { - seResult->AppendFormat("{0:d}", nValue); - } - else if (pageLabelLowerLetter == pEntry->m_eStyle || pageLabelUpperLetter == pEntry->m_eStyle) - { - // Формат: a,..,z,aa,..,zz,aaa,...,zzz,... - int nNum = nValue - 1; - - int nCount = (nNum - nNum % 26) / 26; - int nOst = nNum % 26; - - int nChar; - if (pageLabelLowerLetter == pEntry->m_eStyle) - nChar = nOst + 97; - else - nChar = nOst + 65; - - for (int nCharIndex = 0; nCharIndex < nCount + 1; ++nCharIndex) - seResult->Append(nChar); - } - else if (pageLabelLowerRoman == pEntry->m_eStyle || pageLabelUpperRoman == pEntry->m_eStyle) - { - int nNum = nValue; - - // Переводим число Num в римскую систему исчисления - const char *pRIMS[14] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I", " "}; - const char *pRims[14] = {"m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i", " "}; - - int pVals[14] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1, 0}; - - int nPos = 0; - while (nNum > 0) - { - while (pVals[nPos] <= nNum) - { - seResult->Append(pageLabelLowerRoman == pEntry->m_eStyle ? pRims[nPos] : pRIMS[nPos]); - nNum -= pVals[nPos]; - } - - nPos++; - - if (nPos >= 14) - break; - } - break; - } - - break; - } - } - - return seResult; - } - - PageLabelsEntry::PageLabelsEntry(int nPageIndex, int nStart, PageLabelStyle eStyle, StringExt* sPrefix) - { - m_nPageIndex = nPageIndex; - m_nStart = nStart; - m_eStyle = eStyle; - m_sPrefix = sPrefix; - } - PageLabelsEntry::~PageLabelsEntry() - { - if (m_sPrefix) - delete m_sPrefix; - } -} diff --git a/PdfReader/old/PageLabels.h b/PdfReader/old/PageLabels.h deleted file mode 100644 index e9c5be86b1..0000000000 --- a/PdfReader/old/PageLabels.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PAGELABELS_H -#define _PDF_READER_PAGELABELS_H - -#include "Object.h" -#include "List.h" - -namespace PdfReader -{ - class XRef; - class StringExt; - - //------------------------------------------------------------------------ - // GrFontType - //------------------------------------------------------------------------ - - enum PageLabelStyle - { - pageLabelNone, - pageLabelDecimal, - pageLabelUpperRoman, - pageLabelLowerRoman, - pageLabelUpperLetter, - pageLabelLowerLetter - }; - - //------------------------------------------------------------------------ - // PageLabels - //------------------------------------------------------------------------ - - class PageLabels - { - public: - - PageLabels(Object* pPageLabelsObject, XRef *pXref); - ~PageLabels(); - - StringExt* GetLabel(int nPageIndex); - - private: - - CList* m_pNums; - }; - - class PageLabelsEntry - { - public: - - PageLabelsEntry(int nPageIndex, int nStart, PageLabelStyle eStyle, StringExt* sPrefix); - ~PageLabelsEntry(); - - private: - - int m_nPageIndex; - int m_nStart; - PageLabelStyle m_eStyle; - StringExt* m_sPrefix; - - friend PageLabels; - }; - -} - -#endif // _PDF_READER_PAGELABELS_H diff --git a/PdfReader/old/Parser.cpp b/PdfReader/old/Parser.cpp deleted file mode 100644 index e96acbb522..0000000000 --- a/PdfReader/old/Parser.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include "Object.h" -#include "Array.h" -#include "Dict.h" -#include "Decrypt.h" -#include "Parser.h" -#include "XRef.h" - -namespace PdfReader -{ - Parser::Parser(XRef *pXref, Lexer *pLexer, bool bAllowStreams) - { - m_pXref = pXref; - m_pLexer = pLexer; - m_nInlineImage = 0; - m_bAllowStreams = bAllowStreams; - m_pLexer->GetObject(&m_oBuffer1); - m_pLexer->GetObject(&m_oBuffer2); - } - - Parser::~Parser() - { - m_oBuffer1.Free(); - m_oBuffer2.Free(); - delete m_pLexer; - } - - Object *Parser::GetObject(Object *pObject, unsigned char *sDecryptKey, CryptAlgorithm eEncryptAlgorithm, int nKeyLength, int nObjectNum, int nObjectGen) - { - Stream *pStream = NULL; - Object oTemp; - int nNum = 0; - - // Обновляем буффер после Inline image data - if (m_nInlineImage == 2) - { - m_oBuffer1.Free(); - m_oBuffer2.Free(); - m_pLexer->GetObject(&m_oBuffer1); - m_pLexer->GetObject(&m_oBuffer2); - m_nInlineImage = 0; - } - - // Массив - if (m_oBuffer1.IsCommand("[")) - { - Shift(); - pObject->InitArray(m_pXref); - while (!m_oBuffer1.IsCommand("]") && !m_oBuffer1.IsEOF()) - pObject->ArrayAdd(GetObject(&oTemp, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen)); - if (m_oBuffer1.IsEOF()) - { - // TO DO: Error "End of file inside array" - } - Shift(); - } - else if (m_oBuffer1.IsCommand("<<")) // Dictionary или Stream - { - Shift(); - pObject->InitDict(m_pXref); - while (!m_oBuffer1.IsCommand(">>") && !m_oBuffer1.IsEOF()) - { - if (!m_oBuffer1.IsName()) - { - // TO DO: Error "Dictionary key must be a name object" - Shift(); - } - else - { - char *sKey = CopyString(m_oBuffer1.GetName()); - Shift(); - if (m_oBuffer1.IsEOF() || m_oBuffer1.IsError()) - { - MemUtilsFree(sKey); - break; - } - pObject->DictAdd(sKey, GetObject(&oTemp, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen)); - } - } - if (m_oBuffer1.IsEOF()) - { - // TO DO: Error "End of file inside dictionary" - } - // Объекты Stream Objects не допустимы внутри потока или объекта типа Stream Objects - if (m_bAllowStreams && m_oBuffer2.IsCommand("stream")) - { - if ((pStream = CreateStream(pObject, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen))) - { - pObject->InitStream(pStream); - } - else - { - pObject->Free(); - pObject->InitError(); - } - } - else - { - Shift(); - } - } - else if (m_oBuffer1.IsInt()) // Либо ссылка, либо число - { - nNum = m_oBuffer1.GetInt(); - Shift(); - if (m_oBuffer1.IsInt() && m_oBuffer2.IsCommand("R")) - { - pObject->InitRef(nNum, m_oBuffer1.GetInt()); - Shift(); - Shift(); - } - else - { - pObject->InitInt(nNum); - } - } - else if (m_oBuffer1.IsString() && sDecryptKey) // строка - { - StringExt *seTemp = m_oBuffer1.GetString(); - StringExt *seRes = new StringExt(); - oTemp.InitNull(); - DecryptStream *pDecrypt = new DecryptStream(new MemoryStream(seTemp->GetBuffer(), 0, seTemp->GetLength(), &oTemp), sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen); - pDecrypt->Reset(); - int nChar = 0; - while ((nChar = pDecrypt->GetChar()) != EOF) - { - seRes->Append((char)nChar); - } - delete pDecrypt; - pObject->InitString(seRes); - Shift(); - } - else // простой объект - { - m_oBuffer1.Copy(pObject); - Shift(); - } - - return pObject; - } - - Stream *Parser::CreateStream(Object *pDict, unsigned char *sDecryptKey, CryptAlgorithm eEncryptAlgorithm, int nKeyLength, int nObjectNum, int nObjectGen) - { - Object oTemp; - unsigned int nLength, unEndPos; - - m_pLexer->SkipToNextLine(); - unsigned int unPos = m_pLexer->GetPos(); - - // Считываем длину - pDict->DictLookup("Length", &oTemp); - if (oTemp.IsInt()) - { - nLength = (unsigned int)oTemp.GetInt(); - oTemp.Free(); - } - else - { - oTemp.Free(); - unsigned int unEndPos = unPos; - - while (!m_oBuffer2.IsCommand("endstream") && !m_oBuffer2.IsEOF()) - { - unEndPos = m_pLexer->GetPos(); - Shift(); - } - - nLength = unEndPos - unPos; - m_pLexer->SetPos(unPos); - - // Оставим на всякий случай заглушку - if (nLength <= 0) - nLength = 5000; - } - - // Меняем длину, если файл поврежден - if (m_pXref && m_pXref->GetStreamEnd(unPos, &unEndPos)) - { - nLength = unEndPos - unPos; - } - - // В сильно повержденных файлах PDF, выставляем конец потока сразу - // после его начала - if (!m_pLexer->GetStream()) - { - return NULL; - } - - BaseStream *pBaseStream = m_pLexer->GetStream()->GetBaseStream(); - - // Пропускаем данный потока - m_pLexer->SetPos(unPos + nLength); - - // Проверяем 'endstream' - Shift(); // '>>' - Shift(); // 'endstream' - if (m_oBuffer1.IsCommand("endstream")) - { - Shift(); - } - else - { - // TO DO : Error "Missing 'endstream'" - - // Заплатка для поврежденных файлов: - nLength += 5000; - } - - Stream *pStream = pBaseStream->MakeSubStream(unPos, true, nLength, pDict); - - // Decryption - if (sDecryptKey) - { - pStream = new DecryptStream(pStream, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen); - } - - // Filters - pStream = pStream->AddFilters(pDict); - - return pStream; - } - - void Parser::Shift() - { - if (m_nInlineImage > 0) - { - if (m_nInlineImage < 2) - { - ++m_nInlineImage; - } - else - { - // В поврежденном потоке, если 'ID' появляется в середине потока, - // нужно сбросить параметры - m_nInlineImage = 0; - } - } - else if (m_oBuffer2.IsCommand("ID")) - { - m_pLexer->SkipChar(); // пропускаем символ после команды 'ID' - m_nInlineImage = 1; - } - m_oBuffer1.Free(); - m_oBuffer1 = m_oBuffer2; - if (m_nInlineImage > 0) // не буфферизируем данные Inline Image - m_oBuffer2.InitNull(); - else - m_pLexer->GetObject(&m_oBuffer2); - } -} \ No newline at end of file diff --git a/PdfReader/old/Parser.h b/PdfReader/old/Parser.h deleted file mode 100644 index 317072e076..0000000000 --- a/PdfReader/old/Parser.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_PARSER_H -#define _PDF_READER_PARSER_H - -#include "Lexer.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------ - // Parser - //------------------------------------------------------------------------ - - class Parser - { - public: - - Parser(XRef *pXref, Lexer *pLexer, bool bAllowStreams); - - ~Parser(); - - // Считываем следующий объект из потока. - Object *GetObject(Object *pObject, unsigned char *sDecryptKey = NULL, CryptAlgorithm eEncryptAlgorithm = cryptRC4, int nKeyLength = 0, int nObjectNum = 0, int nObjectGen = 0); - - Stream *GetStream() - { - return m_pLexer->GetStream(); - } - - int GetPos() - { - return m_pLexer->GetPos(); - } - - private: - - Stream *CreateStream(Object *pDict, unsigned char *sDecryptKey, CryptAlgorithm eEncryptAlgorithm, int nKeyLength, int nObjectNum, int nObjectGen); - void Shift(); - - private: - - XRef *m_pXref; // Таблица Xref для даннthe xref table for this PDF file - Lexer *m_pLexer; // Входящий поток - bool m_bAllowStreams; // Будем ли парсить Stream Objects? - Object m_oBuffer1; // Два следующих объекта - Object m_oBuffer2; // - int m_nInlineImage; // Устанавливаем, когда сталкиваемся с Inline Image - }; -} - -#endif // _PDF_READER_PARSER_H - diff --git a/PdfReader/old/SecurityHandler.cpp b/PdfReader/old/SecurityHandler.cpp deleted file mode 100644 index 8842cb65d9..0000000000 --- a/PdfReader/old/SecurityHandler.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "StringExt.h" -#include "PDFDoc.h" -#include "Decrypt.h" -#include "GlobalParams.h" -#include "SecurityHandler.h" - -namespace PdfReader -{ - //------------------------------------------------------------------------------------------------------------------------------- - // SecurityHandler - //------------------------------------------------------------------------------------------------------------------------------- - - SecurityHandler *SecurityHandler::Make(PDFDoc *pDocument, Object *pEncryptDict) - { - SecurityHandler *pSecurityHandler = NULL; - Object oFilter; - pEncryptDict->DictLookup("Filter", &oFilter); - if (oFilter.IsName("Standard")) - { - pSecurityHandler = new StandardSecurityHandler(pDocument, pEncryptDict); - } - else if (oFilter.IsName()) - { - // TO DO: Error "Couldn't find the security handler" - pSecurityHandler = NULL; - } - else - { - // TO DO: Error "Missing or invalid 'Filter' entry in encryption dictionary" - pSecurityHandler = NULL; - } - oFilter.Free(); - return pSecurityHandler; - } - - SecurityHandler::SecurityHandler(PDFDoc *pDocument) - { - m_pDocument = pDocument; - } - - SecurityHandler::~SecurityHandler() - { - } - - bool SecurityHandler::CheckEncryption(const std::wstring &ownerPassword, const std::wstring &userPassword) - { - return Authorize(ownerPassword, userPassword); - } - - //------------------------------------------------------------------------------------------------------------------------------- - // StandardSecurityHandler - //------------------------------------------------------------------------------------------------------------------------------- - - StandardSecurityHandler::StandardSecurityHandler(PDFDoc *pDocument, Object *pEncryptDict) : - SecurityHandler(pDocument), m_seOwnerEncryptionKey(NULL), m_seUserEncryptionKey(NULL), m_sePermsValue(NULL), - m_seFileID(NULL), m_seOwnerKey(NULL), m_seUserKey(NULL) - { - m_bValid = false; - - Object oVersion, oRevision, oLength, oOwnerKey, oUserKey, oPermission, oPermsValue, oOwnerEncryptionKey, oUserEncryptionKey; - - pEncryptDict->DictLookup("V", &oVersion); - pEncryptDict->DictLookup("R", &oRevision); - pEncryptDict->DictLookup("Length", &oLength); - pEncryptDict->DictLookup("O", &oOwnerKey); - pEncryptDict->DictLookup("U", &oUserKey); - pEncryptDict->DictLookup("P", &oPermission); - - Object oFileID; - m_pDocument->GetXRef()->GetTrailerDict()->DictLookup("ID", &oFileID); - - if (oVersion.IsInt() && oRevision.IsInt() && oOwnerKey.IsString() && - oUserKey.IsString() && oPermission.IsInt()) - { - m_nEncryptVersion = oVersion.GetInt(); - m_nEncryptRevision = oRevision.GetInt(); - m_eCryptType = cryptRC4; - - // В случае Revision = 2, ключ должен быть 40-бит - некоторые PDF-генераторы неправильно пишут значение Length - if (m_nEncryptRevision == 2 || !oLength.IsInt()) - { - m_nFileKeyLength = 5; // 5 байт = 40-бит - } - else - { - m_nFileKeyLength = oLength.GetInt() / 8; - } - m_bEncryptMetadata = true; - - Object oCryptFilters, oStreamFilter, oStringFilter; - pEncryptDict->DictLookup("CF", &oCryptFilters); - pEncryptDict->DictLookup("StmF", &oStreamFilter); - pEncryptDict->DictLookup("StrF", &oStringFilter); - - if (oCryptFilters.IsDict() && oStreamFilter.IsName() && oStringFilter.IsName() && !strcmp(oStreamFilter.GetName(), oStringFilter.GetName())) - { - Object oCryptCurFilter; - if (oCryptFilters.DictLookup(oStreamFilter.GetName(), &oCryptCurFilter)->IsDict()) - { - Object oCFM; - oCryptCurFilter.DictLookup("CFM", &oCFM); - if (oCFM.IsName("V2")) - { - m_eCryptType = cryptRC4; - } - else if (oCFM.IsName("AESV2")) - { - m_eCryptType = cryptAES128; - } - else if (oCFM.IsName("AESV3")) - { - m_eCryptType = cryptAES256; - } - - oCFM.Free(); - } - oCryptCurFilter.Free(); - - Object oCFLength; - if (oCryptCurFilter.DictLookup("Length", &oCFLength)->IsInt()) - { - // Согласно спецификации, должно быть oCFLength / 8 - m_nFileKeyLength = oCFLength.GetInt(); - - // для AES256 приходят 32 и 256. Т.е. иногда нажо делить на 8, а иногда нет. - // мы все равно кинем exception, если длина не 32 - if (cryptAES256 == m_eCryptType) - m_nFileKeyLength = 32; - } - oCFLength.Free(); - - } - oStringFilter.Free(); - oStreamFilter.Free(); - oCryptFilters.Free(); - Object oEncryptMetadata; - if (pEncryptDict->DictLookup("EncryptMetadata", &oEncryptMetadata)->IsBool()) - { - m_bEncryptMetadata = oEncryptMetadata.GetBool(); - } - oEncryptMetadata.Free(); - - m_nPermissionFlags = oPermission.GetInt(); - m_seOwnerKey = oOwnerKey.GetString()->Copy(); - m_seUserKey = oUserKey.GetString()->Copy(); - - if (pEncryptDict->DictLookup("OE", &oOwnerEncryptionKey)) - { - if (oOwnerEncryptionKey.IsString()) - { - m_seOwnerEncryptionKey = oOwnerEncryptionKey.GetString()->Copy(); - } - } - if (pEncryptDict->DictLookup("UE", &oUserEncryptionKey)) - { - if (oUserEncryptionKey.IsString()) - { - m_seUserEncryptionKey = oUserEncryptionKey.GetString()->Copy(); - } - } - if (pEncryptDict->DictLookup("Perms", &oPermsValue)) - { - if (oPermsValue.IsString()) - { - m_sePermsValue = oPermsValue.GetString()->Copy(); - } - } - - if (oFileID.IsArray()) - { - Object oFileIDString; - if (oFileID.ArrayGet(0, &oFileIDString)->IsString()) - { - m_seFileID = oFileIDString.GetString()->Copy(); - } - else - { - m_seFileID = new StringExt(); - } - oFileIDString.Free(); - } - else - { - m_seFileID = new StringExt(); - } - m_bValid = true; - - } - else - { - } - - oFileID.Free(); - oPermission.Free(); - oUserKey.Free(); - oOwnerKey.Free(); - oLength.Free(); - oRevision.Free(); - oVersion.Free(); - } - - StandardSecurityHandler::~StandardSecurityHandler() - { - if (m_seFileID) - { - delete m_seFileID; - } - if (m_seOwnerKey) - { - delete m_seOwnerKey; - } - if (m_seUserKey) - { - delete m_seUserKey; - } - if (m_seOwnerEncryptionKey) - { - delete m_seOwnerEncryptionKey; - } - if (m_seUserEncryptionKey) - { - delete m_seUserEncryptionKey; - } - if (m_sePermsValue) - { - delete m_sePermsValue; - } - } - - bool StandardSecurityHandler::Authorize(const std::wstring &ownerPassword, const std::wstring &userPassword) - { - if (!m_bValid) - { - return false; - } - if (!Decrypt::MakeFileKey(this, ownerPassword, userPassword)) - { - return false; - } - return true; - } -} diff --git a/PdfReader/old/SecurityHandler.h b/PdfReader/old/SecurityHandler.h deleted file mode 100644 index 8aea21bfab..0000000000 --- a/PdfReader/old/SecurityHandler.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_SECURITY_HANDLER_H -#define _PDF_READER_SECURITY_HANDLER_H - -#include "Object.h" - -namespace PdfReader -{ - class StringExt; - class PDFDoc; - - //------------------------------------------------------------------------------------------------------------------------------- - // SecurityHandler - //------------------------------------------------------------------------------------------------------------------------------- - - class SecurityHandler - { - public: - - static SecurityHandler *Make(PDFDoc *pDocument, Object *pEncryptDict); - - SecurityHandler(PDFDoc *pDocument); - virtual ~SecurityHandler(); - - bool CheckEncryption(const std::wstring &ownerPassword, const std::wstring &userPassword); - - // Пытаемся авторизоваться. - virtual bool Authorize(const std::wstring &ownerPassword, const std::wstring &userPassword) = 0; - - // Считываем различные параметры. - virtual int GetPermissionFlags() = 0; - virtual bool GetOwnerPasswordValid()= 0; - virtual unsigned char *GetFileKey() = 0; - virtual int GetFileKeyLength() = 0; - virtual int GetEncodingVersion() = 0; - virtual CryptAlgorithm GetEncodingAlgorithm() = 0; - - protected: - - PDFDoc *m_pDocument; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // StandardSecurityHandler - //------------------------------------------------------------------------------------------------------------------------------- - - class StandardSecurityHandler : public SecurityHandler - { - public: - - friend class Decrypt; - - StandardSecurityHandler(PDFDoc *pDocument, Object *pEncryptDict); - virtual ~StandardSecurityHandler(); - - virtual bool Authorize(const std::wstring &ownerPassword, const std::wstring &userPassword); - virtual int GetPermissionFlags() - { - return m_nPermissionFlags; - } - virtual bool GetOwnerPasswordValid() - { - return m_bOwnerPasswordValid; - } - virtual unsigned char *GetFileKey() - { - return m_sFileKey; - } - virtual int GetFileKeyLength() - { - return m_nFileKeyLength; - } - virtual int GetEncodingVersion() - { - return m_nEncryptVersion; - } - virtual CryptAlgorithm GetEncodingAlgorithm() - { - return m_eCryptType; - } - - private: - bool m_bValid; - - int m_nPermissionFlags; - bool m_bOwnerPasswordValid; - unsigned char m_sFileKey[32]; - int m_nFileKeyLength; - int m_nEncryptVersion; - int m_nEncryptRevision; - CryptAlgorithm m_eCryptType; - bool m_bEncryptMetadata; - - StringExt *m_seOwnerKey; - StringExt *m_seUserKey; - StringExt *m_seFileID; - - StringExt *m_seOwnerEncryptionKey; - StringExt *m_seUserEncryptionKey; - StringExt *m_sePermsValue; - }; -} - -#endif // _PDF_READER_SECURITY_HANDLER_H diff --git a/PdfReader/old/Stream.cpp b/PdfReader/old/Stream.cpp deleted file mode 100644 index 9518879348..0000000000 --- a/PdfReader/old/Stream.cpp +++ /dev/null @@ -1,5519 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "File.h" -#include "Constants.h" -#include "Object.h" -#include "Lexer.h" -#include "GState.h" -#include "Stream.h" -#include "CCITT-Tables.h" -#include "JPXStream.h" -#include "JBIG2Stream.h" - -//#define USE_ZLIB // Для декодирования потоков в Flate используем Zlib или внутренний декодер - -namespace PdfReader -{ - //--------------------------------------------------------------------------------------------------------------- - // Stream (основной класс) - //--------------------------------------------------------------------------------------------------------------- - - Stream::Stream() - { - m_nRef = 1; - } - - Stream::~Stream() - { - } - - void Stream::Close() - { - } - - int Stream::GetRawChar() - { - // TO DO : Error "Internal: called GetRawChar() on non-predictor stream" - return EOF; - } - - char *Stream::GetLine(char *sBuffer, int nSize) - { - int nIndex; - - if (LookChar() == EOF) - return NULL; - for (nIndex = 0; nIndex < nSize - 1; ++nIndex) - { - int nChar = GetChar(); - if (nChar == EOF || nChar == '\n') - break; - if (nChar == '\r') - { - if ((nChar = LookChar()) == '\n') - GetChar(); - break; - } - sBuffer[nIndex] = nChar; - } - sBuffer[nIndex] = '\0'; - return sBuffer; - } - - StringExt *Stream::GetPSFilter(int nPSLevel, char *sIndent) - { - return new StringExt(); - } - - Stream *Stream::AddFilters(Object *pDict) - { - Object oTemp; - Object oParms, params2; - - Stream *pStream = this; - pDict->DictLookup("Filter", &oTemp); - if (oTemp.IsNull()) - { - oTemp.Free(); - pDict->DictLookup("F", &oTemp); - } - pDict->DictLookup("DecodeParms", &oParms); - if (oParms.IsNull()) - { - oParms.Free(); - pDict->DictLookup("DP", &oParms); - } - if (oTemp.IsName()) - { - pStream = ApplyFilter(oTemp.GetName(), pStream, &oParms); - } - else if (oTemp.IsArray()) - { - for (int nIndex = 0; nIndex < oTemp.ArrayGetLength(); ++nIndex) - { - Object oItem, oItemParams; - oTemp.ArrayGet(nIndex, &oItem); - if (oParms.IsArray()) - oParms.ArrayGet(nIndex, &oItemParams); - else - oItemParams.InitNull(); - if (oItem.IsName()) - { - pStream = ApplyFilter(oItem.GetName(), pStream, &oItemParams); - } - else - { - // TO DO: Error "Bad filter name" - pStream = new EOFStream(pStream); - } - oItem.Free(); - oItemParams.Free(); - } - } - else if (!oTemp.IsNull()) - { - // TO DO: Error "Bad 'Filter' attribute in stream" - } - oTemp.Free(); - oParms.Free(); - - return pStream; - } - - Stream *Stream::ApplyFilter(char *sName, Stream *pStream, Object *pParams) - { - if (!strcmp(sName, "ASCIIHexDecode") || !strcmp(sName, "AHx")) - { - pStream = new ASCIIHexStream(pStream); - } - else if (!strcmp(sName, "ASCII85Decode") || !strcmp(sName, "A85")) - { - pStream = new ASCII85Stream(pStream); - } - else if (!strcmp(sName, "LZWDecode") || !strcmp(sName, "LZW")) - { - int nPredictor = 1; - int nColumns = 1; - int nColors = 1; - int nBitsPerComponent = 8; - int nEarlyChange = 1; - - if (pParams->IsDict()) - { - Object oTemp; - - pParams->DictLookup("Predictor", &oTemp); - if (oTemp.IsInt()) - nPredictor = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("Columns", &oTemp); - if (oTemp.IsInt()) - nColumns = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("Colors", &oTemp); - if (oTemp.IsInt()) - nColors = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("BitsPerComponent", &oTemp); - if (oTemp.IsInt()) - nBitsPerComponent = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("EarlyChange", &oTemp); - if (oTemp.IsInt()) - nEarlyChange = oTemp.GetInt(); - oTemp.Free(); - } - pStream = new LZWStream(pStream, nPredictor, nColumns, nColors, nBitsPerComponent, nEarlyChange); - } - else if (!strcmp(sName, "RunLengthDecode") || !strcmp(sName, "RL")) - { - pStream = new RunLengthStream(pStream); - } - else if (!strcmp(sName, "CCITTFaxDecode") || !strcmp(sName, "CCF")) - { - int nK = 0; - - bool bEndOfLine = false; - bool bByteAlign = false; - int nColumns = 1728; - int nRows = 0; - bool bEndOfBlock = true; - bool bBlackIs1 = false; - - if (pParams->IsDict()) - { - Object oTemp; - - pParams->DictLookup("K", &oTemp); - if (oTemp.IsInt()) - nK = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("EndOfLine", &oTemp); - if (oTemp.IsBool()) - bEndOfLine = oTemp.GetBool(); - oTemp.Free(); - - pParams->DictLookup("EncodedByteAlign", &oTemp); - if (oTemp.IsBool()) - bByteAlign = oTemp.GetBool(); - oTemp.Free(); - - pParams->DictLookup("Columns", &oTemp); - if (oTemp.IsInt()) - nColumns = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("Rows", &oTemp); - if (oTemp.IsInt()) - nRows = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("EndOfBlock", &oTemp); - if (oTemp.IsBool()) - bEndOfBlock = oTemp.GetBool(); - oTemp.Free(); - - pParams->DictLookup("BlackIs1", &oTemp); - if (oTemp.IsBool()) - bBlackIs1 = oTemp.GetBool(); - oTemp.Free(); - - // TO DO: Добавить чтение поля "DamagedRowsBeforeError" - } - pStream = new CCITTFaxStream(pStream, nK, bEndOfLine, bByteAlign, nColumns, nRows, bEndOfBlock, bBlackIs1); - } - else if (!strcmp(sName, "DCTDecode") || !strcmp(sName, "DCT")) - { - int nColorTransform = -1; - - if (pParams->IsDict()) - { - Object oTemp; - if (pParams->DictLookup("ColorTransform", &oTemp)->IsInt()) - nColorTransform = oTemp.GetInt(); - oTemp.Free(); - } - pStream = new DCTStream(pStream, nColorTransform); - } - else if (!strcmp(sName, "FlateDecode") || !strcmp(sName, "Fl")) - { - int nPredictor = 1; - int nColors = 1; - int nBitsPerComponent = 8; - int nColumns = 1; - - if (pParams->IsDict()) - { - Object oTemp; - - pParams->DictLookup("Predictor", &oTemp); - if (oTemp.IsInt()) - nPredictor = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("Colors", &oTemp); - if (oTemp.IsInt()) - nColors = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("BitsPerComponent", &oTemp); - if (oTemp.IsInt()) - nBitsPerComponent = oTemp.GetInt(); - oTemp.Free(); - - pParams->DictLookup("Columns", &oTemp); - if (oTemp.IsInt()) - nColumns = oTemp.GetInt(); - oTemp.Free(); - } -#ifdef USE_ZLIB - pStream = new FlateZlibStream( pStream, nPredictor, nColumns, nColors, nBitsPerComponent ); -#else - pStream = new FlateStream(pStream, nPredictor, nColumns, nColors, nBitsPerComponent); -#endif - } - else if (!strcmp(sName, "JBIG2Decode")) - { - Object oJBIG2Globals; - if (pParams->IsDict()) - { - pParams->DictLookup("JBIG2Globals", &oJBIG2Globals); - } - // TO DO: Сделать данный фильтр - pStream = new JBIG2Stream(pStream, &oJBIG2Globals); - oJBIG2Globals.Free(); - } - else if (!strcmp(sName, "JPXDecode")) - { - pStream = new JPXStream(pStream); - } - else - { - // TO DO: Error "Unknown filter" - pStream = new EOFStream(pStream); - } - return pStream; - } - - //--------------------------------------------------------------------------------------------------------------- - // BaseStream - //--------------------------------------------------------------------------------------------------------------- - - BaseStream::BaseStream(Object *pDict) - { - m_pDict = *pDict; - } - - BaseStream::~BaseStream() - { - m_pDict.Free(); - } - - //--------------------------------------------------------------------------------------------------------------- - // FilterStream - //--------------------------------------------------------------------------------------------------------------- - - FilterStream::FilterStream(Stream *pStream) - { - m_pStream = pStream; - } - - FilterStream::~FilterStream() - { - } - - void FilterStream::Close() - { - m_pStream->Close(); - } - - void FilterStream::SetPos(unsigned int unPos, int nDirection) - { - // TO DO: Error "Internal: called SetPos() on FilterStream" - } - - //--------------------------------------------------------------------------------------------------------------- - // ImageStream - //--------------------------------------------------------------------------------------------------------------- - - ImageStream::ImageStream(Stream *pStream, int nWidth, int nComponents, int nBitsPerComponent) - { - int nLineSize = 0; - - m_pStream = pStream; - m_nWidth = nWidth; - m_nComponentsPerPixel = nComponents; - m_nBitsPerComponent = nBitsPerComponent; - - m_nComponentsPerLine = m_nWidth * m_nComponentsPerPixel; - - if (1 == m_nBitsPerComponent) - { - nLineSize = (m_nComponentsPerLine + 7) & ~7; - } - else - { - nLineSize = m_nComponentsPerLine; - } - m_pLineBuffer = (unsigned char *)MemUtilsMallocArray(nLineSize, sizeof(unsigned char)); - m_nLinePos = m_nComponentsPerLine; - } - - ImageStream::~ImageStream() - { - MemUtilsFree(m_pLineBuffer); - } - - void ImageStream::Reset() - { - m_pStream->Reset(); - } - - bool ImageStream::GetPixel(unsigned char *pPixel) - { - if (m_nLinePos >= m_nComponentsPerLine) - { - GetNextLine(); - m_nLinePos = 0; - } - for (int nIndex = 0; nIndex < m_nComponentsPerPixel; ++nIndex) - { - pPixel[nIndex] = m_pLineBuffer[m_nLinePos++]; - } - return true; - } - - unsigned char *ImageStream::GetNextLine() - { - if (m_nBitsPerComponent == 1) - { - for (int nIndex = 0; nIndex < m_nComponentsPerLine; nIndex += 8) - { - int nChar = m_pStream->GetChar(); - m_pLineBuffer[nIndex + 0] = (unsigned char)((nChar >> 7) & 1); - m_pLineBuffer[nIndex + 1] = (unsigned char)((nChar >> 6) & 1); - m_pLineBuffer[nIndex + 2] = (unsigned char)((nChar >> 5) & 1); - m_pLineBuffer[nIndex + 3] = (unsigned char)((nChar >> 4) & 1); - m_pLineBuffer[nIndex + 4] = (unsigned char)((nChar >> 3) & 1); - m_pLineBuffer[nIndex + 5] = (unsigned char)((nChar >> 2) & 1); - m_pLineBuffer[nIndex + 6] = (unsigned char)((nChar >> 1) & 1); - m_pLineBuffer[nIndex + 7] = (unsigned char)(nChar & 1); - } - } - else if (m_nBitsPerComponent == 8) - { - for (int nIndex = 0; nIndex < m_nComponentsPerLine; ++nIndex) - { - m_pLineBuffer[nIndex] = m_pStream->GetChar(); - } - } - else - { - unsigned long nBitMask = (1 << m_nBitsPerComponent) - 1; - unsigned long nTemp = 0; - int nBits = 0; - for (int nIndex = 0; nIndex < m_nComponentsPerLine; ++nIndex) - { - if (nBits < m_nBitsPerComponent) - { - nTemp = (nTemp << 8) | (m_pStream->GetChar() & 0xff); - nBits += 8; - } - m_pLineBuffer[nIndex] = (unsigned char)((nTemp >> (nBits - m_nBitsPerComponent)) & nBitMask); - nBits -= m_nBitsPerComponent; - } - } - return m_pLineBuffer; - } - - void ImageStream::SkipLine() - { - int nCount = (m_nComponentsPerLine * m_nBitsPerComponent + 7) >> 3; - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - m_pStream->GetChar(); - } - } - - //--------------------------------------------------------------------------------------------------------------- - // StreamPredictor - //--------------------------------------------------------------------------------------------------------------- - - StreamPredictor::StreamPredictor(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent) - { - m_pStream = pStream; - m_nPredictor = nPredictor; - m_nWidth = nWidth; - m_nComponentsPerPixel = nComponents; - m_nBitsPerComponent = nBitsPerComponent; - m_pLineBuffer = NULL; - m_bSuccess = false; - - m_nComponentsPerLine = m_nWidth * m_nComponentsPerPixel; - - // Patch1 - m_nBytesPerPixel = (m_nComponentsPerPixel * m_nBitsPerComponent + 7) >> 3; - m_nBytesPerLine = ((m_nComponentsPerLine * m_nBitsPerComponent + 7) >> 3) + m_nBytesPerPixel; - - if (m_nWidth <= 0 || m_nComponentsPerPixel <= 0 || m_nBitsPerComponent <= 0 || m_nComponentsPerPixel >= GrColorMaxComps || m_nBitsPerComponent > 16 || m_nWidth >= INT_MAX / m_nComponentsPerPixel || m_nComponentsPerLine >= (INT_MAX - 7) / m_nBitsPerComponent) - return; // m_bSuccess = false; - - // End Patch1 - - if (m_nBytesPerLine <= 0) - return; // m_bSuccess = false; - - m_pLineBuffer = (unsigned char *)MemUtilsMalloc(m_nBytesPerLine); - - memset(m_pLineBuffer, 0, m_nBytesPerLine); - m_nLinePos = m_nBytesPerLine; - - m_bSuccess = true; - } - - StreamPredictor::~StreamPredictor() - { - MemUtilsFree(m_pLineBuffer); - } - - int StreamPredictor::LookChar() - { - if (m_nLinePos >= m_nBytesPerLine) - { - if (!GetNextLine()) - { - return EOF; - } - } - return m_pLineBuffer[m_nLinePos]; - } - - int StreamPredictor::GetChar() - { - if (m_nLinePos >= m_nBytesPerLine) - { - if (!GetNextLine()) - { - return EOF; - } - } - return m_pLineBuffer[m_nLinePos++]; - } - - bool StreamPredictor::GetNextLine() - { - int nCurPredictor = 1; - int nLeft, nTop, nTopLeft, nCur, nLeftDiff, nTopDiff, nTopLeftDiff; - int nChar; - - // PNG prediction - if (m_nPredictor >= 10) - { - if ((nCurPredictor = m_pStream->GetRawChar()) == EOF) - { - return false; - } - nCurPredictor += 10; - } - else - { - nCurPredictor = m_nPredictor; - } - - // Читаем по строке, применяя PNG (byte) фильтрацию(prediction) - unsigned char arrTopLeftBuf[GrColorMaxComps * 2 + 1]; - memset(arrTopLeftBuf, 0, m_nBytesPerPixel + 1); - - for (int nIndex = m_nBytesPerPixel; nIndex < m_nBytesPerLine; ++nIndex) - { - for (int nJ = m_nBytesPerPixel; nJ > 0; --nJ) - { - arrTopLeftBuf[nJ] = arrTopLeftBuf[nJ - 1]; - } - arrTopLeftBuf[0] = m_pLineBuffer[nIndex]; - if ((nChar = m_pStream->GetRawChar()) == EOF) - { - if (nIndex > m_nBytesPerPixel) - { - // this ought to return false, but some (broken) PDF files - // contain truncated image data, and Adobe apparently reads the - // last partial line - break; - } - return false; - } - switch (nCurPredictor) - { - case 11: // PNG Sub - m_pLineBuffer[nIndex] = m_pLineBuffer[nIndex - m_nBytesPerPixel] + (unsigned char)nChar; - break; - case 12: // PNG Up - m_pLineBuffer[nIndex] = m_pLineBuffer[nIndex] + (unsigned char)nChar; - break; - case 13: // PNG Average - m_pLineBuffer[nIndex] = ((m_pLineBuffer[nIndex - m_nBytesPerPixel] + m_pLineBuffer[nIndex]) >> 1) + (unsigned char)nChar; - break; - case 14: // PNG Paeth - nLeft = m_pLineBuffer[nIndex - m_nBytesPerPixel]; - nTop = m_pLineBuffer[nIndex]; - nTopLeft = arrTopLeftBuf[m_nBytesPerPixel]; - nCur = nLeft + nTop - nTopLeft; - if ((nLeftDiff = nCur - nLeft) < 0) - nLeftDiff = -nLeftDiff; - if ((nTopDiff = nCur - nTop) < 0) - nTopDiff = -nTopDiff; - if ((nTopLeftDiff = nCur - nTopLeft) < 0) - nTopLeftDiff = -nTopLeftDiff; - if (nLeftDiff <= nTopDiff && nLeftDiff <= nTopLeftDiff) - m_pLineBuffer[nIndex] = nLeft + (unsigned char)nChar; - else if (nTopDiff <= nTopLeftDiff) - m_pLineBuffer[nIndex] = nTop + (unsigned char)nChar; - else - m_pLineBuffer[nIndex] = nTopLeft + (unsigned char)nChar; - break; - case 10: // PNG none - default: // No predictor или TIFF predictor - m_pLineBuffer[nIndex] = (unsigned char)nChar; - break; - } - } - - // Применяем TIFF фильтрацию (predictor) - unsigned long nInTemp, nOutTemp; - if (m_nPredictor == 2) - { - if (m_nBitsPerComponent == 1) - { - nInTemp = m_pLineBuffer[m_nBytesPerPixel - 1]; - for (int nIndex = m_nBytesPerPixel; nIndex < m_nBytesPerLine; nIndex += 8) - { - // 1-bit add is just xor - nInTemp = (nInTemp << 8) | m_pLineBuffer[nIndex]; - m_pLineBuffer[nIndex] ^= nInTemp >> m_nComponentsPerPixel; - } - } - else if (m_nBitsPerComponent == 8) - { - for (int nIndex = m_nBytesPerPixel; nIndex < m_nBytesPerLine; ++nIndex) - { - m_pLineBuffer[nIndex] += m_pLineBuffer[nIndex - m_nComponentsPerPixel]; - } - } - else - { - memset(arrTopLeftBuf, 0, m_nComponentsPerPixel + 1); - int nBitMask = (1 << m_nBitsPerComponent) - 1; - nInTemp = 0, nOutTemp = 0; - int nInBits = 0, nOutBits = 0; - int nJ = m_nBytesPerPixel, nK = m_nBytesPerPixel; - for (int nIndex = 0; nIndex < m_nWidth; ++nIndex) - { - for (int nKK = 0; nKK < m_nComponentsPerPixel; ++nKK) - { - if (nInBits < m_nBitsPerComponent) - { - nInTemp = (nInTemp << 8) | (m_pLineBuffer[nJ++] & 0xff); - nInBits += 8; - } - arrTopLeftBuf[nKK] = (unsigned char)((arrTopLeftBuf[nKK] + (nInTemp >> (nInBits - m_nBitsPerComponent))) & nBitMask); - nInBits -= m_nBitsPerComponent; - nOutTemp = (nOutTemp << m_nBitsPerComponent) | arrTopLeftBuf[nKK]; - nOutBits += m_nBitsPerComponent; - if (nOutBits >= 8) - { - m_pLineBuffer[nK++] = (unsigned char)(nOutTemp >> (nOutBits - 8)); - nOutBits -= 8; - } - } - } - if (nOutBits > 0) - { - m_pLineBuffer[nK++] = (unsigned char)((nOutTemp << (8 - nOutBits)) + (nInTemp & ((1 << (8 - nOutBits)) - 1))); - } - } - } - - m_nLinePos = m_nBytesPerPixel; - - return true; - } - - //--------------------------------------------------------------------------------------------------------------- - // FileStream - //--------------------------------------------------------------------------------------------------------------- - - FileStream::FileStream(FILE *pFile, unsigned int unStart, bool bLimited, unsigned int nLength, Object *pDict) : - BaseStream(pDict) - { - m_pFile = pFile; - - m_unStart = unStart; - m_bLimited = bLimited; - m_unLength = nLength; - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_unBufferPos = m_unStart; - m_nSavePos = 0; - m_bSaved = false; - } - - FileStream::~FileStream() - { - Close(); - } - - Stream *FileStream::MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict) - { - return new FileStream(m_pFile, unStart, bLimited, unLength, pDict); - } - - void FileStream::Reset() - { - m_nSavePos = (unsigned int)ftell(m_pFile); - fseek(m_pFile, m_unStart, SEEK_SET); - - m_bSaved = true; - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_unBufferPos = m_unStart; - } - - void FileStream::Close() - { - if (m_bSaved) - { - fseek(m_pFile, m_nSavePos, SEEK_SET); - m_bSaved = false; - } - } - - bool FileStream::FillBuffer() - { - int nCurBufLen = 0; - - m_unBufferPos += m_pBufferEnd - m_sBuffer; - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - if (m_bLimited && m_unBufferPos >= m_unStart + m_unLength) - return false; - - if (m_bLimited && m_unBufferPos + FileStreamBufferSize > m_unStart + m_unLength) - nCurBufLen = m_unStart + m_unLength - m_unBufferPos; - else - nCurBufLen = FileStreamBufferSize; - - nCurBufLen = fread(m_sBuffer, 1, nCurBufLen, m_pFile); - m_pBufferEnd = m_sBuffer + nCurBufLen; - - if (m_pBufferPointer >= m_pBufferEnd) - return false; - - return true; - } - - void FileStream::SetPos(unsigned int unPos, int nDirection) - { - if (nDirection >= 0) - { - fseek(m_pFile, unPos, SEEK_SET); - m_unBufferPos = unPos; - } - else - { - fseek(m_pFile, 0, SEEK_END); - unsigned int unSize = (unsigned int)ftell(m_pFile); - if (unPos > unSize) - unPos = (unsigned int)unSize; - fseek(m_pFile, -(int)unPos, SEEK_END); - m_unBufferPos = (unsigned int)ftell(m_pFile); - } - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - } - - void FileStream::SetStartPos(int nDelta) - { - m_unStart += nDelta; - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_unBufferPos = m_unStart; - } - - //--------------------------------------------------------------------------------------------------------------- - // MemoryStream - //--------------------------------------------------------------------------------------------------------------- - - MemoryStream::MemoryStream(char *sBuffer, unsigned int unStart, unsigned int unLength, Object *pDict) : - BaseStream(pDict) - { - m_sBuffer = sBuffer; - m_unStart = unStart; - m_unLength = unLength; - m_pBufferEnd = m_sBuffer + m_unStart + m_unLength; - m_pBufferPointer = m_sBuffer + m_unStart; - m_bNeedFree = false; - } - - MemoryStream::~MemoryStream() - { - if (m_bNeedFree) - MemUtilsFree(m_sBuffer); - } - char* MemoryStream::getCurrent() - { - return m_pBufferPointer; - } - unsigned int MemoryStream::getCurrentLength() - { - return (m_pBufferEnd - m_pBufferPointer); - } - - Stream *MemoryStream::MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict) - { - unsigned int unNewLength = 0; - - if (!bLimited || unStart + unLength > m_unStart + m_unLength) - { - unNewLength = m_unStart + m_unLength - unStart; - if (unStart >= m_unStart + m_unLength) - unNewLength = 0; - } - else - { - unNewLength = unLength; - } - MemoryStream *pSubStream = new MemoryStream(m_sBuffer, unStart, unNewLength, pDict); - return pSubStream; - } - - void MemoryStream::Reset() - { - m_pBufferPointer = m_sBuffer + m_unStart; - } - - void MemoryStream::Close() - { - } - - void MemoryStream::SetPos(unsigned int unPos, int nDirection) - { - unsigned int unCurPos = 0; - - if (nDirection >= 0) - { - unCurPos = unPos; - } - else - { - unCurPos = m_unStart + m_unLength - unPos; - } - - if (unCurPos < m_unStart) - { - unCurPos = m_unStart; - } - else if (unCurPos > m_unStart + m_unLength) - { - unCurPos = m_unStart + m_unLength; - } - m_pBufferPointer = m_sBuffer + unCurPos; - } - - void MemoryStream::SetStartPos(int nDelta) - { - m_unStart += nDelta; - m_unLength -= nDelta; - m_pBufferPointer = m_sBuffer + m_unStart; - } - - //--------------------------------------------------------------------------------------------------------------- - // EmbedStream - //--------------------------------------------------------------------------------------------------------------- - - EmbedStream::EmbedStream(Stream *pStream, Object *pDict, bool bLimited, unsigned int unLength) : - BaseStream(pDict) - { - m_pStream = pStream; - m_bLimited = bLimited; - m_unLength = unLength; - } - - EmbedStream::~EmbedStream() - { - } - - Stream *EmbedStream::MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict) - { - // TO DO: Error "Internal: called MakeSubStream() on EmbedStream" - return NULL; - } - - int EmbedStream::GetChar() - { - if (m_bLimited && !m_unLength) - { - return EOF; - } - --m_unLength; - return m_pStream->GetChar(); - } - - int EmbedStream::LookChar() - { - if (m_bLimited && !m_unLength) - { - return EOF; - } - return m_pStream->LookChar(); - } - - void EmbedStream::SetPos(unsigned int unPos, int nDirection) - { - // TO DO: Error "Internal: called SetPos() on EmbedStream" - } - - unsigned int EmbedStream::GetStartPos() - { - // TO DO: Error "Internal: called GetStartPos() on EmbedStream" - return 0; - } - - void EmbedStream::SetStartPos(int nDelta) - { - // TO DO: Error "Internal: called SetStartPos() on EmbedStream" - } - - //--------------------------------------------------------------------------------------------------------------- - // ASCIIHexStream - //--------------------------------------------------------------------------------------------------------------- - - ASCIIHexStream::ASCIIHexStream(Stream *pStream) : - FilterStream(pStream) - { - m_nBuffer = EOF; - m_bEOF = false; - } - - ASCIIHexStream::~ASCIIHexStream() - { - delete m_pStream; - } - - void ASCIIHexStream::Reset() - { - m_pStream->Reset(); - m_nBuffer = EOF; - m_bEOF = false; - } - - int ASCIIHexStream::LookChar() - { - int nFirstChar = 0, nSecondChar = 0, nHexValue = 0; - - if (m_nBuffer != EOF) - return m_nBuffer; - if (m_bEOF) - { - m_nBuffer = EOF; - return EOF; - } - do { - nFirstChar = m_pStream->GetChar(); - } while (isspace(nFirstChar)); - - if (nFirstChar == '>') - { - m_bEOF = true; - m_nBuffer = EOF; - return m_nBuffer; - } - do { - nSecondChar = m_pStream->GetChar(); - } while (isspace(nSecondChar)); - - if (nSecondChar == '>') - { - m_bEOF = true; - nSecondChar = '0'; - } - - if (nFirstChar >= '0' && nFirstChar <= '9') - { - nHexValue = (nFirstChar - '0') << 4; - } - else if (nFirstChar >= 'A' && nFirstChar <= 'F') - { - nHexValue = (nFirstChar - 'A' + 10) << 4; - } - else if (nFirstChar >= 'a' && nFirstChar <= 'f') - { - nHexValue = (nFirstChar - 'a' + 10) << 4; - } - else if (nFirstChar == EOF) - { - m_bEOF = true; - nHexValue = 0; - } - else - { - // TO DO: Error "Illegal character in ASCIIHex stream" - nHexValue = 0; - } - - if (nSecondChar >= '0' && nSecondChar <= '9') - { - nHexValue += nSecondChar - '0'; - } - else if (nSecondChar >= 'A' && nSecondChar <= 'F') - { - nHexValue += nSecondChar - 'A' + 10; - } - else if (nSecondChar >= 'a' && nSecondChar <= 'f') - { - nHexValue += nSecondChar - 'a' + 10; - } - else if (nSecondChar == EOF) - { - m_bEOF = true; - nHexValue = 0; - } - else - { - // TO DO: Error "Illegal character in ASCIIHex stream" - } - m_nBuffer = nHexValue & 0xff; - return m_nBuffer; - } - - StringExt *ASCIIHexStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 2) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("/ASCIIHexDecode filter\n"); - return seResult; - } - - bool ASCIIHexStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(false); - } - - //--------------------------------------------------------------------------------------------------------------- - // ASCII85Stream - //--------------------------------------------------------------------------------------------------------------- - - ASCII85Stream::ASCII85Stream(Stream *pStream) : - FilterStream(pStream) - { - m_nIndex = m_nCount = 0; - m_bEOF = false; - } - - ASCII85Stream::~ASCII85Stream() - { - delete m_pStream; - } - - void ASCII85Stream::Reset() - { - m_pStream->Reset(); - m_nIndex = m_nCount = 0; - m_bEOF = false; - } - - int ASCII85Stream::LookChar() - { - int nK = 0; - - if (m_nIndex >= m_nCount) - { - if (m_bEOF) - return EOF; - m_nIndex = 0; - do { - m_arrC[0] = m_pStream->GetChar(); - } while (Lexer::IsSpace(m_arrC[0])); - - if (m_arrC[0] == '~' || m_arrC[0] == EOF) - { - m_bEOF = true; - m_nCount = 0; - return EOF; - } - else if (m_arrC[0] == 'z') - { - m_arrB[0] = m_arrB[1] = m_arrB[2] = m_arrB[3] = 0; - m_nCount = 4; - } - else - { - for (nK = 1; nK < 5; ++nK) - { - do { - m_arrC[nK] = m_pStream->GetChar(); - } while (Lexer::IsSpace(m_arrC[nK])); - - if (m_arrC[nK] == '~' || m_arrC[nK] == EOF) - break; - } - m_nCount = nK - 1; - if (nK < 5 && (m_arrC[nK] == '~' || m_arrC[nK] == EOF)) - { - for (++nK; nK < 5; ++nK) - m_arrC[nK] = 0x21 + 84; - m_bEOF = true; - } - unsigned long unT = 0; - for (nK = 0; nK < 5; ++nK) - unT = unT * 85 + (m_arrC[nK] - 0x21); - for (nK = 3; nK >= 0; --nK) - { - m_arrB[nK] = (int)(unT & 0xff); - unT >>= 8; - } - } - } - return m_arrB[m_nIndex]; - } - - StringExt *ASCII85Stream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 2) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("/ASCII85Decode filter\n"); - return seResult; - } - - bool ASCII85Stream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(false); - } - - //--------------------------------------------------------------------------------------------------------------- - // LZWStream - //--------------------------------------------------------------------------------------------------------------- - - LZWStream::LZWStream(Stream *pStream, int nPredictor, int nColumns, int nColors, int nBitsPerPixel, int nEarlyChange) : - FilterStream(pStream) - { - if (1 != nPredictor) - { - m_pPredictor = new StreamPredictor(this, nPredictor, nColumns, nColors, nBitsPerPixel); - if (!m_pPredictor->CheckValidate()) - { - delete m_pPredictor; - m_pPredictor = NULL; - } - } - else - { - m_pPredictor = NULL; - } - - m_nEarlyChange = nEarlyChange; - m_bEOF = false; - m_nInputBits = 0; - ClearTable(); - } - - LZWStream::~LZWStream() - { - if (m_pPredictor) - { - delete m_pPredictor; - } - delete m_pStream; - } - - int LZWStream::GetChar() - { - if (m_pPredictor) - { - return m_pPredictor->GetChar(); - } - if (m_bEOF) - { - return EOF; - } - if (m_nCurPos >= m_nCurLength) - { - if (!ProcessNextCode()) - { - return EOF; - } - } - return m_arrCurBuffer[m_nCurPos++]; - } - - int LZWStream::LookChar() - { - if (m_pPredictor) - { - return m_pPredictor->LookChar(); - } - if (m_bEOF) - { - return EOF; - } - if (m_nCurPos >= m_nCurLength) - { - if (!ProcessNextCode()) - { - return EOF; - } - } - return m_arrCurBuffer[m_nCurPos]; - } - - int LZWStream::GetRawChar() - { - // Отличие от GetChar в том, что тут мы неиспользуем фильтр, указанный в m_pPredictor - if (m_bEOF) - { - return EOF; - } - if (m_nCurPos >= m_nCurLength) - { - if (!ProcessNextCode()) - { - return EOF; - } - } - return m_arrCurBuffer[m_nCurPos++]; - } - - void LZWStream::Reset() - { - m_pStream->Reset(); - m_bEOF = false; - m_nInputBits = 0; - ClearTable(); - } - - bool LZWStream::ProcessNextCode() - { - if (m_bEOF) - { - return false; - } - - // Проверяем конец кода(eod) и очищаем таблицу кодов - start: - int nCode = GetCode(); - - if (nCode == EOF || nCode == 257) - { - m_bEOF = true; - return false; - } - if (nCode == 256) - { - ClearTable(); - goto start; - } - if (m_nNextCode >= 4097) - { - // TO DO: Error "Bad LZW stream - expected clear-table code" - ClearTable(); - } - - // Process the next code - - int nNextLength = m_nCurLength + 1; - if (nCode < 256) - { - m_arrCurBuffer[0] = nCode; - m_nCurLength = 1; - } - else if (nCode < m_nNextCode) - { - m_nCurLength = m_pTable[nCode].nLength; - int nI = 0, nJ = 0; - for (nI = m_nCurLength - 1, nJ = nCode; nI > 0; --nI) - { - m_arrCurBuffer[nI] = m_pTable[nJ].unTail; - nJ = m_pTable[nJ].nHead; - } - m_arrCurBuffer[0] = nJ; - } - else if (nCode == m_nNextCode) - { - m_arrCurBuffer[m_nCurLength] = m_nNewChar; - ++m_nCurLength; - } - else - { - // TO DO : Error "Bad LZW stream - unexpected code" - m_bEOF = true; - return false; - } - - m_nNewChar = m_arrCurBuffer[0]; - if (m_bFirst) - { - m_bFirst = false; - } - else - { - m_pTable[m_nNextCode].nLength = nNextLength; - m_pTable[m_nNextCode].nHead = m_nPrevCode; - m_pTable[m_nNextCode].unTail = m_nNewChar; - ++m_nNextCode; - if (m_nNextCode + m_nEarlyChange == 512) - m_nNextBits = 10; - else if (m_nNextCode + m_nEarlyChange == 1024) - m_nNextBits = 11; - else if (m_nNextCode + m_nEarlyChange == 2048) - m_nNextBits = 12; - } - m_nPrevCode = nCode; - - m_nCurPos = 0; - - return true; - } - - void LZWStream::ClearTable() - { - m_nNextCode = 258; - m_nNextBits = 9; - m_nCurPos = m_nCurLength = 0; - m_bFirst = true; - } - - int LZWStream::GetCode() - { - int nChar = 0; - - while (m_nInputBits < m_nNextBits) - { - if ((nChar = m_pStream->GetChar()) == EOF) - return EOF; - m_nInputBuffer = (m_nInputBuffer << 8) | (nChar & 0xff); - m_nInputBits += 8; - } - int nCode = (m_nInputBuffer >> (m_nInputBits - m_nNextBits)) & ((1 << m_nNextBits) - 1); - m_nInputBits -= m_nNextBits; - return nCode; - } - - StringExt *LZWStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 2 || m_pPredictor) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("<< "); - if (!m_nEarlyChange) - { - seResult->Append("/EarlyChange 0 "); - } - seResult->Append(">> /LZWDecode filter\n"); - return seResult; - } - - bool LZWStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - //--------------------------------------------------------------------------------------------------------------- - // RunLengthStream - //--------------------------------------------------------------------------------------------------------------- - - RunLengthStream::RunLengthStream(Stream *pStream) : - FilterStream(pStream) - { - m_pBufferPointer = m_pEndOfBuffer = m_sBuffer; - m_bEOF = false; - } - - RunLengthStream::~RunLengthStream() - { - delete m_pStream; - } - - void RunLengthStream::Reset() - { - m_pStream->Reset(); - m_pBufferPointer = m_pEndOfBuffer = m_sBuffer; - m_bEOF = false; - } - - StringExt *RunLengthStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 2) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("/RunLengthDecode filter\n"); - return seResult; - } - - bool RunLengthStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - bool RunLengthStream::FillBuffer() - { - int nLen = 0; - - if (m_bEOF) - return false; - - int nChar = m_pStream->GetChar(); - if (nChar == 0x80 || nChar == EOF) - { - m_bEOF = true; - return false; - } - if (nChar < 0x80) - { - nLen = nChar + 1; - for (int nIndex = 0; nIndex < nLen; ++nIndex) - m_sBuffer[nIndex] = (char)m_pStream->GetChar(); - } - else - { - nLen = 0x101 - nChar; - nChar = m_pStream->GetChar(); - for (int nIndex = 0; nIndex < nLen; ++nIndex) - m_sBuffer[nIndex] = (char)nChar; - } - m_pBufferPointer = m_sBuffer; - m_pEndOfBuffer = m_sBuffer + nLen; - return true; - } - - //--------------------------------------------------------------------------------------------------------------- - // CCITTFaxStream - //--------------------------------------------------------------------------------------------------------------- - - CCITTFaxStream::CCITTFaxStream(Stream *pStream, int nK, bool bEndOfLine, bool bByteAlign, int nColumns, int nRows, bool bEndOfBlock, bool bBlackIs1) : - FilterStream(pStream) - { - m_nK = nK; - m_bEndOfLine = bEndOfLine; - m_bByteAlign = bByteAlign; - - m_nColumns = nColumns; - if (m_nColumns < 1) - m_nColumns = 1; - if (m_nColumns + 4 <= 0) - m_nColumns = INT_MAX - 4; - - m_nRows = nRows; - m_bEndOfBlock = bEndOfBlock; - m_bBlackIs1 = bBlackIs1; - - m_pRefLine = (short *)MemUtilsMallocArray(m_nColumns + 3, sizeof(short)); - m_pCodingLine = (short *)MemUtilsMallocArray(m_nColumns + 2, sizeof(short)); - - m_bEOF = false; - m_mCurRow = 0; - m_bNextLine2D = (m_nK < 0); - m_nInputBits = 0; - m_pCodingLine[0] = 0; - m_pCodingLine[1] = m_pRefLine[2] = m_nColumns; - m_nCurPosCL = 1; - - m_nCharBuffer = EOF; - } - - CCITTFaxStream::~CCITTFaxStream() - { - delete m_pStream; - MemUtilsFree(m_pRefLine); - MemUtilsFree(m_pCodingLine); - } - - void CCITTFaxStream::Reset() - { - short nCode1; - - m_pStream->Reset(); - m_bEOF = false; - m_mCurRow = 0; - m_bNextLine2D = (m_nK < 0); - m_nInputBits = 0; - m_pCodingLine[0] = 0; - m_pCodingLine[1] = m_nColumns; - m_nCurPosCL = 1; - m_nCharBuffer = EOF; - - // Пропускам начальные нулевые биты и символы окончания строки, и считываем тэг 2D кодировки - while ((nCode1 = LookBits(12)) == 0) - { - SkipBits(1); - } - if (nCode1 == 0x001) - { - SkipBits(12); - } - if (m_nK > 0) - { - m_bNextLine2D = !LookBits(1); - SkipBits(1); - } - } - - int CCITTFaxStream::LookChar() - { - short nCode1, nCode2, nCode3; - int nIndex = 0; - - if (m_bEOF && m_pCodingLine[m_nCurPosCL] >= m_nColumns) - { - return EOF; - } - - // Считываем строку - bool bError = false; - if (m_pCodingLine[m_nCurPosCL] >= m_nColumns) - { - - // 2D кодировка - if (m_bNextLine2D) - { - // Начальное состояние: - // nNewCLPos = Текущая позиция в кодированной строке (0 <= nNewCLPos <= m_nColumns) - // m_pCodingLine[m_nCurPosCL] = Последнее изменение в кодированной строке - // (black-to-white, если m_nCurPosCL четно, - // white-to-black, если m_nCurPosCL нечетно) - // m_pRefLine[m_nCurPosRL] = Следующее изменение в ссылочной строке, противоположного - // цвета, цвету m_nCurPosCL - // В любой момент должно быть верно: - // 0 <= m_pCodingLine[m_nCurPosCL] <= nNewCLPos <= m_pRefLine[m_nCurPosRL] <= m_pRefLine[m_nCurPosRL + 1] <= m_nColumns - // 0 <= m_nCurPosCL <= m_nColumns + 1 - // m_pRefLine[0] = 0 - // m_pRefLine[n] = m_pRefLine[n + 1] = columns -- для некоторого 1 <= n <= m_nColumns + 1 - // Условие окончания алгоритма: - // 0 = m_pCodingLine[0] <= m_pCodingLine[1] < m_pCodingLine[2] < ... < m_pCodingLine[n-1] < m_pCodingLine[n] = m_nColumns, - // где <= n <= m_nColumns + 1 - - int nNewCLPos = 0; - for (nIndex = 0; m_pCodingLine[nIndex] < m_nColumns; ++nIndex) - { - m_pRefLine[nIndex] = m_pCodingLine[nIndex]; - } - m_pRefLine[nIndex] = m_pRefLine[nIndex + 1] = m_nColumns; - m_nCurPosRL = 1; - nNewCLPos = m_pCodingLine[m_nCurPosCL = 0] = 0; - do { - nCode1 = Get2DCode(); - switch (nCode1) - { - case Pass_2D: - if (m_pRefLine[m_nCurPosRL] < m_nColumns) - { - nNewCLPos = m_pRefLine[m_nCurPosRL + 1]; - m_nCurPosRL += 2; - } - break; - case Horiz_2D: - if ((m_nCurPosCL & 1) == 0) - { - nCode1 = nCode2 = 0; - do { - nCode1 += nCode3 = GetWhiteCode(); - } while (nCode3 >= 64); - do { - nCode2 += nCode3 = GetBlackCode(); - } while (nCode3 >= 64); - } - else - { - nCode1 = nCode2 = 0; - do { - nCode1 += nCode3 = GetBlackCode(); - } while (nCode3 >= 64); - do { - nCode2 += nCode3 = GetWhiteCode(); - } while (nCode3 >= 64); - } - if (nCode1 > 0 || nCode2 > 0) - { - if (nNewCLPos + nCode1 <= m_nColumns) - { - m_pCodingLine[m_nCurPosCL + 1] = nNewCLPos + nCode1; - } - else - { - m_pCodingLine[m_nCurPosCL + 1] = m_nColumns; - } - ++m_nCurPosCL; - if (m_pCodingLine[m_nCurPosCL] + nCode2 <= m_nColumns) - { - m_pCodingLine[m_nCurPosCL + 1] = m_pCodingLine[m_nCurPosCL] + nCode2; - } - else - { - m_pCodingLine[m_nCurPosCL + 1] = m_nColumns; - } - ++m_nCurPosCL; - nNewCLPos = m_pCodingLine[m_nCurPosCL]; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - break; - case Vert0_2D: - if (m_pRefLine[m_nCurPosRL] < m_nColumns) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL]; - ++m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - else - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_nColumns; - } - break; - case VertR1_2D: - if (m_pRefLine[m_nCurPosRL] + 1 < m_nColumns) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] + 1; - ++m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - else - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_nColumns; - } - break; - case VertL1_2D: - if (m_pRefLine[m_nCurPosRL] - 1 > nNewCLPos || (m_nCurPosCL == 0 && m_pRefLine[m_nCurPosRL] == 1)) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] - 1; - --m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - break; - case VertR2_2D: - if (m_pRefLine[m_nCurPosRL] + 2 < m_nColumns) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] + 2; - ++m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - else - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_nColumns; - } - break; - case VertL2_2D: - if (m_pRefLine[m_nCurPosRL] - 2 > nNewCLPos || (m_nCurPosCL == 0 && m_pRefLine[m_nCurPosRL] == 2)) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] - 2; - --m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - break; - case VertR3_2D: - if (m_pRefLine[m_nCurPosRL] + 3 < m_nColumns) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] + 3; - ++m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - else - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_nColumns; - } - break; - case VertL3_2D: - if (m_pRefLine[m_nCurPosRL] - 3 > nNewCLPos || (m_nCurPosCL == 0 && m_pRefLine[m_nCurPosRL] == 3)) - { - nNewCLPos = m_pCodingLine[++m_nCurPosCL] = m_pRefLine[m_nCurPosRL] - 3; - --m_nCurPosRL; - while (m_pRefLine[m_nCurPosRL] <= nNewCLPos && m_pRefLine[m_nCurPosRL] < m_nColumns) - { - m_nCurPosRL += 2; - } - } - break; - case EOF: - m_bEOF = true; - m_pCodingLine[m_nCurPosCL = 0] = m_nColumns; - return EOF; - default: - // TO DO: Error "Bad 2D code in CCITTFax stream" - bError = true; - break; - } - } while (m_pCodingLine[m_nCurPosCL] < m_nColumns); - } - else // 1-D encoding - { - m_pCodingLine[m_nCurPosCL = 0] = 0; - int nBlackPixels = 0; - while (m_pCodingLine[m_nCurPosCL] < m_nColumns) - { - nCode1 = 0; - - if (nBlackPixels) - { - do { - nCode1 += nCode3 = GetBlackCode(); - } while (nCode3 >= 64); - } - else - { - do { - nCode1 += nCode3 = GetWhiteCode(); - } while (nCode3 >= 64); - } - - m_pCodingLine[m_nCurPosCL + 1] = m_pCodingLine[m_nCurPosCL] + nCode1; - ++m_nCurPosCL; - nBlackPixels ^= 1; - } - } - - if (m_pCodingLine[m_nCurPosCL] != m_nColumns) - { - // TO DO: Error "CCITTFax row is wrong length " - - // Выставляем корректную длину - while (m_pCodingLine[m_nCurPosCL] > m_nColumns) - { - --m_nCurPosCL; - } - m_pCodingLine[++m_nCurPosCL] = m_nColumns; - bError = true; - } - - if (m_bByteAlign) - { - m_nInputBits &= ~7; - } - - // Проверяем символ конца строки, пропуска нулевые биты - bool bEOL = false; - if (!m_bEndOfBlock && m_mCurRow == m_nRows - 1) - { - m_bEOF = true; - } - else - { - nCode1 = LookBits(12); - while (nCode1 == 0) - { - SkipBits(1); - nCode1 = LookBits(12); - } - if (nCode1 == 0x001) - { - SkipBits(12); - bEOL = true; - } - else if (nCode1 == EOF) - { - m_bEOF = true; - } - } - - // Считываем тэг 2D кодировки - if (!m_bEOF && m_nK > 0) - { - m_bNextLine2D = !LookBits(1); - SkipBits(1); - } - - // Проверяем символ конца блока(end-of-block marker) - if (m_bEndOfBlock && bEOL) - { - nCode1 = LookBits(12); - if (nCode1 == 0x001) - { - SkipBits(12); - if (m_nK > 0) - { - LookBits(1); - SkipBits(1); - } - if (m_nK >= 0) - { - for (nIndex = 0; nIndex < 4; ++nIndex) - { - nCode1 = LookBits(12); - if (nCode1 != 0x001) - { - // TO DO: Error "Bad RTC code in CCITTFax stream" - } - SkipBits(12); - if (m_nK > 0) - { - LookBits(1); - SkipBits(1); - } - } - } - m_bEOF = true; - } - } - else if (bError && m_bEndOfLine) - { - do { - if (nCode1 == EOF) - { - m_bEOF = true; - return EOF; - } - SkipBits(1); - nCode1 = LookBits(13); - } while ((nCode1 >> 1) != 0x001); - SkipBits(12); - if (m_nK > 0) - { - SkipBits(1); - m_bNextLine2D = !(nCode1 & 1); - } - } - - m_nCurPosCL = 0; - m_nOutputBits = m_pCodingLine[1] - m_pCodingLine[0]; - if (m_nOutputBits == 0) - { - m_nCurPosCL = 1; - m_nOutputBits = m_pCodingLine[2] - m_pCodingLine[1]; - } - ++m_mCurRow; - } - - // Считываем один байт - int nRet = 0; - if (m_nOutputBits >= 8) - { - nRet = ((m_nCurPosCL & 1) == 0) ? 0xff : 0x00; - if ((m_nOutputBits -= 8) == 0) - { - ++m_nCurPosCL; - if (m_pCodingLine[m_nCurPosCL] < m_nColumns) - { - m_nOutputBits = m_pCodingLine[m_nCurPosCL + 1] - m_pCodingLine[m_nCurPosCL]; - } - } - } - else - { - int nBits = 8; - nRet = 0; - do { - if (m_nOutputBits > nBits) - { - nIndex = nBits; - nBits = 0; - if ((m_nCurPosCL & 1) == 0) - { - nRet |= 0xff >> (8 - nIndex); - } - m_nOutputBits -= nIndex; - } - else - { - nIndex = m_nOutputBits; - nBits -= m_nOutputBits; - if ((m_nCurPosCL & 1) == 0) - { - nRet |= (0xff >> (8 - nIndex)) << nBits; - } - m_nOutputBits = 0; - ++m_nCurPosCL; - if (m_pCodingLine[m_nCurPosCL] < m_nColumns) - { - m_nOutputBits = m_pCodingLine[m_nCurPosCL + 1] - m_pCodingLine[m_nCurPosCL]; - } - } - } while (nBits > 0 && m_pCodingLine[m_nCurPosCL] < m_nColumns); - } - m_nCharBuffer = m_bBlackIs1 ? (nRet ^ 0xff) : nRet; - return m_nCharBuffer; - } - - short CCITTFaxStream::Get2DCode() - { - CCITTCode *pCCITTCode; - - short nCode = 0; - if (m_bEndOfBlock) - { - nCode = LookBits(7); - pCCITTCode = &c_arrTable2D[nCode]; - if (pCCITTCode->nBitsCount > 0) - { - SkipBits(pCCITTCode->nBitsCount); - return pCCITTCode->nCode; - } - } - else - { - for (int nCount = 1; nCount <= 7; ++nCount) - { - nCode = LookBits(nCount); - if (nCount < 7) - { - nCode <<= 7 - nCount; - } - pCCITTCode = &c_arrTable2D[nCode]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - } - // TO DO: Error "Bad 2D code in CCITTFax stream" - return EOF; - } - - short CCITTFaxStream::GetWhiteCode() - { - CCITTCode *pCCITTCode; - - short nCode = 0; - if (m_bEndOfBlock) - { - nCode = LookBits(12); - if (EOF == nCode) - return 1; - - if ((nCode >> 5) == 0) - { - pCCITTCode = &c_arrWhiteTable1[nCode]; - } - else - { - pCCITTCode = &c_arrWhiteTable2[nCode >> 3]; - } - if (pCCITTCode->nBitsCount > 0) - { - SkipBits(pCCITTCode->nBitsCount); - return pCCITTCode->nCode; - } - } - else - { - for (int nCount = 1; nCount <= 9; ++nCount) - { - nCode = LookBits(nCount); - if (EOF == nCode) - return 1; - - if (nCount < 9) - { - nCode <<= 9 - nCount; - } - pCCITTCode = &c_arrWhiteTable2[nCode]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - for (int nCount = 11; nCount <= 12; ++nCount) - { - nCode = LookBits(nCount); - if (EOF == nCode) - return 1; - - if (nCount < 12) - { - nCode <<= 12 - nCount; - } - pCCITTCode = &c_arrWhiteTable1[nCode]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - } - // TO DO: Error "Bad white code in CCITTFax stream" - - SkipBits(1); - return 1; - } - - short CCITTFaxStream::GetBlackCode() - { - CCITTCode *pCCITTCode; - - short nCode = 0; - if (m_bEndOfBlock) - { - nCode = LookBits(13); - if (EOF == nCode) - return 1; - - if ((nCode >> 7) == 0) - { - pCCITTCode = &c_arrBlackTable1[nCode]; - } - else if ((nCode >> 9) == 0) - { - pCCITTCode = &c_arrBlackTable2[(nCode >> 1) - 64]; - } - else - { - pCCITTCode = &c_arrBlackTable3[nCode >> 7]; - } - if (pCCITTCode->nBitsCount > 0) - { - SkipBits(pCCITTCode->nBitsCount); - return pCCITTCode->nCode; - } - } - else - { - for (int nCount = 2; nCount <= 6; ++nCount) - { - nCode = LookBits(nCount); - if (EOF == nCode) - return 1; - - if (nCount < 6) - { - nCode <<= 6 - nCount; - } - pCCITTCode = &c_arrBlackTable3[nCode]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - for (int nCount = 7; nCount <= 12; ++nCount) - { - nCode = LookBits(nCount); - if (EOF == nCode) - return 1; - - if (nCount < 12) - { - nCode <<= 12 - nCount; - } - if (nCode >= 64) - { - pCCITTCode = &c_arrBlackTable2[nCode - 64]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - } - for (int nCount = 10; nCount <= 13; ++nCount) - { - nCode = LookBits(nCount); - if (EOF == nCode) - return 1; - - if (nCount < 13) - { - nCode <<= 13 - nCount; - } - pCCITTCode = &c_arrBlackTable1[nCode]; - if (pCCITTCode->nBitsCount == nCount) - { - SkipBits(nCount); - return pCCITTCode->nCode; - } - } - } - // TO DO: Error "Bad black code in CCITTFax stream" - - SkipBits(1); - return 1; - } - - short CCITTFaxStream::LookBits(int nCount) - { - while (m_nInputBits < nCount) - { - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - if (m_nInputBits == 0) - { - return EOF; - } - // Вблизи конца потока может оказаться, что запрашивается больше бит, чем - // их осталось в потоке. Нужно возратить корректное значение в данном случае. - return (m_nInputBuffer << (nCount - m_nInputBits)) & (0xffff >> (16 - nCount)); - } - m_nInputBuffer = (m_nInputBuffer << 8) + nChar; - m_nInputBits += 8; - } - return (m_nInputBuffer >> (m_nInputBits - nCount)) & (0xffff >> (16 - nCount)); - } - - StringExt *CCITTFaxStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - char sTemp[50]; - - if (nPSLevel < 2) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - - seResult->Append(sIndent)->Append("<< "); - if (m_nK != 0) - { - sprintf(sTemp, "/K %d ", m_nK); - seResult->Append(sTemp); - } - if (m_bEndOfLine) - { - seResult->Append("/EndOfLine true "); - } - if (m_bByteAlign) - { - seResult->Append("/EncodedByteAlign true "); - } - sprintf(sTemp, "/Columns %d ", m_nColumns); - seResult->Append(sTemp); - if (m_nRows != 0) - { - sprintf(sTemp, "/Rows %d ", m_nRows); - seResult->Append(sTemp); - } - if (!m_bEndOfBlock) - { - seResult->Append("/EndOfBlock false "); - } - if (m_bBlackIs1) - { - seResult->Append("/BlackIs1 true "); - } - seResult->Append(">> /CCITTFaxDecode filter\n"); - return seResult; - } - - bool CCITTFaxStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - //--------------------------------------------------------------------------------------------------------------- - // DCTStream - //--------------------------------------------------------------------------------------------------------------- - - // Константы для косинусного преобразования (20.12 fixed point format) -#define DCT_Cos_1_16 4017 // cos(pi/16) -#define DCT_Sin_1_16 799 // sin(pi/16) -#define DCT_Cos_3_16 3406 // cos(3*pi/16) -#define DCT_Sin_3_16 2276 // sin(3*pi/16) -#define DCT_Cos_6_16 1567 // cos(6*pi/16) -#define DCT_Sin_6_16 3784 // sin(6*pi/16) - -#define DCT_Sqrt_2 5793 // sqrt(2) -#define DCT_Sqrt_2__2 2896 // sqrt(2) / 2 - - // Константы для преобразования цветов (16.16 fixed point format) -#define DCT_CrToR 91881 // 1.4020 -#define DCT_CbToG -22553 // -0.3441363 -#define DCT_CrToG -46802 // -0.71413636 -#define DCT_CbToB 116130 // 1.772 - - // clip [-256,511] --> [0,255] -#define DCTClipOffset 256 - static unsigned char arrDCTClip[768]; - static int nDCTClipInit = 0; - - // zig zag - static int arrDCTZigZag[64] = - { - 0, - 1, 8, - 16, 9, 2, - 3, 10, 17, 24, - 32, 25, 18, 11, 4, - 5, 12, 19, 26, 33, 40, - 48, 41, 34, 27, 20, 13, 6, - 7, 14, 21, 28, 35, 42, 49, 56, - 57, 50, 43, 36, 29, 22, 15, - 23, 30, 37, 44, 51, 58, - 59, 52, 45, 38, 31, - 39, 46, 53, 60, - 61, 54, 47, - 55, 62, - 63 - }; - - DCTStream::DCTStream(Stream *pStream, int nColorTransform) : - FilterStream(pStream) - { - m_nColorTransform = nColorTransform; - m_bProgressive = m_bInterleaved = false; - m_nWidth = m_nHeight = 0; - m_nMCUWidth = m_nMCUHeight = 0; - m_nComponentsCount = 0; - m_nCurComponent = 0; - m_nX = m_nY = m_nDY = 0; - - for (int nComp = 0; nComp < 4; ++nComp) - { - for (int nIndex = 0; nIndex < 32; ++nIndex) - { - m_pppRowBuffer[nComp][nIndex] = NULL; - } - m_ppFrameBuffer[nComp] = NULL; - } - - if (!nDCTClipInit) - { - for (int nIndex = -256; nIndex < 0; ++nIndex) - arrDCTClip[DCTClipOffset + nIndex] = 0; - for (int nIndex = 0; nIndex < 256; ++nIndex) - arrDCTClip[DCTClipOffset + nIndex] = nIndex; - for (int nIndex = 256; nIndex < 512; ++nIndex) - arrDCTClip[DCTClipOffset + nIndex] = 255; - nDCTClipInit = 1; - } - } - - DCTStream::~DCTStream() - { - Close(); - delete m_pStream; - } - - void DCTStream::Reset() - { - m_pStream->Reset(); - - m_bProgressive = m_bInterleaved = false; - m_nWidth = m_nHeight = 0; - m_nComponentsCount = 0; - m_nQuantTablesCount = 0; - m_nDCHuffTablesCount = 0; - m_nACHuffTablesCount = 0; - m_bJFIFMarker = false; - m_bAdobeMarker = false; - m_nRestartInterval = 0; - - if (!ReadHeader()) - { - m_nY = m_nHeight; - return; - } - - // Вычислим размеры MCU - if (m_nComponentsCount == 1) - { - m_arrCompInfo[0].nXResolution = m_arrCompInfo[0].nYResolution = 1; - } - - m_nMCUWidth = m_arrCompInfo[0].nXResolution; - m_nMCUHeight = m_arrCompInfo[0].nYResolution; - - for (int nIndex = 1; nIndex < m_nComponentsCount; ++nIndex) - { - if (m_arrCompInfo[nIndex].nXResolution > m_nMCUWidth) - { - m_nMCUWidth = m_arrCompInfo[nIndex].nXResolution; - } - if (m_arrCompInfo[nIndex].nYResolution > m_nMCUHeight) - { - m_nMCUHeight = m_arrCompInfo[nIndex].nYResolution; - } - } - m_nMCUWidth *= 8; - m_nMCUHeight *= 8; - - if (m_nColorTransform == -1) - { - if (m_nComponentsCount == 3) - { - if (m_bJFIFMarker) - { - m_nColorTransform = 1; - } - else if (m_arrCompInfo[0].nID == 82 && m_arrCompInfo[1].nID == 71 && m_arrCompInfo[2].nID == 66) // ASCII "RGB" - { - m_nColorTransform = 0; - } - else - { - m_nColorTransform = 1; - } - } - else - { - m_nColorTransform = 0; - } - } - - if (m_bProgressive || !m_bInterleaved) - { - - // Выделяем память для всей картинки - m_nBufferWidth = ((m_nWidth + m_nMCUWidth - 1) / m_nMCUWidth) * m_nMCUWidth; - m_nBufferHeight = ((m_nHeight + m_nMCUHeight - 1) / m_nMCUHeight) * m_nMCUHeight; - - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - m_ppFrameBuffer[nIndex] = (int *)MemUtilsMallocArray(m_nBufferWidth * m_nBufferHeight, sizeof(int)); - memset(m_ppFrameBuffer[nIndex], 0, m_nBufferWidth * m_nBufferHeight * sizeof(int)); - } - - // Считываем данные картинки - do { - m_nRestartMarker = 0xd0; - Restart(); - ReadScan(); - } while (ReadHeader()); - - // Декодируем - DecodeImage(); - - // Обнуляем счетчики - m_nCurComponent = 0; - m_nX = 0; - m_nY = 0; - - } - else - { - // Выделяем память под одну строку для MCU - m_nBufferWidth = ((m_nWidth + m_nMCUWidth - 1) / m_nMCUWidth) * m_nMCUWidth; - for (int nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - for (int nY = 0; nY < m_nMCUHeight; ++nY) - { - m_pppRowBuffer[nComp][nY] = (unsigned char *)MemUtilsMallocArray(m_nBufferWidth, sizeof(unsigned char)); - } - } - - // Обнуляем счетчики - m_nCurComponent = 0; - m_nX = 0; - m_nY = 0; - m_nDY = m_nMCUHeight; - - m_nRestartMarker = 0xd0; - Restart(); - } - } - - void DCTStream::Close() - { - for (int nComp = 0; nComp < 4; ++nComp) - { - for (int nY = 0; nY < 32; ++nY) - { - MemUtilsFree(m_pppRowBuffer[nComp][nY]); - m_pppRowBuffer[nComp][nY] = NULL; - } - MemUtilsFree(m_ppFrameBuffer[nComp]); - m_ppFrameBuffer[nComp] = NULL; - } - FilterStream::Close(); - } - - int DCTStream::GetChar() - { - int nChar = 0; - if (m_nY >= m_nHeight) - { - return EOF; - } - if (m_bProgressive || !m_bInterleaved) - { - nChar = m_ppFrameBuffer[m_nCurComponent][m_nY * m_nBufferWidth + m_nX]; - if (++m_nCurComponent == m_nComponentsCount) - { - m_nCurComponent = 0; - if (++m_nX == m_nWidth) - { - m_nX = 0; - ++m_nY; - } - } - } - else - { - if (m_nDY >= m_nMCUHeight) - { - if (!ReadMCURow()) - { - m_nY = m_nHeight; - return EOF; - } - m_nCurComponent = 0; - m_nX = 0; - m_nDY = 0; - } - nChar = m_pppRowBuffer[m_nCurComponent][m_nDY][m_nX]; - if (++m_nCurComponent == m_nComponentsCount) - { - m_nCurComponent = 0; - if (++m_nX == m_nWidth) - { - m_nX = 0; - ++m_nY; - ++m_nDY; - if (m_nY == m_nHeight) - { - ReadTrailer(); - } - } - } - } - return nChar; - } - - int DCTStream::LookChar() - { - if (m_nY >= m_nHeight) - { - return EOF; - } - if (m_bProgressive || !m_bInterleaved) - { - return m_ppFrameBuffer[m_nCurComponent][m_nY * m_nBufferWidth + m_nX]; - } - else - { - if (m_nDY >= m_nMCUHeight) - { - if (!ReadMCURow()) - { - m_nY = m_nHeight; - return EOF; - } - m_nCurComponent = 0; - m_nX = 0; - m_nDY = 0; - } - return m_pppRowBuffer[m_nCurComponent][m_nDY][m_nX]; - } - } - - void DCTStream::Restart() - { - m_nInputBits = 0; - m_nRestartCtr = m_nRestartInterval; - - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - m_arrCompInfo[nIndex].nPrevDC = 0; - - m_nEOBRun = 0; - } - - // Считываем одну строку из MCUs из соответствующего потока JPEG. - bool DCTStream::ReadMCURow() - { - int arrRawData[64]; - unsigned char arrTransformData[64]; - unsigned char *p1, *p2; - int x1, x2, y2, x3, y3, x4, y4, x5, y5, i; - - for (x1 = 0; x1 < m_nWidth; x1 += m_nMCUWidth) - { - // Обрабатываем restart marker - if (m_nRestartInterval > 0 && m_nRestartCtr == 0) - { - int nChar = ReadMarker(); - if (nChar != m_nRestartMarker) - { - // TO DO: Error "Bad DCT data: incorrect restart marker" - return false; - } - if (++m_nRestartMarker == 0xd8) - m_nRestartMarker = 0xd0; - Restart(); - } - - // Считываем один MCU - for (int nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - int nXRes = m_arrCompInfo[nComp].nXResolution; - int nYRes = m_arrCompInfo[nComp].nYResolution; - int nHoriz = m_nMCUWidth / nXRes; - int nVert = m_nMCUHeight / nYRes; - int nHorizSub = nHoriz / 8; - int nVertSub = nVert / 8; - for (y2 = 0; y2 < m_nMCUHeight; y2 += nVert) - { - for (x2 = 0; x2 < m_nMCUWidth; x2 += nHoriz) - { - if (!ReadDataUnit(&m_arrDCHuffTables[m_oCurScanInfo.arrDCHuffTable[nComp]], &m_arrACHuffTables[m_oCurScanInfo.arrACHuffTable[nComp]], &m_arrCompInfo[nComp].nPrevDC, arrRawData)) - return false; - - TransformDataUnit(m_arrQuantTables[m_arrCompInfo[nComp].nQuantTableNum], arrRawData, arrTransformData); - if (nHorizSub == 1 && nVertSub == 1) - { - for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) - { - p1 = &m_pppRowBuffer[nComp][y2 + y3][x1 + x2]; - p1[0] = arrTransformData[i + 0]; - p1[1] = arrTransformData[i + 1]; - p1[2] = arrTransformData[i + 2]; - p1[3] = arrTransformData[i + 3]; - p1[4] = arrTransformData[i + 4]; - p1[5] = arrTransformData[i + 5]; - p1[6] = arrTransformData[i + 6]; - p1[7] = arrTransformData[i + 7]; - } - } - else if (nHorizSub == 2 && nVertSub == 2) - { - for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) - { - p1 = &m_pppRowBuffer[nComp][y2 + y3][x1 + x2]; - p2 = &m_pppRowBuffer[nComp][y2 + y3 + 1][x1 + x2]; - p1[0] = p1[1] = p2[0] = p2[1] = arrTransformData[i + 0]; - p1[2] = p1[3] = p2[2] = p2[3] = arrTransformData[i + 1]; - p1[4] = p1[5] = p2[4] = p2[5] = arrTransformData[i + 2]; - p1[6] = p1[7] = p2[6] = p2[7] = arrTransformData[i + 3]; - p1[8] = p1[9] = p2[8] = p2[9] = arrTransformData[i + 4]; - p1[10] = p1[11] = p2[10] = p2[11] = arrTransformData[i + 5]; - p1[12] = p1[13] = p2[12] = p2[13] = arrTransformData[i + 6]; - p1[14] = p1[15] = p2[14] = p2[15] = arrTransformData[i + 7]; - } - } - else - { - i = 0; - for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += nVertSub) - { - for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += nHorizSub) - { - for (y5 = 0; y5 < nVertSub; ++y5) - for (x5 = 0; x5 < nHorizSub; ++x5) - m_pppRowBuffer[nComp][y2 + y4 + y5][x1 + x2 + x4 + x5] = arrTransformData[i]; - ++i; - } - } - } - } - } - } - --m_nRestartCtr; - - // Преобазуем пространство цветов - if (m_nColorTransform) - { - // YCbCr -> RGB - if (m_nComponentsCount == 3) - { - for (y2 = 0; y2 < m_nMCUHeight; ++y2) - { - for (x2 = 0; x2 < m_nMCUWidth; ++x2) - { - int nY = m_pppRowBuffer[0][y2][x1 + x2]; - int nCb = m_pppRowBuffer[1][y2][x1 + x2] - 128; - int nCr = m_pppRowBuffer[2][y2][x1 + x2] - 128; - int nR = ((nY << 16) + DCT_CrToR * nCr + 32768) >> 16; - m_pppRowBuffer[0][y2][x1 + x2] = arrDCTClip[DCTClipOffset + nR]; - int nG = ((nY << 16) + DCT_CbToG * nCb + DCT_CrToG * nCr + 32768) >> 16; - m_pppRowBuffer[1][y2][x1 + x2] = arrDCTClip[DCTClipOffset + nG]; - int nB = ((nY << 16) + DCT_CbToB * nCb + 32768) >> 16; - m_pppRowBuffer[2][y2][x1 + x2] = arrDCTClip[DCTClipOffset + nB]; - } - } - } - else if (m_nComponentsCount == 4) // YCbCrK -> CMYK (K оставляем неизменненным) - { - for (y2 = 0; y2 < m_nMCUHeight; ++y2) - { - for (x2 = 0; x2 < m_nMCUWidth; ++x2) - { - int nY = m_pppRowBuffer[0][y2][x1 + x2]; - int nCb = m_pppRowBuffer[1][y2][x1 + x2] - 128; - int nCr = m_pppRowBuffer[2][y2][x1 + x2] - 128; - int nR = ((nY << 16) + DCT_CrToR * nCr + 32768) >> 16; - m_pppRowBuffer[0][y2][x1 + x2] = 255 - arrDCTClip[DCTClipOffset + nR]; - int nG = ((nY << 16) + DCT_CbToG * nCb + DCT_CrToG * nCr + 32768) >> 16; - m_pppRowBuffer[1][y2][x1 + x2] = 255 - arrDCTClip[DCTClipOffset + nG]; - int nB = ((nY << 16) + DCT_CbToB * nCb + 32768) >> 16; - m_pppRowBuffer[2][y2][x1 + x2] = 255 - arrDCTClip[DCTClipOffset + nB]; - } - } - } - } - } - return true; - } - - // Только для progressive или не interleaved JPEG. - void DCTStream::ReadScan() - { - int arrData[64]; - int x1, y1, dx1, dy1, x2, y2, y3, nComponent = 0, i; - int *pBuffer; - - if (m_oCurScanInfo.nComponentsCount == 1) - { - for (nComponent = 0; nComponent < m_nComponentsCount; ++nComponent) - { - if (m_oCurScanInfo.arrbComponent[nComponent]) - { - break; - } - } - dx1 = m_nMCUWidth / m_arrCompInfo[nComponent].nXResolution; - dy1 = m_nMCUHeight / m_arrCompInfo[nComponent].nYResolution; - } - else - { - dx1 = m_nMCUWidth; - dy1 = m_nMCUHeight; - } - - for (y1 = 0; y1 < m_nHeight; y1 += dy1) - { - for (x1 = 0; x1 < m_nWidth; x1 += dx1) - { - - // Обрабатываем restart marker - if (m_nRestartInterval > 0 && m_nRestartCtr == 0) - { - int nChar = ReadMarker(); - if (nChar != m_nRestartMarker) - { - // TO DO: Error "Bad DCT data: incorrect restart marker" - return; - } - if (++m_nRestartMarker == 0xd8) - { - m_nRestartMarker = 0xd0; - } - Restart(); - } - - // Считываем один MCU - for (nComponent = 0; nComponent < m_nComponentsCount; ++nComponent) - { - if (!m_oCurScanInfo.arrbComponent[nComponent]) - { - continue; - } - - int nXRes = m_arrCompInfo[nComponent].nXResolution; - int nYRes = m_arrCompInfo[nComponent].nYResolution; - int nHoriz = m_nMCUWidth / nXRes; - int nVert = m_nMCUHeight / nYRes; - int nVertSub = nVert / 8; - for (y2 = 0; y2 < dy1; y2 += nVert) - { - for (x2 = 0; x2 < dx1; x2 += nHoriz) - { - pBuffer = &m_ppFrameBuffer[nComponent][(y1 + y2) * m_nBufferWidth + (x1 + x2)]; - for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) - { - arrData[i + 0] = pBuffer[0]; - arrData[i + 1] = pBuffer[1]; - arrData[i + 2] = pBuffer[2]; - arrData[i + 3] = pBuffer[3]; - arrData[i + 4] = pBuffer[4]; - arrData[i + 5] = pBuffer[5]; - arrData[i + 6] = pBuffer[6]; - arrData[i + 7] = pBuffer[7]; - pBuffer += m_nBufferWidth * nVertSub; - } - - if (m_bProgressive) - { - if (!ReadProgressiveDataUnit(&m_arrDCHuffTables[m_oCurScanInfo.arrDCHuffTable[nComponent]], &m_arrACHuffTables[m_oCurScanInfo.arrACHuffTable[nComponent]], &m_arrCompInfo[nComponent].nPrevDC, arrData)) - { - return; - } - } - else - { - if (!ReadDataUnit(&m_arrDCHuffTables[m_oCurScanInfo.arrDCHuffTable[nComponent]], &m_arrACHuffTables[m_oCurScanInfo.arrACHuffTable[nComponent]], &m_arrCompInfo[nComponent].nPrevDC, arrData)) - { - return; - } - } - - pBuffer = &m_ppFrameBuffer[nComponent][(y1 + y2) * m_nBufferWidth + (x1 + x2)]; - for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) - { - pBuffer[0] = arrData[i + 0]; - pBuffer[1] = arrData[i + 1]; - pBuffer[2] = arrData[i + 2]; - pBuffer[3] = arrData[i + 3]; - pBuffer[4] = arrData[i + 4]; - pBuffer[5] = arrData[i + 5]; - pBuffer[6] = arrData[i + 6]; - pBuffer[7] = arrData[i + 7]; - pBuffer += m_nBufferWidth * nVertSub; - } - } - } - } - --m_nRestartCtr; - } - } - } - - bool DCTStream::ReadDataUnit(DCTHuffTable *pDCHuffTable, DCTHuffTable *pACHuffTable, int *pnPrevDC, int arrData[64]) - { - int nSize = 0, nAmp = 0; - - if ((nSize = ReadHuffSymbol(pDCHuffTable)) == 9999) - { - return false; - } - if (nSize > 0) - { - if ((nAmp = ReadAmp(nSize)) == 9999) - { - return false; - } - } - else - { - nAmp = 0; - } - arrData[0] = *pnPrevDC += nAmp; - for (int nI = 1; nI < 64; ++nI) - { - arrData[nI] = 0; - } - int nIndex = 1; - while (nIndex < 64) - { - int nRun = 0; - int nSymbol = 0; - while ((nSymbol = ReadHuffSymbol(pACHuffTable)) == 0xf0 && nRun < 0x30) - { - nRun += 0x10; - } - if (nSymbol == 9999) - { - return false; - } - if (nSymbol == 0x00) - { - break; - } - else - { - nRun += (nSymbol >> 4) & 0x0f; - nSize = nSymbol & 0x0f; - nAmp = ReadAmp(nSize); - if (nAmp == 9999) - { - return false; - } - nIndex += nRun; - if (nIndex < 64) - { - int nNewIndex = arrDCTZigZag[nIndex++]; - arrData[nNewIndex] = nAmp; - } - } - } - return true; - } - - bool DCTStream::ReadProgressiveDataUnit(DCTHuffTable *pDCHuffTable, DCTHuffTable *pACHuffTable, int *pnPrevDC, int arrData[64]) - { - int nRun = 0, nSize = 0, nAmp = 0, nBit = 0; - - // DC кoэффициенты - int nKoef = m_oCurScanInfo.nFirstKoef; - if (nKoef == 0) - { - if (m_oCurScanInfo.nApproxH == 0) - { - if ((nSize = ReadHuffSymbol(pDCHuffTable)) == 9999) - { - return false; - } - if (nSize > 0) - { - if ((nAmp = ReadAmp(nSize)) == 9999) - { - return false; - } - } - else - { - nAmp = 0; - } - arrData[0] += (*pnPrevDC += nAmp) << m_oCurScanInfo.nApproxL; - } - else - { - if ((nBit = ReadBit()) == 9999) - { - return false; - } - arrData[0] += nBit << m_oCurScanInfo.nApproxL; - } - ++nKoef; - } - if (m_oCurScanInfo.nLastKoef == 0) - { - return true; - } - - // Проверяем группу EOB - if (m_nEOBRun > 0) - { - while (nKoef <= m_oCurScanInfo.nLastKoef) - { - int nNewIndex = arrDCTZigZag[nKoef++]; - if (arrData[nNewIndex] != 0) - { - if ((nBit = ReadBit()) == EOF) - { - return false; - } - if (nBit) - { - arrData[nNewIndex] += 1 << m_oCurScanInfo.nApproxL; - } - } - } - --m_nEOBRun; - return true; - } - - int nK = 0; - // считываем коэффициенты AC - while (nKoef <= m_oCurScanInfo.nLastKoef) - { - int nSymbol = 0; - if ((nSymbol = ReadHuffSymbol(pACHuffTable)) == 9999) - { - return false; - } - - // ZRL - if (nSymbol == 0xf0) - { - nK = 0; - while (nK < 16) - { - int nNewIndex = arrDCTZigZag[nKoef++]; - if (arrData[nNewIndex] == 0) - { - ++nK; - } - else - { - if ((nBit = ReadBit()) == EOF) - { - return false; - } - if (nBit) - { - arrData[nNewIndex] += 1 << m_oCurScanInfo.nApproxL; - } - } - } - } - else if ((nSymbol & 0x0f) == 0x00) // EOB run - { - int nTemp = nSymbol >> 4; - m_nEOBRun = 0; - for (nK = 0; nK < nTemp; ++nK) - { - if ((nBit = ReadBit()) == EOF) - { - return false; - } - m_nEOBRun = (m_nEOBRun << 1) | nBit; - } - m_nEOBRun += 1 << nTemp; - while (nKoef <= m_oCurScanInfo.nLastKoef) - { - int nNewIndex = arrDCTZigZag[nKoef++]; - if (arrData[nNewIndex] != 0) - { - if ((nBit = ReadBit()) == EOF) - { - return false; - } - if (nBit) - { - arrData[nNewIndex] += 1 << m_oCurScanInfo.nApproxL; - } - } - } - --m_nEOBRun; - break; - } - else - { - nRun = (nSymbol >> 4) & 0x0f; - nSize = nSymbol & 0x0f; - if ((nAmp = ReadAmp(nSize)) == 9999) - { - return false; - } - nK = 0; - int nNewIndex = 0; - do { - nNewIndex = arrDCTZigZag[nKoef++]; - while (arrData[nNewIndex] != 0) - { - if ((nBit = ReadBit()) == EOF) - { - return false; - } - if (nBit) - { - arrData[nNewIndex] += 1 << m_oCurScanInfo.nApproxL; - } - nNewIndex = arrDCTZigZag[nKoef++]; - } - ++nK; - } while (nK <= nRun); - arrData[nNewIndex] = nAmp << m_oCurScanInfo.nApproxL; - } - } - - return true; - } - - void DCTStream::DecodeImage() - { - int arrDataIn[64]; - unsigned char arrDataOut[64]; - unsigned short *pQuantTable; - int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, i; - - int *p0, *p1, *p2; - - for (y1 = 0; y1 < m_nBufferHeight; y1 += m_nMCUHeight) - { - for (x1 = 0; x1 < m_nBufferWidth; x1 += m_nMCUWidth) - { - for (int nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - pQuantTable = m_arrQuantTables[m_arrCompInfo[nComp].nQuantTableNum]; - int nXRes = m_arrCompInfo[nComp].nXResolution; - int nYRes = m_arrCompInfo[nComp].nYResolution; - int nHoriz = m_nMCUWidth / nXRes; - int nVert = m_nMCUHeight / nYRes; - int nHorizSub = nHoriz / 8; - int nVertSub = nVert / 8; - for (y2 = 0; y2 < m_nMCUHeight; y2 += nVert) - { - for (x2 = 0; x2 < m_nMCUWidth; x2 += nHoriz) - { - p1 = &m_ppFrameBuffer[nComp][(y1 + y2) * m_nBufferWidth + (x1 + x2)]; - for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) - { - arrDataIn[i + 0] = p1[0]; - arrDataIn[i + 1] = p1[1]; - arrDataIn[i + 2] = p1[2]; - arrDataIn[i + 3] = p1[3]; - arrDataIn[i + 4] = p1[4]; - arrDataIn[i + 5] = p1[5]; - arrDataIn[i + 6] = p1[6]; - arrDataIn[i + 7] = p1[7]; - p1 += m_nBufferWidth * nVertSub; - } - - TransformDataUnit(pQuantTable, arrDataIn, arrDataOut); - - p1 = &m_ppFrameBuffer[nComp][(y1 + y2) * m_nBufferWidth + (x1 + x2)]; - if (nHorizSub == 1 && nVertSub == 1) - { - for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) - { - p1[0] = arrDataOut[i + 0] & 0xff; - p1[1] = arrDataOut[i + 1] & 0xff; - p1[2] = arrDataOut[i + 2] & 0xff; - p1[3] = arrDataOut[i + 3] & 0xff; - p1[4] = arrDataOut[i + 4] & 0xff; - p1[5] = arrDataOut[i + 5] & 0xff; - p1[6] = arrDataOut[i + 6] & 0xff; - p1[7] = arrDataOut[i + 7] & 0xff; - p1 += m_nBufferWidth; - } - } - else if (nHorizSub == 2 && nVertSub == 2) - { - p2 = p1 + m_nBufferWidth; - for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) - { - p1[0] = p1[1] = p2[0] = p2[1] = arrDataOut[i + 0] & 0xff; - p1[2] = p1[3] = p2[2] = p2[3] = arrDataOut[i + 1] & 0xff; - p1[4] = p1[5] = p2[4] = p2[5] = arrDataOut[i + 2] & 0xff; - p1[6] = p1[7] = p2[6] = p2[7] = arrDataOut[i + 3] & 0xff; - p1[8] = p1[9] = p2[8] = p2[9] = arrDataOut[i + 4] & 0xff; - p1[10] = p1[11] = p2[10] = p2[11] = arrDataOut[i + 5] & 0xff; - p1[12] = p1[13] = p2[12] = p2[13] = arrDataOut[i + 6] & 0xff; - p1[14] = p1[15] = p2[14] = p2[15] = arrDataOut[i + 7] & 0xff; - p1 += m_nBufferWidth * 2; - p2 += m_nBufferWidth * 2; - } - } - else - { - i = 0; - for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += nVertSub) - { - for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += nHorizSub) - { - p2 = p1 + x4; - for (y5 = 0; y5 < nVertSub; ++y5) - { - for (x5 = 0; x5 < nHorizSub; ++x5) - { - p2[x5] = arrDataOut[i] & 0xff; - } - p2 += m_nBufferWidth; - } - ++i; - } - p1 += m_nBufferWidth * nVertSub; - } - } - } - } - } - - // Преобразование пространства цветов - if (m_nColorTransform) - { - // YCbCr -> RGB - if (m_nComponentsCount == 3) - { - for (y2 = 0; y2 < m_nMCUHeight; ++y2) - { - p0 = &m_ppFrameBuffer[0][(y1 + y2) * m_nBufferWidth + x1]; - p1 = &m_ppFrameBuffer[1][(y1 + y2) * m_nBufferWidth + x1]; - p2 = &m_ppFrameBuffer[2][(y1 + y2) * m_nBufferWidth + x1]; - for (x2 = 0; x2 < m_nMCUWidth; ++x2) - { - int nY = *p0; - int nCb = *p1 - 128; - int nCr = *p2 - 128; - int nR = ((nY << 16) + DCT_CrToR * nCr + 32768) >> 16; - *p0++ = arrDCTClip[DCTClipOffset + nR]; - int nG = ((nY << 16) + DCT_CbToG * nCb + DCT_CrToG * nCr + 32768) >> 16; - *p1++ = arrDCTClip[DCTClipOffset + nG]; - int nB = ((nY << 16) + DCT_CbToB * nCb + 32768) >> 16; - *p2++ = arrDCTClip[DCTClipOffset + nB]; - } - } - } - else if (m_nComponentsCount == 4) // YCbCrK -> CMYK (K оставляем неизмененным) - { - for (y2 = 0; y2 < m_nMCUHeight; ++y2) - { - p0 = &m_ppFrameBuffer[0][(y1 + y2) * m_nBufferWidth + x1]; - p1 = &m_ppFrameBuffer[1][(y1 + y2) * m_nBufferWidth + x1]; - p2 = &m_ppFrameBuffer[2][(y1 + y2) * m_nBufferWidth + x1]; - for (x2 = 0; x2 < m_nMCUWidth; ++x2) - { - int nY = *p0; - int nCb = *p1 - 128; - int nCr = *p2 - 128; - int nR = ((nY << 16) + DCT_CrToR * nCr + 32768) >> 16; - *p0++ = 255 - arrDCTClip[DCTClipOffset + nR]; - int nG = ((nY << 16) + DCT_CbToG * nCb + DCT_CrToG * nCr + 32768) >> 16; - *p1++ = 255 - arrDCTClip[DCTClipOffset + nG]; - int nB = ((nY << 16) + DCT_CbToB * nCb + 32768) >> 16; - *p2++ = 255 - arrDCTClip[DCTClipOffset + nB]; - } - } - } - } - } - } - } - - void DCTStream::TransformDataUnit(unsigned short *pQuantTable, int arrDataIn[64], unsigned char arrDataOut[64]) - { - int arrBuffer[8] ={ 0, 0, 0, 0, 0, 0, 0, 0 }; - int nTemp = 0; - int *pCurLine = NULL; - - // Деквантизация - for (int nIndex = 0; nIndex < 64; ++nIndex) - { - arrDataIn[nIndex] *= pQuantTable[nIndex]; - } - - // Обратное синусно-косинусное преобразования (по строкам) - for (int nIndex = 0; nIndex < 64; nIndex += 8) - { - pCurLine = arrDataIn + nIndex; - - // Проверяем случай, когда все коэффициенты равны 0 - if (pCurLine[1] == 0 && pCurLine[2] == 0 && pCurLine[3] == 0 && pCurLine[4] == 0 && pCurLine[5] == 0 && pCurLine[6] == 0 && pCurLine[7] == 0) - { - nTemp = (DCT_Sqrt_2 * pCurLine[0] + 512) >> 10; - pCurLine[0] = nTemp; - pCurLine[1] = nTemp; - pCurLine[2] = nTemp; - pCurLine[3] = nTemp; - pCurLine[4] = nTemp; - pCurLine[5] = nTemp; - pCurLine[6] = nTemp; - pCurLine[7] = nTemp; - continue; - } - - // Шаг 4 (Сдвиг на 128) - arrBuffer[0] = (DCT_Sqrt_2 * pCurLine[0] + 128) >> 8; - arrBuffer[1] = (DCT_Sqrt_2 * pCurLine[4] + 128) >> 8; - arrBuffer[2] = pCurLine[2]; - arrBuffer[3] = pCurLine[6]; - arrBuffer[4] = (DCT_Sqrt_2__2 * (pCurLine[1] - pCurLine[7]) + 128) >> 8; - arrBuffer[7] = (DCT_Sqrt_2__2 * (pCurLine[1] + pCurLine[7]) + 128) >> 8; - arrBuffer[5] = pCurLine[3] << 4; - arrBuffer[6] = pCurLine[5] << 4; - - // Шаг 3 - nTemp = (arrBuffer[0] - arrBuffer[1] + 1) >> 1; - arrBuffer[0] = (arrBuffer[0] + arrBuffer[1] + 1) >> 1; - arrBuffer[1] = nTemp; - nTemp = (arrBuffer[2] * DCT_Sin_6_16 + arrBuffer[3] * DCT_Cos_6_16 + 128) >> 8; - arrBuffer[2] = (arrBuffer[2] * DCT_Cos_6_16 - arrBuffer[3] * DCT_Sin_6_16 + 128) >> 8; - arrBuffer[3] = nTemp; - nTemp = (arrBuffer[4] - arrBuffer[6] + 1) >> 1; - arrBuffer[4] = (arrBuffer[4] + arrBuffer[6] + 1) >> 1; - arrBuffer[6] = nTemp; - nTemp = (arrBuffer[7] + arrBuffer[5] + 1) >> 1; - arrBuffer[5] = (arrBuffer[7] - arrBuffer[5] + 1) >> 1; - arrBuffer[7] = nTemp; - - // Шаг 2 - nTemp = (arrBuffer[0] - arrBuffer[3] + 1) >> 1; - arrBuffer[0] = (arrBuffer[0] + arrBuffer[3] + 1) >> 1; - arrBuffer[3] = nTemp; - nTemp = (arrBuffer[1] - arrBuffer[2] + 1) >> 1; - arrBuffer[1] = (arrBuffer[1] + arrBuffer[2] + 1) >> 1; - arrBuffer[2] = nTemp; - nTemp = (arrBuffer[4] * DCT_Sin_3_16 + arrBuffer[7] * DCT_Cos_3_16 + 2048) >> 12; - arrBuffer[4] = (arrBuffer[4] * DCT_Cos_3_16 - arrBuffer[7] * DCT_Sin_3_16 + 2048) >> 12; - arrBuffer[7] = nTemp; - nTemp = (arrBuffer[5] * DCT_Sin_1_16 + arrBuffer[6] * DCT_Cos_1_16 + 2048) >> 12; - arrBuffer[5] = (arrBuffer[5] * DCT_Cos_1_16 - arrBuffer[6] * DCT_Sin_1_16 + 2048) >> 12; - arrBuffer[6] = nTemp; - - // Шаг 1 - pCurLine[0] = arrBuffer[0] + arrBuffer[7]; - pCurLine[7] = arrBuffer[0] - arrBuffer[7]; - pCurLine[1] = arrBuffer[1] + arrBuffer[6]; - pCurLine[6] = arrBuffer[1] - arrBuffer[6]; - pCurLine[2] = arrBuffer[2] + arrBuffer[5]; - pCurLine[5] = arrBuffer[2] - arrBuffer[5]; - pCurLine[3] = arrBuffer[3] + arrBuffer[4]; - pCurLine[4] = arrBuffer[3] - arrBuffer[4]; - } - - // Обратное синусно-косинусное преобразования (по столбцам) - for (int nIndex = 0; nIndex < 8; ++nIndex) - { - pCurLine = arrDataIn + nIndex; - - // проверяем все ли коэффициенты нулевые - if (pCurLine[1 * 8] == 0 && pCurLine[2 * 8] == 0 && pCurLine[3 * 8] == 0 && pCurLine[4 * 8] == 0 && pCurLine[5 * 8] == 0 && pCurLine[6 * 8] == 0 && pCurLine[7 * 8] == 0) - { - nTemp = (DCT_Sqrt_2 * arrDataIn[nIndex + 0] + 8192) >> 14; - pCurLine[0 * 8] = nTemp; - pCurLine[1 * 8] = nTemp; - pCurLine[2 * 8] = nTemp; - pCurLine[3 * 8] = nTemp; - pCurLine[4 * 8] = nTemp; - pCurLine[5 * 8] = nTemp; - pCurLine[6 * 8] = nTemp; - pCurLine[7 * 8] = nTemp; - continue; - } - - // Шаг 4 - arrBuffer[0] = (DCT_Sqrt_2 * pCurLine[0 * 8] + 2048) >> 12; - arrBuffer[1] = (DCT_Sqrt_2 * pCurLine[4 * 8] + 2048) >> 12; - arrBuffer[2] = pCurLine[2 * 8]; - arrBuffer[3] = pCurLine[6 * 8]; - arrBuffer[4] = (DCT_Sqrt_2__2 * (pCurLine[1 * 8] - pCurLine[7 * 8]) + 2048) >> 12; - arrBuffer[7] = (DCT_Sqrt_2__2 * (pCurLine[1 * 8] + pCurLine[7 * 8]) + 2048) >> 12; - arrBuffer[5] = pCurLine[3 * 8]; - arrBuffer[6] = pCurLine[5 * 8]; - - // Шаг 3 - nTemp = (arrBuffer[0] - arrBuffer[1] + 1) >> 1; - arrBuffer[0] = (arrBuffer[0] + arrBuffer[1] + 1) >> 1; - arrBuffer[1] = nTemp; - nTemp = (arrBuffer[2] * DCT_Sin_6_16 + arrBuffer[3] * DCT_Cos_6_16 + 2048) >> 12; - arrBuffer[2] = (arrBuffer[2] * DCT_Cos_6_16 - arrBuffer[3] * DCT_Sin_6_16 + 2048) >> 12; - arrBuffer[3] = nTemp; - nTemp = (arrBuffer[4] - arrBuffer[6] + 1) >> 1; - arrBuffer[4] = (arrBuffer[4] + arrBuffer[6] + 1) >> 1; - arrBuffer[6] = nTemp; - nTemp = (arrBuffer[7] + arrBuffer[5] + 1) >> 1; - arrBuffer[5] = (arrBuffer[7] - arrBuffer[5] + 1) >> 1; - arrBuffer[7] = nTemp; - - // Шаг 2 - nTemp = (arrBuffer[0] - arrBuffer[3] + 1) >> 1; - arrBuffer[0] = (arrBuffer[0] + arrBuffer[3] + 1) >> 1; - arrBuffer[3] = nTemp; - nTemp = (arrBuffer[1] - arrBuffer[2] + 1) >> 1; - arrBuffer[1] = (arrBuffer[1] + arrBuffer[2] + 1) >> 1; - arrBuffer[2] = nTemp; - nTemp = (arrBuffer[4] * DCT_Sin_3_16 + arrBuffer[7] * DCT_Cos_3_16 + 2048) >> 12; - arrBuffer[4] = (arrBuffer[4] * DCT_Cos_3_16 - arrBuffer[7] * DCT_Sin_3_16 + 2048) >> 12; - arrBuffer[7] = nTemp; - nTemp = (arrBuffer[5] * DCT_Sin_1_16 + arrBuffer[6] * DCT_Cos_1_16 + 2048) >> 12; - arrBuffer[5] = (arrBuffer[5] * DCT_Cos_1_16 - arrBuffer[6] * DCT_Sin_1_16 + 2048) >> 12; - arrBuffer[6] = nTemp; - - // Шаг 1 - pCurLine[0 * 8] = arrBuffer[0] + arrBuffer[7]; - pCurLine[7 * 8] = arrBuffer[0] - arrBuffer[7]; - pCurLine[1 * 8] = arrBuffer[1] + arrBuffer[6]; - pCurLine[6 * 8] = arrBuffer[1] - arrBuffer[6]; - pCurLine[2 * 8] = arrBuffer[2] + arrBuffer[5]; - pCurLine[5 * 8] = arrBuffer[2] - arrBuffer[5]; - pCurLine[3 * 8] = arrBuffer[3] + arrBuffer[4]; - pCurLine[4 * 8] = arrBuffer[3] - arrBuffer[4]; - } - - // convert to 8-bit integers - for (int nIndex = 0; nIndex < 64; ++nIndex) - { - arrDataOut[nIndex] = arrDCTClip[DCTClipOffset + 128 + ((arrDataIn[nIndex] + 8) >> 4)]; - } - } - - int DCTStream::ReadHuffSymbol(DCTHuffTable *pTable) - { - unsigned short nCode = 0; - int nCodeBitsCount = 0; - do { - int nBit = 0; - if ((nBit = ReadBit()) == EOF) - return 9999; - nCode = (nCode << 1) + nBit; - ++nCodeBitsCount; - - if (nCode - pTable->arrunFirstCode[nCodeBitsCount] < pTable->arrunCodesCount[nCodeBitsCount]) - { - nCode -= pTable->arrunFirstCode[nCodeBitsCount]; - return pTable->arrunSymbols[pTable->arrunFirstSymbol[nCodeBitsCount] + nCode]; - } - } while (nCodeBitsCount < 16); - - // TO DO: Error "Bad Huffman code in DCT stream" - return 9999; - } - - int DCTStream::ReadAmp(int nSize) - { - int nAmp = 0; - for (int nBitsCount = 0; nBitsCount < nSize; ++nBitsCount) - { - int nBit = 0; - if ((nBit = ReadBit()) == EOF) - return 9999; - nAmp = (nAmp << 1) + nBit; - } - if (nAmp < (1 << (nSize - 1))) - nAmp -= (1 << nSize) - 1; - return nAmp; - } - - int DCTStream::ReadBit() - { - if (m_nInputBits == 0) - { - int nFirstChar = 0; - if ((nFirstChar = m_pStream->GetChar()) == EOF) - return EOF; - if (nFirstChar == 0xff) - { - int nSecondChar = 0; - do { - nSecondChar = m_pStream->GetChar(); - } while (nSecondChar == 0xff); - if (nSecondChar != 0x00) - { - // TO DO: Error "Bad DCT data: missing 00 after ff" - return EOF; - } - } - m_nInputBuffer = nFirstChar; - m_nInputBits = 8; - } - int nBit = (m_nInputBuffer >> (m_nInputBits - 1)) & 1; - --m_nInputBits; - return nBit; - } - - bool DCTStream::ReadHeader() - { - // Читаем заголовок - bool bDoScan = false; - while (!bDoScan) - { - int nChar = ReadMarker(); - switch (nChar) - { - case 0xc0: // SOF0 (sequential) - case 0xc1: // SOF1 (extended sequential) - if (!ReadBaselineSOF()) - { - return false; - } - break; - case 0xc2: // SOF2 (progressive) - if (!ReadProgressiveSOF()) - { - return false; - } - break; - case 0xc4: // DHT - if (!ReadHuffmanTables()) - { - return false; - } - break; - case 0xd8: // SOI - break; - case 0xd9: // EOI - return false; - case 0xda: // SOS - if (!ReadScanInfo()) - { - return false; - } - bDoScan = true; - break; - case 0xdb: // DQT - if (!ReadQuantTables()) - { - return false; - } - break; - case 0xdd: // DRI - if (!ReadRestartInterval()) - { - return false; - } - break; - case 0xe0: // APP0 - if (!ReadJFIFMarker()) - { - return false; - } - break; - case 0xee: // APP14 - if (!ReadAdobeMarker()) - { - return false; - } - break; - case EOF: - // TO DO : Error "Bad DCT header" - return false; - default: - // Пропускам маркеры типа: APPn, COM и т.д. - if (nChar >= 0xe0) - { - int nCount = Read16() - 2; - for (int nIndex = 0; nIndex < nCount; ++nIndex) - { - m_pStream->GetChar(); - } - } - else - { - // TO DO: Error "Unknown DCT marker" - return false; - } - break; - } - } - - return true; - } - - bool DCTStream::ReadBaselineSOF() - { - int nLength = Read16(); - int nPrecision = m_pStream->GetChar(); - m_nHeight = Read16(); - m_nWidth = Read16(); - m_nComponentsCount = m_pStream->GetChar(); - if (m_nComponentsCount <= 0 || m_nComponentsCount > 4) - { - // TO DO: Error "Bad number of components in DCT stream" - m_nComponentsCount = 0; - return false; - } - if (nPrecision != 8) - { - // TO DO: Error "Bad DCT precision" - return false; - } - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - m_arrCompInfo[nIndex].nID = m_pStream->GetChar(); - int nChar = m_pStream->GetChar(); - m_arrCompInfo[nIndex].nXResolution = (nChar >> 4) & 0x0f; - m_arrCompInfo[nIndex].nYResolution = nChar & 0x0f; - m_arrCompInfo[nIndex].nQuantTableNum = m_pStream->GetChar(); - } - m_bProgressive = false; - return true; - } - - bool DCTStream::ReadProgressiveSOF() - { - int nLength = Read16(); - int ReadProgressiveSOF = m_pStream->GetChar(); - m_nHeight = Read16(); - m_nWidth = Read16(); - m_nComponentsCount = m_pStream->GetChar(); - - if (m_nComponentsCount <= 0 || m_nComponentsCount > 4) - { - // TO DO: Error "Bad number of components in DCT stream" - m_nComponentsCount = 0; - return false; - } - if (ReadProgressiveSOF != 8) - { - // TO DO: Error "Bad DCT precision" - return false; - } - for (int nIndex = 0; nIndex < m_nComponentsCount; ++nIndex) - { - m_arrCompInfo[nIndex].nID = m_pStream->GetChar(); - int nChar = m_pStream->GetChar(); - m_arrCompInfo[nIndex].nXResolution = (nChar >> 4) & 0x0f; - m_arrCompInfo[nIndex].nYResolution = nChar & 0x0f; - m_arrCompInfo[nIndex].nQuantTableNum = m_pStream->GetChar(); - } - m_bProgressive = true; - return true; - } - - bool DCTStream::ReadScanInfo() - { - int nComp = 0; - - int nLength = Read16() - 2; - m_oCurScanInfo.nComponentsCount = m_pStream->GetChar(); - if (m_oCurScanInfo.nComponentsCount <= 0 || m_oCurScanInfo.nComponentsCount > 4) - { - // TO DO: Error "Bad number of components in DCT stream" - m_oCurScanInfo.nComponentsCount = 0; - return false; - } - --nLength; - if (nLength != 2 * m_oCurScanInfo.nComponentsCount + 3) - { - // TO DO: Error "Bad DCT scan info block" - return false; - } - m_bInterleaved = m_oCurScanInfo.nComponentsCount == m_nComponentsCount; - - for (nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - m_oCurScanInfo.arrbComponent[nComp] = false; - } - for (int nIndex = 0; nIndex < m_oCurScanInfo.nComponentsCount; ++nIndex) - { - int nID = m_pStream->GetChar(); - // некоторые(некорректные) DCT потоки используют свои ID числа много раз, но как минимум - // в потоке компоненты идут по порядку, поэтому мы сначала проверяем m_arrCompInfo[i], чтобы - // решить данную пробему - if (nID == m_arrCompInfo[nIndex].nID) - { - nComp = nIndex; - } - else - { - for (nComp = 0; nComp < m_nComponentsCount; ++nComp) - { - if (nID == m_arrCompInfo[nComp].nID) - { - break; - } - } - if (nComp == m_nComponentsCount) - { - // TO DO: Error "Bad DCT component ID in scan info block" - return false; - } - } - m_oCurScanInfo.arrbComponent[nComp] = true; - int nChar = m_pStream->GetChar(); - m_oCurScanInfo.arrDCHuffTable[nComp] = (nChar >> 4) & 0x0f; - m_oCurScanInfo.arrACHuffTable[nComp] = nChar & 0x0f; - } - m_oCurScanInfo.nFirstKoef = m_pStream->GetChar(); - m_oCurScanInfo.nLastKoef = m_pStream->GetChar(); - int nChar = m_pStream->GetChar(); - m_oCurScanInfo.nApproxH = (nChar >> 4) & 0x0f; - m_oCurScanInfo.nApproxL = nChar & 0x0f; - return true; - } - - bool DCTStream::ReadQuantTables() - { - int nLength = Read16() - 2; - while (nLength > 0) - { - int nTableIndex = m_pStream->GetChar(); - int nPrecision = (nTableIndex >> 4) & 0x0f; - nTableIndex &= 0x0f; - if (nPrecision > 1 || nTableIndex >= 4) - { - // TO DO: Error "Bad DCT quantization table" - return false; - } - if (nTableIndex == m_nQuantTablesCount) - { - m_nQuantTablesCount = nTableIndex + 1; - } - for (int nIndex = 0; nIndex < 64; ++nIndex) - { - if (nPrecision) - { - m_arrQuantTables[nTableIndex][arrDCTZigZag[nIndex]] = Read16(); - } - else - { - m_arrQuantTables[nTableIndex][arrDCTZigZag[nIndex]] = m_pStream->GetChar(); - } - } - if (nPrecision) - { - nLength -= 129; - } - else - { - nLength -= 65; - } - } - return true; - } - - bool DCTStream::ReadHuffmanTables() - { - int nLength = Read16() - 2; - - while (nLength > 0) - { - int nTableIndex = m_pStream->GetChar(); - --nLength; - if ((nTableIndex & 0x0f) >= 4) - { - // TO DO: Error "Bad DCT Huffman table" - return false; - } - DCTHuffTable *pTable = NULL; - if (nTableIndex & 0x10) - { - nTableIndex &= 0x0f; - if (nTableIndex >= m_nACHuffTablesCount) - m_nACHuffTablesCount = nTableIndex + 1; - pTable = &m_arrACHuffTables[nTableIndex]; - } - else - { - nTableIndex &= 0x0f; - if (nTableIndex >= m_nDCHuffTablesCount) - m_nDCHuffTablesCount = nTableIndex + 1; - pTable = &m_arrDCHuffTables[nTableIndex]; - } - unsigned char nSymbol = 0; - unsigned short nCode = 0; - for (int nIndex = 1; nIndex <= 16; ++nIndex) - { - int nChar = m_pStream->GetChar(); - pTable->arrunFirstSymbol[nIndex] = nSymbol; - pTable->arrunFirstCode[nIndex] = nCode; - pTable->arrunCodesCount[nIndex] = nChar; - nSymbol += nChar; - nCode = (nCode + nChar) << 1; - } - nLength -= 16; - for (int nIndex = 0; nIndex < nSymbol; ++nIndex) - pTable->arrunSymbols[nIndex] = m_pStream->GetChar(); - nLength -= nSymbol; - } - return true; - } - - bool DCTStream::ReadRestartInterval() - { - int nLength = Read16(); - if (nLength != 4) - { - // TO DO: Error "Bad DCT restart interval" - return false; - } - m_nRestartInterval = Read16(); - return true; - } - - bool DCTStream::ReadJFIFMarker() - { - char sBuffer[5]; - - int nLength = Read16(); - nLength -= 2; - if (nLength >= 5) - { - for (int nIndex = 0; nIndex < 5; ++nIndex) - { - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad DCT APP0 marker" - return false; - } - sBuffer[nIndex] = nChar; - } - nLength -= 5; - if (!memcmp(sBuffer, "JFIF\0", 5)) - { - m_bJFIFMarker = true; - } - } - while (nLength > 0) - { - if (m_pStream->GetChar() == EOF) - { - // TO DO: Error "Bad DCT APP0 marker" - return false; - } - --nLength; - } - return true; - } - - bool DCTStream::ReadAdobeMarker() - { - char sBuffer[12]; - - int nLength = Read16(); - if (nLength < 14) - { - // TO DO: Error "Bad DCT Adobe APP14 marker" - return false; - } - for (int nIndex = 0; nIndex < 12; ++nIndex) - { - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad DCT Adobe APP14 marker" - return false; - } - sBuffer[nIndex] = nChar; - } - if (strncmp(sBuffer, "Adobe", 5)) - { - // TO DO: Error "Bad DCT Adobe APP14 marker" - return false; - } - m_nColorTransform = sBuffer[11]; - m_bAdobeMarker = true; - for (int nIndex = 14; nIndex < nLength; ++nIndex) - { - if (m_pStream->GetChar() == EOF) - { - // TO DO: Error "Bad DCT Adobe APP14 marker" - return false; - } - } - return true; - } - - bool DCTStream::ReadTrailer() - { - int nChar = ReadMarker(); - if (nChar != 0xd9) // EOI - { - // TO DO: Error "Bad DCT trailer" - return false; - } - return true; - } - - int DCTStream::ReadMarker() - { - int nChar = 0; - - do { - do { - nChar = m_pStream->GetChar(); - } while (nChar != 0xff && nChar != EOF); - - do { - nChar = m_pStream->GetChar(); - } while (nChar == 0xff); - } while (nChar == 0x00); - return nChar; - } - - int DCTStream::Read16() - { - int nFirstChar = 0, nSecondChar = 0; - - if ((nFirstChar = m_pStream->GetChar()) == EOF) - return EOF; - if ((nSecondChar = m_pStream->GetChar()) == EOF) - return EOF; - return (nFirstChar << 8) + nSecondChar; - } - - StringExt *DCTStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 2) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("<< >> /DCTDecode filter\n"); - return seResult; - } - - bool DCTStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - //--------------------------------------------------------------------------------------------------------------- - // FlateZlibStream - //--------------------------------------------------------------------------------------------------------------- - - FlateZlibStream::FlateZlibStream(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent) : - FilterStream(pStream) - { - if (1 != nPredictor) - { - m_pPredictor = new StreamPredictor(this, nPredictor, nWidth, nComponents, nBitsPerComponent); - if (!m_pPredictor->CheckValidate()) - { - delete m_pPredictor; - m_pPredictor = NULL; - } - } - else - { - m_pPredictor = NULL; - } - - memset(m_arrInBuffer, 0, flateZlibWindow); - memset(m_arrBuffer, 0, flateZlibWindow); - - m_oZStream.ClearFuncs(); - - m_oZStream.Init(); - } - - FlateZlibStream::~FlateZlibStream() - { - if (m_pPredictor) - { - delete m_pPredictor; - } - delete m_pStream; - - m_oZStream.End(); - } - - void FlateZlibStream::Reset() - { - m_nBufferCurPos = 0; - m_nRemain = 0; - - m_bEndOfBlock = true; - m_bEOF = true; - - m_oZStream.End(); - m_oZStream.ClearFuncs(); - m_oZStream.Init(); - - m_pStream->Reset(); - - m_bEOF = false; - } - - int FlateZlibStream::GetChar() - { - if (m_pPredictor) - { - return m_pPredictor->GetChar(); - } - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - - int nChar = m_arrBuffer[m_nBufferCurPos]; - m_nBufferCurPos = (m_nBufferCurPos + 1) & flateZlibMask; - --m_nRemain; - return nChar; - } - - int FlateZlibStream::LookChar() - { - if (m_pPredictor) - { - return m_pPredictor->LookChar(); - } - - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - int nChar = m_arrBuffer[m_nBufferCurPos]; - return nChar; - } - - int FlateZlibStream::GetRawChar() - { - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - int nChar = m_arrBuffer[m_nBufferCurPos]; - m_nBufferCurPos = (m_nBufferCurPos + 1) & flateZlibMask; - --m_nRemain; - return nChar; - } - - StringExt *FlateZlibStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 3 || m_pPredictor) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("<< >> /FlateDecode filter\n"); - return seResult; - } - - bool FlateZlibStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - void FlateZlibStream::ReadSome() - { - unsigned int unInSize = flateZlibWindow; - if (m_bEndOfBlock) - { - memset(m_arrInBuffer, 0, flateZlibWindow); - int nChar = 0; - for (unsigned int unIndex = 0; unIndex < flateZlibWindow; unIndex++) - { - nChar = m_pStream->GetChar(); - - if (EOF == nChar) - { - unInSize = unIndex; - if (0 == unInSize) - { - m_nRemain = 0; - m_bEndOfBlock = m_bEOF = true; - return; - } - break; - } - - m_arrInBuffer[unIndex] = nChar; - } - - m_oZStream.SetIn(m_arrInBuffer, unInSize); - - m_bEndOfBlock = false; - } - - m_oZStream.SetOut(m_arrBuffer, flateZlibWindow); - - int nRet = m_oZStream.Process(DEFLATE_NO_FLUSH); - - if (nRet == DEFLATE_DATA_ERROR || nRet == DEFLATE_MEM_ERROR) - { - m_nRemain = 0; - m_bEOF = m_bEndOfBlock = true; - return; - } - - m_nRemain = flateZlibWindow - m_oZStream.GetAvailOut(); - - if (m_oZStream.GetAvailOut() != 0) - m_bEndOfBlock = true; - - return; - } - - - //--------------------------------------------------------------------------------------------------------------- - // FlateStream - //--------------------------------------------------------------------------------------------------------------- - - int FlateStream::m_arrCodeLenCodeMap[flateMaxCodeLenCodes] = - { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - FlateDecode FlateStream::m_arrLengthDecode[flateMaxLitCodes - 257] = - { - { 0, 3 }, - { 0, 4 }, - { 0, 5 }, - { 0, 6 }, - { 0, 7 }, - { 0, 8 }, - { 0, 9 }, - { 0, 10 }, - { 1, 11 }, - { 1, 13 }, - { 1, 15 }, - { 1, 17 }, - { 2, 19 }, - { 2, 23 }, - { 2, 27 }, - { 2, 31 }, - { 3, 35 }, - { 3, 43 }, - { 3, 51 }, - { 3, 59 }, - { 4, 67 }, - { 4, 83 }, - { 4, 99 }, - { 4, 115 }, - { 5, 131 }, - { 5, 163 }, - { 5, 195 }, - { 5, 227 }, - { 0, 258 }, - { 0, 258 }, - { 0, 258 } - }; - - FlateDecode FlateStream::m_arrDistanceDecode[flateMaxDistCodes] = - { - { 0, 1 }, - { 0, 2 }, - { 0, 3 }, - { 0, 4 }, - { 1, 5 }, - { 1, 7 }, - { 2, 9 }, - { 2, 13 }, - { 3, 17 }, - { 3, 25 }, - { 4, 33 }, - { 4, 49 }, - { 5, 65 }, - { 5, 97 }, - { 6, 129 }, - { 6, 193 }, - { 7, 257 }, - { 7, 385 }, - { 8, 513 }, - { 8, 769 }, - { 9, 1025 }, - { 9, 1537 }, - { 10, 2049 }, - { 10, 3073 }, - { 11, 4097 }, - { 11, 6145 }, - { 12, 8193 }, - { 12, 12289 }, - { 13, 16385 }, - { 13, 24577 } - }; - - static FlateHuffmanCode c_arrFlateFixedLiteralCodeTableCodes[512] = - { - { 7, 0x0100 }, - { 8, 0x0050 }, - { 8, 0x0010 }, - { 8, 0x0118 }, - { 7, 0x0110 }, - { 8, 0x0070 }, - { 8, 0x0030 }, - { 9, 0x00c0 }, - { 7, 0x0108 }, - { 8, 0x0060 }, - { 8, 0x0020 }, - { 9, 0x00a0 }, - { 8, 0x0000 }, - { 8, 0x0080 }, - { 8, 0x0040 }, - { 9, 0x00e0 }, - { 7, 0x0104 }, - { 8, 0x0058 }, - { 8, 0x0018 }, - { 9, 0x0090 }, - { 7, 0x0114 }, - { 8, 0x0078 }, - { 8, 0x0038 }, - { 9, 0x00d0 }, - { 7, 0x010c }, - { 8, 0x0068 }, - { 8, 0x0028 }, - { 9, 0x00b0 }, - { 8, 0x0008 }, - { 8, 0x0088 }, - { 8, 0x0048 }, - { 9, 0x00f0 }, - { 7, 0x0102 }, - { 8, 0x0054 }, - { 8, 0x0014 }, - { 8, 0x011c }, - { 7, 0x0112 }, - { 8, 0x0074 }, - { 8, 0x0034 }, - { 9, 0x00c8 }, - { 7, 0x010a }, - { 8, 0x0064 }, - { 8, 0x0024 }, - { 9, 0x00a8 }, - { 8, 0x0004 }, - { 8, 0x0084 }, - { 8, 0x0044 }, - { 9, 0x00e8 }, - { 7, 0x0106 }, - { 8, 0x005c }, - { 8, 0x001c }, - { 9, 0x0098 }, - { 7, 0x0116 }, - { 8, 0x007c }, - { 8, 0x003c }, - { 9, 0x00d8 }, - { 7, 0x010e }, - { 8, 0x006c }, - { 8, 0x002c }, - { 9, 0x00b8 }, - { 8, 0x000c }, - { 8, 0x008c }, - { 8, 0x004c }, - { 9, 0x00f8 }, - { 7, 0x0101 }, - { 8, 0x0052 }, - { 8, 0x0012 }, - { 8, 0x011a }, - { 7, 0x0111 }, - { 8, 0x0072 }, - { 8, 0x0032 }, - { 9, 0x00c4 }, - { 7, 0x0109 }, - { 8, 0x0062 }, - { 8, 0x0022 }, - { 9, 0x00a4 }, - { 8, 0x0002 }, - { 8, 0x0082 }, - { 8, 0x0042 }, - { 9, 0x00e4 }, - { 7, 0x0105 }, - { 8, 0x005a }, - { 8, 0x001a }, - { 9, 0x0094 }, - { 7, 0x0115 }, - { 8, 0x007a }, - { 8, 0x003a }, - { 9, 0x00d4 }, - { 7, 0x010d }, - { 8, 0x006a }, - { 8, 0x002a }, - { 9, 0x00b4 }, - { 8, 0x000a }, - { 8, 0x008a }, - { 8, 0x004a }, - { 9, 0x00f4 }, - { 7, 0x0103 }, - { 8, 0x0056 }, - { 8, 0x0016 }, - { 8, 0x011e }, - { 7, 0x0113 }, - { 8, 0x0076 }, - { 8, 0x0036 }, - { 9, 0x00cc }, - { 7, 0x010b }, - { 8, 0x0066 }, - { 8, 0x0026 }, - { 9, 0x00ac }, - { 8, 0x0006 }, - { 8, 0x0086 }, - { 8, 0x0046 }, - { 9, 0x00ec }, - { 7, 0x0107 }, - { 8, 0x005e }, - { 8, 0x001e }, - { 9, 0x009c }, - { 7, 0x0117 }, - { 8, 0x007e }, - { 8, 0x003e }, - { 9, 0x00dc }, - { 7, 0x010f }, - { 8, 0x006e }, - { 8, 0x002e }, - { 9, 0x00bc }, - { 8, 0x000e }, - { 8, 0x008e }, - { 8, 0x004e }, - { 9, 0x00fc }, - { 7, 0x0100 }, - { 8, 0x0051 }, - { 8, 0x0011 }, - { 8, 0x0119 }, - { 7, 0x0110 }, - { 8, 0x0071 }, - { 8, 0x0031 }, - { 9, 0x00c2 }, - { 7, 0x0108 }, - { 8, 0x0061 }, - { 8, 0x0021 }, - { 9, 0x00a2 }, - { 8, 0x0001 }, - { 8, 0x0081 }, - { 8, 0x0041 }, - { 9, 0x00e2 }, - { 7, 0x0104 }, - { 8, 0x0059 }, - { 8, 0x0019 }, - { 9, 0x0092 }, - { 7, 0x0114 }, - { 8, 0x0079 }, - { 8, 0x0039 }, - { 9, 0x00d2 }, - { 7, 0x010c }, - { 8, 0x0069 }, - { 8, 0x0029 }, - { 9, 0x00b2 }, - { 8, 0x0009 }, - { 8, 0x0089 }, - { 8, 0x0049 }, - { 9, 0x00f2 }, - { 7, 0x0102 }, - { 8, 0x0055 }, - { 8, 0x0015 }, - { 8, 0x011d }, - { 7, 0x0112 }, - { 8, 0x0075 }, - { 8, 0x0035 }, - { 9, 0x00ca }, - { 7, 0x010a }, - { 8, 0x0065 }, - { 8, 0x0025 }, - { 9, 0x00aa }, - { 8, 0x0005 }, - { 8, 0x0085 }, - { 8, 0x0045 }, - { 9, 0x00ea }, - { 7, 0x0106 }, - { 8, 0x005d }, - { 8, 0x001d }, - { 9, 0x009a }, - { 7, 0x0116 }, - { 8, 0x007d }, - { 8, 0x003d }, - { 9, 0x00da }, - { 7, 0x010e }, - { 8, 0x006d }, - { 8, 0x002d }, - { 9, 0x00ba }, - { 8, 0x000d }, - { 8, 0x008d }, - { 8, 0x004d }, - { 9, 0x00fa }, - { 7, 0x0101 }, - { 8, 0x0053 }, - { 8, 0x0013 }, - { 8, 0x011b }, - { 7, 0x0111 }, - { 8, 0x0073 }, - { 8, 0x0033 }, - { 9, 0x00c6 }, - { 7, 0x0109 }, - { 8, 0x0063 }, - { 8, 0x0023 }, - { 9, 0x00a6 }, - { 8, 0x0003 }, - { 8, 0x0083 }, - { 8, 0x0043 }, - { 9, 0x00e6 }, - { 7, 0x0105 }, - { 8, 0x005b }, - { 8, 0x001b }, - { 9, 0x0096 }, - { 7, 0x0115 }, - { 8, 0x007b }, - { 8, 0x003b }, - { 9, 0x00d6 }, - { 7, 0x010d }, - { 8, 0x006b }, - { 8, 0x002b }, - { 9, 0x00b6 }, - { 8, 0x000b }, - { 8, 0x008b }, - { 8, 0x004b }, - { 9, 0x00f6 }, - { 7, 0x0103 }, - { 8, 0x0057 }, - { 8, 0x0017 }, - { 8, 0x011f }, - { 7, 0x0113 }, - { 8, 0x0077 }, - { 8, 0x0037 }, - { 9, 0x00ce }, - { 7, 0x010b }, - { 8, 0x0067 }, - { 8, 0x0027 }, - { 9, 0x00ae }, - { 8, 0x0007 }, - { 8, 0x0087 }, - { 8, 0x0047 }, - { 9, 0x00ee }, - { 7, 0x0107 }, - { 8, 0x005f }, - { 8, 0x001f }, - { 9, 0x009e }, - { 7, 0x0117 }, - { 8, 0x007f }, - { 8, 0x003f }, - { 9, 0x00de }, - { 7, 0x010f }, - { 8, 0x006f }, - { 8, 0x002f }, - { 9, 0x00be }, - { 8, 0x000f }, - { 8, 0x008f }, - { 8, 0x004f }, - { 9, 0x00fe }, - { 7, 0x0100 }, - { 8, 0x0050 }, - { 8, 0x0010 }, - { 8, 0x0118 }, - { 7, 0x0110 }, - { 8, 0x0070 }, - { 8, 0x0030 }, - { 9, 0x00c1 }, - { 7, 0x0108 }, - { 8, 0x0060 }, - { 8, 0x0020 }, - { 9, 0x00a1 }, - { 8, 0x0000 }, - { 8, 0x0080 }, - { 8, 0x0040 }, - { 9, 0x00e1 }, - { 7, 0x0104 }, - { 8, 0x0058 }, - { 8, 0x0018 }, - { 9, 0x0091 }, - { 7, 0x0114 }, - { 8, 0x0078 }, - { 8, 0x0038 }, - { 9, 0x00d1 }, - { 7, 0x010c }, - { 8, 0x0068 }, - { 8, 0x0028 }, - { 9, 0x00b1 }, - { 8, 0x0008 }, - { 8, 0x0088 }, - { 8, 0x0048 }, - { 9, 0x00f1 }, - { 7, 0x0102 }, - { 8, 0x0054 }, - { 8, 0x0014 }, - { 8, 0x011c }, - { 7, 0x0112 }, - { 8, 0x0074 }, - { 8, 0x0034 }, - { 9, 0x00c9 }, - { 7, 0x010a }, - { 8, 0x0064 }, - { 8, 0x0024 }, - { 9, 0x00a9 }, - { 8, 0x0004 }, - { 8, 0x0084 }, - { 8, 0x0044 }, - { 9, 0x00e9 }, - { 7, 0x0106 }, - { 8, 0x005c }, - { 8, 0x001c }, - { 9, 0x0099 }, - { 7, 0x0116 }, - { 8, 0x007c }, - { 8, 0x003c }, - { 9, 0x00d9 }, - { 7, 0x010e }, - { 8, 0x006c }, - { 8, 0x002c }, - { 9, 0x00b9 }, - { 8, 0x000c }, - { 8, 0x008c }, - { 8, 0x004c }, - { 9, 0x00f9 }, - { 7, 0x0101 }, - { 8, 0x0052 }, - { 8, 0x0012 }, - { 8, 0x011a }, - { 7, 0x0111 }, - { 8, 0x0072 }, - { 8, 0x0032 }, - { 9, 0x00c5 }, - { 7, 0x0109 }, - { 8, 0x0062 }, - { 8, 0x0022 }, - { 9, 0x00a5 }, - { 8, 0x0002 }, - { 8, 0x0082 }, - { 8, 0x0042 }, - { 9, 0x00e5 }, - { 7, 0x0105 }, - { 8, 0x005a }, - { 8, 0x001a }, - { 9, 0x0095 }, - { 7, 0x0115 }, - { 8, 0x007a }, - { 8, 0x003a }, - { 9, 0x00d5 }, - { 7, 0x010d }, - { 8, 0x006a }, - { 8, 0x002a }, - { 9, 0x00b5 }, - { 8, 0x000a }, - { 8, 0x008a }, - { 8, 0x004a }, - { 9, 0x00f5 }, - { 7, 0x0103 }, - { 8, 0x0056 }, - { 8, 0x0016 }, - { 8, 0x011e }, - { 7, 0x0113 }, - { 8, 0x0076 }, - { 8, 0x0036 }, - { 9, 0x00cd }, - { 7, 0x010b }, - { 8, 0x0066 }, - { 8, 0x0026 }, - { 9, 0x00ad }, - { 8, 0x0006 }, - { 8, 0x0086 }, - { 8, 0x0046 }, - { 9, 0x00ed }, - { 7, 0x0107 }, - { 8, 0x005e }, - { 8, 0x001e }, - { 9, 0x009d }, - { 7, 0x0117 }, - { 8, 0x007e }, - { 8, 0x003e }, - { 9, 0x00dd }, - { 7, 0x010f }, - { 8, 0x006e }, - { 8, 0x002e }, - { 9, 0x00bd }, - { 8, 0x000e }, - { 8, 0x008e }, - { 8, 0x004e }, - { 9, 0x00fd }, - { 7, 0x0100 }, - { 8, 0x0051 }, - { 8, 0x0011 }, - { 8, 0x0119 }, - { 7, 0x0110 }, - { 8, 0x0071 }, - { 8, 0x0031 }, - { 9, 0x00c3 }, - { 7, 0x0108 }, - { 8, 0x0061 }, - { 8, 0x0021 }, - { 9, 0x00a3 }, - { 8, 0x0001 }, - { 8, 0x0081 }, - { 8, 0x0041 }, - { 9, 0x00e3 }, - { 7, 0x0104 }, - { 8, 0x0059 }, - { 8, 0x0019 }, - { 9, 0x0093 }, - { 7, 0x0114 }, - { 8, 0x0079 }, - { 8, 0x0039 }, - { 9, 0x00d3 }, - { 7, 0x010c }, - { 8, 0x0069 }, - { 8, 0x0029 }, - { 9, 0x00b3 }, - { 8, 0x0009 }, - { 8, 0x0089 }, - { 8, 0x0049 }, - { 9, 0x00f3 }, - { 7, 0x0102 }, - { 8, 0x0055 }, - { 8, 0x0015 }, - { 8, 0x011d }, - { 7, 0x0112 }, - { 8, 0x0075 }, - { 8, 0x0035 }, - { 9, 0x00cb }, - { 7, 0x010a }, - { 8, 0x0065 }, - { 8, 0x0025 }, - { 9, 0x00ab }, - { 8, 0x0005 }, - { 8, 0x0085 }, - { 8, 0x0045 }, - { 9, 0x00eb }, - { 7, 0x0106 }, - { 8, 0x005d }, - { 8, 0x001d }, - { 9, 0x009b }, - { 7, 0x0116 }, - { 8, 0x007d }, - { 8, 0x003d }, - { 9, 0x00db }, - { 7, 0x010e }, - { 8, 0x006d }, - { 8, 0x002d }, - { 9, 0x00bb }, - { 8, 0x000d }, - { 8, 0x008d }, - { 8, 0x004d }, - { 9, 0x00fb }, - { 7, 0x0101 }, - { 8, 0x0053 }, - { 8, 0x0013 }, - { 8, 0x011b }, - { 7, 0x0111 }, - { 8, 0x0073 }, - { 8, 0x0033 }, - { 9, 0x00c7 }, - { 7, 0x0109 }, - { 8, 0x0063 }, - { 8, 0x0023 }, - { 9, 0x00a7 }, - { 8, 0x0003 }, - { 8, 0x0083 }, - { 8, 0x0043 }, - { 9, 0x00e7 }, - { 7, 0x0105 }, - { 8, 0x005b }, - { 8, 0x001b }, - { 9, 0x0097 }, - { 7, 0x0115 }, - { 8, 0x007b }, - { 8, 0x003b }, - { 9, 0x00d7 }, - { 7, 0x010d }, - { 8, 0x006b }, - { 8, 0x002b }, - { 9, 0x00b7 }, - { 8, 0x000b }, - { 8, 0x008b }, - { 8, 0x004b }, - { 9, 0x00f7 }, - { 7, 0x0103 }, - { 8, 0x0057 }, - { 8, 0x0017 }, - { 8, 0x011f }, - { 7, 0x0113 }, - { 8, 0x0077 }, - { 8, 0x0037 }, - { 9, 0x00cf }, - { 7, 0x010b }, - { 8, 0x0067 }, - { 8, 0x0027 }, - { 9, 0x00af }, - { 8, 0x0007 }, - { 8, 0x0087 }, - { 8, 0x0047 }, - { 9, 0x00ef }, - { 7, 0x0107 }, - { 8, 0x005f }, - { 8, 0x001f }, - { 9, 0x009f }, - { 7, 0x0117 }, - { 8, 0x007f }, - { 8, 0x003f }, - { 9, 0x00df }, - { 7, 0x010f }, - { 8, 0x006f }, - { 8, 0x002f }, - { 9, 0x00bf }, - { 8, 0x000f }, - { 8, 0x008f }, - { 8, 0x004f }, - { 9, 0x00ff } - }; - - FlateHuffmanTable FlateStream::m_oFixedLiteralCodeTable = - { - c_arrFlateFixedLiteralCodeTableCodes, 9 - }; - - static FlateHuffmanCode c_arrFlateFixedDistanceCodeTableCodes[32] = - { - { 5, 0x0000 }, - { 5, 0x0010 }, - { 5, 0x0008 }, - { 5, 0x0018 }, - { 5, 0x0004 }, - { 5, 0x0014 }, - { 5, 0x000c }, - { 5, 0x001c }, - { 5, 0x0002 }, - { 5, 0x0012 }, - { 5, 0x000a }, - { 5, 0x001a }, - { 5, 0x0006 }, - { 5, 0x0016 }, - { 5, 0x000e }, - { 0, 0x0000 }, - { 5, 0x0001 }, - { 5, 0x0011 }, - { 5, 0x0009 }, - { 5, 0x0019 }, - { 5, 0x0005 }, - { 5, 0x0015 }, - { 5, 0x000d }, - { 5, 0x001d }, - { 5, 0x0003 }, - { 5, 0x0013 }, - { 5, 0x000b }, - { 5, 0x001b }, - { 5, 0x0007 }, - { 5, 0x0017 }, - { 5, 0x000f }, - { 0, 0x0000 } - }; - - FlateHuffmanTable FlateStream::m_oFixedDistanceCodeTable = - { - c_arrFlateFixedDistanceCodeTableCodes, 5 - }; - - FlateStream::FlateStream(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent) : - FilterStream(pStream) - { - if (1 != nPredictor) - { - m_pPredictor = new StreamPredictor(this, nPredictor, nWidth, nComponents, nBitsPerComponent); - if (!m_pPredictor->CheckValidate()) - { - delete m_pPredictor; - m_pPredictor = NULL; - } - } - else - { - m_pPredictor = NULL; - } - m_oLiteratCodeTable.pCodes = NULL; - m_oDistanceCodeTable.pCodes = NULL; - - memset(m_arrBuffer, 0, flateWindow); - } - - FlateStream::~FlateStream() - { - if (m_oLiteratCodeTable.pCodes != m_oFixedLiteralCodeTable.pCodes) - { - MemUtilsFree(m_oLiteratCodeTable.pCodes); - } - if (m_oDistanceCodeTable.pCodes != m_oFixedDistanceCodeTable.pCodes) - { - MemUtilsFree(m_oDistanceCodeTable.pCodes); - } - if (m_pPredictor) - { - delete m_pPredictor; - } - delete m_pStream; - } - - void FlateStream::Reset() - { - m_nBufferCurPos = 0; - m_nRemain = 0; - m_nCodeBuffer = 0; - m_nCodeSize = 0; - m_bCompressedBlock = false; - m_bEndOfBlock = true; - m_bEOF = true; - - m_pStream->Reset(); - - m_bEndOfBlock = m_bEOF = true; - - //читаем заголовок - int nCmf = m_pStream->GetChar(); - int nFlag = m_pStream->GetChar(); - if (nCmf == EOF || nFlag == EOF) - return; - if ((nCmf & 0x0f) != 0x08) - { - //TO DO: Error "Unknown compression method in flate stream" - return; - } - if ((((nCmf << 8) + nFlag) % 31) != 0) - { - // TO DO: Error "Bad FCHECK in flate stream" - return; - } - if (nFlag & 0x20) - { - //TO DO: Error "FDICT bit set in flate stream" - return; - } - - m_bEOF = false; - } - - int FlateStream::GetChar() - { - if (m_pPredictor) - { - return m_pPredictor->GetChar(); - } - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - - int nChar = m_arrBuffer[m_nBufferCurPos]; - m_nBufferCurPos = (m_nBufferCurPos + 1) & flateMask; - --m_nRemain; - return nChar; - } - - int FlateStream::LookChar() - { - if (m_pPredictor) - { - return m_pPredictor->LookChar(); - } - - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - int nChar = m_arrBuffer[m_nBufferCurPos]; - return nChar; - } - - int FlateStream::GetRawChar() - { - while (m_nRemain == 0) - { - if (m_bEndOfBlock && m_bEOF) - return EOF; - ReadSome(); - } - int nChar = m_arrBuffer[m_nBufferCurPos]; - m_nBufferCurPos = (m_nBufferCurPos + 1) & flateMask; - --m_nRemain; - return nChar; - } - - StringExt *FlateStream::GetPSFilter(int nPSLevel, char *sIndent) - { - StringExt *seResult; - - if (nPSLevel < 3 || m_pPredictor) - { - return NULL; - } - if (!(seResult = m_pStream->GetPSFilter(nPSLevel, sIndent))) - { - return NULL; - } - seResult->Append(sIndent)->Append("<< >> /FlateDecode filter\n"); - return seResult; - } - - bool FlateStream::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - void FlateStream::ReadSome() - { - int nFirst = 0, nSecond = 0; - - if (m_bEndOfBlock) - { - if (!StartBlock()) - return; - } - - if (m_bCompressedBlock) - { - int nHuffCode = 0; - if ((nHuffCode = GetHuffmanCodeWord(&m_oLiteratCodeTable)) == EOF) - { - // TO DO: Error "Unexpected end of file in flate stream" - m_bEndOfBlock = m_bEOF = true; - m_nRemain = 0; - } - if (nHuffCode < 256) - { - m_arrBuffer[m_nBufferCurPos] = nHuffCode; - m_nRemain = 1; - } - else if (nHuffCode == 256) - { - m_bEndOfBlock = true; - m_nRemain = 0; - } - else - { - nHuffCode -= 257; - int nExtraCode = m_arrLengthDecode[nHuffCode].nExtraBitsCount; - if (nExtraCode > 0 && (nExtraCode = GetCodeWord(nExtraCode)) == EOF) - { - // TO DO: Error "Unexpected end of file in flate stream" - m_bEndOfBlock = m_bEOF = true; - m_nRemain = 0; - } - int nLen = m_arrLengthDecode[nHuffCode].nFirst + nExtraCode; - if ((nHuffCode = GetHuffmanCodeWord(&m_oDistanceCodeTable)) == EOF) - { - // TO DO: Error "Unexpected end of file in flate stream" - m_bEndOfBlock = m_bEOF = true; - m_nRemain = 0; - } - nExtraCode = m_arrDistanceDecode[nHuffCode].nExtraBitsCount; - if (nExtraCode > 0 && (nExtraCode = GetCodeWord(nExtraCode)) == EOF) - { - // TO DO: Error "Unexpected end of file in flate stream" - m_bEndOfBlock = m_bEOF = true; - m_nRemain = 0; - } - int nDistance = m_arrDistanceDecode[nHuffCode].nFirst + nExtraCode; - nFirst = m_nBufferCurPos; - nSecond = (m_nBufferCurPos - nDistance) & flateMask; - for (int nK = 0; nK < nLen; ++nK) - { - m_arrBuffer[nFirst] = m_arrBuffer[nSecond]; - nFirst = (nFirst + 1) & flateMask; - nSecond = (nSecond + 1) & flateMask; - } - m_nRemain = nLen; - } - } - else - { - int nLen = (m_nUncompBlockLen < flateWindow) ? m_nUncompBlockLen : flateWindow; - for (nFirst = 0, nSecond = m_nBufferCurPos; nFirst < nLen; ++nFirst, nSecond = (nSecond + 1) & flateMask) - { - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - m_bEndOfBlock = m_bEOF = true; - break; - } - m_arrBuffer[nSecond] = nChar & 0xff; - } - m_nRemain = nFirst; - m_nUncompBlockLen -= nLen; - if (m_nUncompBlockLen == 0) - m_bEndOfBlock = true; - } - return; - } - - bool FlateStream::StartBlock() - { - // Освобождаем таблицы кодов из предыдущего блока - if (m_oLiteratCodeTable.pCodes != m_oFixedLiteralCodeTable.pCodes) - { - MemUtilsFree(m_oLiteratCodeTable.pCodes); - } - m_oLiteratCodeTable.pCodes = NULL; - if (m_oDistanceCodeTable.pCodes != m_oFixedDistanceCodeTable.pCodes) - { - MemUtilsFree(m_oDistanceCodeTable.pCodes); - } - m_oDistanceCodeTable.pCodes = NULL; - - // Считываем заголовок блока - int nBlockHeader = GetCodeWord(3); - if (nBlockHeader & 1) - m_bEOF = true; - - nBlockHeader >>= 1; - - if (nBlockHeader == 0) // uncompressed block - { - m_bCompressedBlock = false; - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - m_nUncompBlockLen = nChar & 0xff; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - m_nUncompBlockLen |= (nChar & 0xff) << 8; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - int nCheck = nChar & 0xff; - if ((nChar = m_pStream->GetChar()) == EOF) - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - nCheck |= (nChar & 0xff) << 8; - if (nCheck != (~m_nUncompBlockLen & 0xffff)) - { - // TO DO: Error "Bad uncompressed block length in flate stream" - } - m_nCodeBuffer = 0; - m_nCodeSize = 0; - } - else if (nBlockHeader == 1) // compressed block with fixed codes - { - m_bCompressedBlock = true; - LoadFixedCodes(); - } - else if (nBlockHeader == 2) // compressed block with dynamic codes - { - m_bCompressedBlock = true; - if (!ReadDynamicCodes()) - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - } - else // unknown block type - { - // TO DO: Error "Bad block header in flate stream" - m_bEndOfBlock = m_bEOF = true; - return false; - } - - m_bEndOfBlock = false; - return true; - } - - void FlateStream::LoadFixedCodes() - { - m_oLiteratCodeTable.pCodes = m_oFixedLiteralCodeTable.pCodes; - m_oLiteratCodeTable.nMaxLen = m_oFixedLiteralCodeTable.nMaxLen; - m_oDistanceCodeTable.pCodes = m_oFixedDistanceCodeTable.pCodes; - m_oDistanceCodeTable.nMaxLen = m_oFixedDistanceCodeTable.nMaxLen; - } - - bool FlateStream::ReadDynamicCodes() - { - int arrCodeLenCodeLengths[flateMaxCodeLenCodes]; - FlateHuffmanTable oCodeLenCodeTable; - - oCodeLenCodeTable.pCodes = NULL; - - // Lengths - int nNumLiteralCodes = 0; - if ((nNumLiteralCodes = GetCodeWord(5)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nNumLiteralCodes += 257; - - int nNumDistanceCodes = 0; - if ((nNumDistanceCodes = GetCodeWord(5)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nNumDistanceCodes += 1; - - int nNumCodeLenCodes = 0; - if ((nNumCodeLenCodes = GetCodeWord(4)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nNumCodeLenCodes += 4; - - if (nNumLiteralCodes > flateMaxLitCodes || nNumDistanceCodes > flateMaxDistCodes || nNumCodeLenCodes > flateMaxCodeLenCodes) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - - // code length code table - for (int nI = 0; nI < flateMaxCodeLenCodes; ++nI) - { - arrCodeLenCodeLengths[nI] = 0; - } - for (int nI = 0; nI < nNumCodeLenCodes; ++nI) - { - if ((arrCodeLenCodeLengths[m_arrCodeLenCodeMap[nI]] = GetCodeWord(3)) == -1) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - } - ConvertHuffmanCodes(arrCodeLenCodeLengths, flateMaxCodeLenCodes, &oCodeLenCodeTable); - - // Literal, distance code tables - int nLen = 0; - int nRepeat = 0; - int nIndex = 0; - int nCurCode = 0; - while (nIndex < nNumLiteralCodes + nNumDistanceCodes) - { - if ((nCurCode = GetHuffmanCodeWord(&oCodeLenCodeTable)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - if (nCurCode == 16) - { - if ((nRepeat = GetCodeWord(2)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nRepeat += 3; - if (nIndex + nRepeat > nNumLiteralCodes + nNumDistanceCodes) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - for (; nRepeat > 0; --nRepeat) - { - m_arrCodeLengths[nIndex++] = nLen; - } - } - else if (nCurCode == 17) - { - if ((nRepeat = GetCodeWord(3)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nRepeat += 3; - if (nIndex + nRepeat > nNumLiteralCodes + nNumDistanceCodes) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nLen = 0; - for (; nRepeat > 0; --nRepeat) - { - m_arrCodeLengths[nIndex++] = 0; - } - } - else if (nCurCode == 18) - { - if ((nRepeat = GetCodeWord(7)) == EOF) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nRepeat += 11; - if (nIndex + nRepeat > nNumLiteralCodes + nNumDistanceCodes) - { - // TO DO: Error "Bad dynamic code table in flate stream" - MemUtilsFree(oCodeLenCodeTable.pCodes); - return false; - } - nLen = 0; - for (; nRepeat > 0; --nRepeat) - { - m_arrCodeLengths[nIndex++] = 0; - } - } - else - { - m_arrCodeLengths[nIndex++] = nLen = nCurCode; - } - } - ConvertHuffmanCodes(m_arrCodeLengths, nNumLiteralCodes, &m_oLiteratCodeTable); - ConvertHuffmanCodes(m_arrCodeLengths + nNumLiteralCodes, nNumDistanceCodes, &m_oDistanceCodeTable); - - MemUtilsFree(oCodeLenCodeTable.pCodes); - return true; - } - - // Конвертируем массив , в таблицу Хаффмана(сортируя по значениям) - void FlateStream::ConvertHuffmanCodes(int *pLengths, int nCount, FlateHuffmanTable *pTable) - { - // Ищем макимальный элемент - pTable->nMaxLen = 0; - for (int nValue = 0; nValue < nCount; ++nValue) - { - if (pLengths[nValue] > pTable->nMaxLen) - { - pTable->nMaxLen = pLengths[nValue]; - } - } - - // Выделяем место для таблицы - int nTableSize = 1 << pTable->nMaxLen; - pTable->pCodes = (FlateHuffmanCode *)MemUtilsMallocArray(nTableSize, sizeof(FlateHuffmanCode)); - - // Очищаем таблицу - for (int nIndex = 0; nIndex < nTableSize; ++nIndex) - { - pTable->pCodes[nIndex].nLength = 0; - pTable->pCodes[nIndex].nValue = 0; - } - - // Заполняем таблицу - int nLen = 0, nSkip = 0, nCode = 0; - for (nLen = 1, nCode = 0, nSkip = 2; nLen <= pTable->nMaxLen; ++nLen, nCode <<= 1, nSkip <<= 1) - { - for (int nValue = 0; nValue < nCount; ++nValue) - { - if (pLengths[nValue] == nLen) - { - // bit-reverse code - int nReverseCode = 0; - int nTemp = nCode; - for (int nIndex = 0; nIndex < nLen; ++nIndex) - { - nReverseCode = (nReverseCode << 1) | (nTemp & 1); - nTemp >>= 1; - } - - for (int nIndex = nReverseCode; nIndex < nTableSize; nIndex += nSkip) - { - pTable->pCodes[nIndex].nLength = (unsigned short)nLen; - pTable->pCodes[nIndex].nValue = (unsigned short)nValue; - } - ++nCode; - } - } - } - } - - int FlateStream::GetHuffmanCodeWord(FlateHuffmanTable *pTable) - { - while (m_nCodeSize < pTable->nMaxLen) - { - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - break; - } - m_nCodeBuffer |= (nChar & 0xff) << m_nCodeSize; - m_nCodeSize += 8; - } - FlateHuffmanCode *pHuffCode = &pTable->pCodes[m_nCodeBuffer & ((1 << pTable->nMaxLen) - 1)]; - if (m_nCodeSize == 0 || m_nCodeSize < pHuffCode->nLength || pHuffCode->nLength == 0) - { - return EOF; - } - m_nCodeBuffer >>= pHuffCode->nLength; - m_nCodeSize -= pHuffCode->nLength; - return (int)pHuffCode->nValue; - } - - int FlateStream::GetCodeWord(int nBits) - { - int nChar = 0; - while (m_nCodeSize < nBits) - { - if ((nChar = m_pStream->GetChar()) == EOF) - return EOF; - m_nCodeBuffer |= (nChar & 0xff) << m_nCodeSize; - m_nCodeSize += 8; - } - nChar = m_nCodeBuffer & ((1 << nBits) - 1); - m_nCodeBuffer >>= nBits; - m_nCodeSize -= nBits; - return nChar; - } - - //--------------------------------------------------------------------------------------------------------------- - // EOFStream - //--------------------------------------------------------------------------------------------------------------- - - EOFStream::EOFStream(Stream *pStream) : - FilterStream(pStream) - { - } - - EOFStream::~EOFStream() - { - delete m_pStream; - } - - //--------------------------------------------------------------------------------------------------------------- - // FixedLengthEncoder - //--------------------------------------------------------------------------------------------------------------- - - FixedLengthEncoder::FixedLengthEncoder(Stream *pStream, int nLength) : - FilterStream(pStream) - { - m_nLength = nLength; - m_nCount = 0; - } - - FixedLengthEncoder::~FixedLengthEncoder() - { - if (m_pStream->IsEncoder()) - delete m_pStream; - } - - void FixedLengthEncoder::Reset() - { - m_pStream->Reset(); - m_nCount = 0; - } - - int FixedLengthEncoder::GetChar() - { - if (m_nLength >= 0 && m_nCount >= m_nLength) - return EOF; - ++m_nCount; - return m_pStream->GetChar(); - } - - int FixedLengthEncoder::LookChar() - { - if (m_nLength >= 0 && m_nCount >= m_nLength) - return EOF; - return m_pStream->GetChar(); - } - - bool FixedLengthEncoder::IsBinary(bool bLast) - { - return m_pStream->IsBinary(true); - } - - //--------------------------------------------------------------------------------------------------------------- - // ASCIIHexEncoder - //--------------------------------------------------------------------------------------------------------------- - - ASCIIHexEncoder::ASCIIHexEncoder(Stream *pStream) : - FilterStream(pStream) - { - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_nLineLength = 0; - m_bEOF = false; - } - - ASCIIHexEncoder::~ASCIIHexEncoder() - { - if (m_pStream->IsEncoder()) - delete m_pStream; - } - - void ASCIIHexEncoder::Reset() - { - m_pStream->Reset(); - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_nLineLength = 0; - m_bEOF = false; - } - - bool ASCIIHexEncoder::FillBuffer() - { - static char *c_sHex = "0123456789abcdef"; - - if (m_bEOF) - { - return false; - } - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - - int nChar = 0; - if ((nChar = m_pStream->GetChar()) == EOF) - { - *m_pBufferEnd++ = '>'; - m_bEOF = true; - } - else - { - if (m_nLineLength >= 64) - { - *m_pBufferEnd++ = '\n'; - m_nLineLength = 0; - } - *m_pBufferEnd++ = c_sHex[(nChar >> 4) & 0x0f]; - *m_pBufferEnd++ = c_sHex[nChar & 0x0f]; - m_nLineLength += 2; - } - return true; - } - - //--------------------------------------------------------------------------------------------------------------- - // ASCII85Encoder - //--------------------------------------------------------------------------------------------------------------- - - ASCII85Encoder::ASCII85Encoder(Stream *pStream) : - FilterStream(pStream) - { - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_nLineLength = 0; - m_bEOF = false; - } - - ASCII85Encoder::~ASCII85Encoder() - { - if (m_pStream->IsEncoder()) - delete m_pStream; - } - - void ASCII85Encoder::Reset() - { - m_pStream->Reset(); - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - m_nLineLength = 0; - m_bEOF = false; - } - - bool ASCII85Encoder::FillBuffer() - { - unsigned long unTemp = 0; - char arrB[5]; - int arrC[4] ={ 0, 0, 0, 0 }; - int nLen = 0; - - if (m_bEOF) - { - return false; - } - arrC[0] = m_pStream->GetChar(); - arrC[1] = m_pStream->GetChar(); - arrC[2] = m_pStream->GetChar(); - arrC[3] = m_pStream->GetChar(); - m_pBufferPointer = m_pBufferEnd = m_sBuffer; - if (arrC[3] == EOF) - { - if (arrC[0] == EOF) - { - nLen = 0; - unTemp = 0; - } - else - { - if (arrC[1] == EOF) - { - nLen = 1; - unTemp = arrC[0] << 24; - } - else if (arrC[2] == EOF) - { - nLen = 2; - unTemp = (arrC[0] << 24) | (arrC[1] << 16); - } - else - { - nLen = 3; - unTemp = (arrC[0] << 24) | (arrC[1] << 16) | (arrC[2] << 8); - } - for (int nIndex = 4; nIndex >= 0; --nIndex) - { - arrB[nIndex] = (char)(unTemp % 85 + 0x21); - unTemp /= 85; - } - for (int nIndex = 0; nIndex <= nLen; ++nIndex) - { - *m_pBufferEnd++ = arrB[nIndex]; - if (++m_nLineLength == 65) - { - *m_pBufferEnd++ = '\n'; - m_nLineLength = 0; - } - } - } - *m_pBufferEnd++ = '~'; - *m_pBufferEnd++ = '>'; - m_bEOF = true; - } - else - { - unTemp = (arrC[0] << 24) | (arrC[1] << 16) | (arrC[2] << 8) | arrC[3]; - if (unTemp == 0) - { - *m_pBufferEnd++ = 'z'; - if (++m_nLineLength == 65) - { - *m_pBufferEnd++ = '\n'; - m_nLineLength = 0; - } - } - else - { - for (int nIndex = 4; nIndex >= 0; --nIndex) - { - arrB[nIndex] = (char)(unTemp % 85 + 0x21); - unTemp /= 85; - } - for (int nIndex = 0; nIndex <= 4; ++nIndex) - { - *m_pBufferEnd++ = arrB[nIndex]; - if (++m_nLineLength == 65) - { - *m_pBufferEnd++ = '\n'; - m_nLineLength = 0; - } - } - } - } - return true; - } - - //--------------------------------------------------------------------------------------------------------------- - // RunLengthEncoder - //--------------------------------------------------------------------------------------------------------------- - - RunLengthEncoder::RunLengthEncoder(Stream *pStream) : - FilterStream(pStream) - { - m_pBufferPointer = m_pBufferEnd = m_pNextEnd = m_sBuffer; - m_bEOF = false; - } - - RunLengthEncoder::~RunLengthEncoder() - { - if (m_pStream->IsEncoder()) - delete m_pStream; - } - - void RunLengthEncoder::Reset() - { - m_pStream->Reset(); - m_pBufferPointer = m_pBufferEnd = m_pNextEnd = m_sBuffer; - m_bEOF = false; - } - - // - // После выполнения функции FillBuffer, m_sBuffer[] выглядит следующим образом: - // +-----+--------------+-----------------+-- - // + tag | ... data ... | next 0, 1, or 2 | - // +-----+--------------+-----------------+-- - // ^ ^ ^ - // m_pBufferPointer m_pBufferEnd m_pNextEnd - // - bool RunLengthEncoder::FillBuffer() - { - if (m_bEOF) - return false; - - // считываем два байта - int nChar1 = 0, nChar2 = 0; - if (m_pNextEnd < m_pBufferEnd + 1) - { - if ((nChar1 = m_pStream->GetChar()) == EOF) - { - m_bEOF = true; - return false; - } - } - else - { - nChar1 = m_pBufferEnd[0] & 0xff; - } - if (m_pNextEnd < m_pBufferEnd + 2) - { - if ((nChar2 = m_pStream->GetChar()) == EOF) - { - m_bEOF = true; - m_sBuffer[0] = 0; - m_sBuffer[1] = nChar1; - m_pBufferPointer = m_sBuffer; - m_pBufferEnd = &m_sBuffer[2]; - return true; - } - } - else - { - nChar2 = m_pBufferEnd[1] & 0xff; - } - - int nChar = 0; - if (nChar1 == nChar2) - { - int nLen = 2; - while (nLen < 128 && (nChar = m_pStream->GetChar()) == nChar1) - ++nLen; - m_sBuffer[0] = (char)(257 - nLen); - m_sBuffer[1] = nChar1; - m_pBufferEnd = &m_sBuffer[2]; - if (nChar == EOF) - { - m_bEOF = true; - } - else if (nLen < 128) - { - m_sBuffer[2] = nChar; - m_pNextEnd = &m_sBuffer[3]; - } - else - { - m_pNextEnd = m_pBufferEnd; - } - - - } - else - { - m_sBuffer[1] = nChar1; - m_sBuffer[2] = nChar2; - int nLen = 2; - while (nLen < 128) - { - if ((nChar = m_pStream->GetChar()) == EOF) - { - m_bEOF = true; - break; - } - ++nLen; - m_sBuffer[nLen] = nChar; - if (m_sBuffer[nLen] == m_sBuffer[nLen - 1]) - break; - } - if (m_sBuffer[nLen] == m_sBuffer[nLen - 1]) - { - m_sBuffer[0] = (char)(nLen - 2 - 1); - m_pBufferEnd = &m_sBuffer[nLen - 1]; - m_pNextEnd = &m_sBuffer[nLen + 1]; - } - else - { - m_sBuffer[0] = (char)(nLen - 1); - m_pBufferEnd = m_pNextEnd = &m_sBuffer[nLen + 1]; - } - } - m_pBufferPointer = m_sBuffer; - return true; - } -} diff --git a/PdfReader/old/Stream.h b/PdfReader/old/Stream.h deleted file mode 100644 index caee0c2d20..0000000000 --- a/PdfReader/old/Stream.h +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_STREAM_H -#define _PDF_READER_STREAM_H - -#include -#include "Object.h" -#include "../../OfficeUtils/src/OfficeUtils.h" - -namespace PdfReader -{ - class BaseStream; - - //------------------------------------------------------------------------ - - enum StreamType - { - strFile, - strASCIIHex, - strASCII85, - strLZW, - strRunLength, - strCCITTFax, - strDCT, - strFlate, - strJBIG2, - strJPX, - strWeird // internal-use stream types - }; - - enum StreamColorSpaceMode - { - streamCSNone, - streamCSDeviceGray, - streamCSDeviceRGB, - streamCSDeviceCMYK - }; - - //------------------------------------------------------------------------ - - enum CryptAlgorithm - { - cryptRC4, - cryptAES128, - cryptAES256 - }; - - //------------------------------------------------------------------------ - // Stream (основной класс) - //------------------------------------------------------------------------ - - class Stream - { - public: - - Stream(); - - virtual ~Stream(); - - // Счетчик ссылок. - int AddRef() - { - return ++m_nRef; - } - int Release() - { - return --m_nRef; - } - - // Тип потока. - virtual StreamType GetType() = 0; - - // Сбрасываем все параметры(к начальным). - virtual void Reset() = 0; - - // Закрываем поток. - virtual void Close(); - - // Передвигаемся к следующему символу в потоке. - virtual int GetChar() = 0; - - // Смотрим на следующий символ в потоке. - virtual int LookChar() = 0; - - // GetChar буз использования Predictor. - // Используется только в StreamPredictor. - virtual int GetRawChar(); - - // Следующая строка в потоке. - virtual char *GetLine(char *sBuffer, int nSize); - - // Текущая позиция в потоке. - virtual int GetPos() = 0; - - // Устанавливаем текущую позицию в потоке. Если nDirection - - // отрицательно, тогда позицию отсчитваем от конца потока, а - // если положительно, тогда от начала. - virtual void SetPos(unsigned int unPos, int nDirection = 0) = 0; - - // PostScript'ое название фильтра. - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - - // Может ли поток содержать непечатыемые символы? - virtual bool IsBinary(bool bLast = true) = 0; - - virtual BaseStream *GetBaseStream() = 0; - - // Поток после последнего декодирования (это может быть BaseStream - // или DecryptStream). - virtual Stream *GetUndecodedStream() = 0; - - // Словарь связанный с данным потоком. - virtual Dict *GetDict() = 0; - - // Encoding filter? - virtual bool IsEncoder() - { - return false; - } - - // Получить параметры изображения, определенного содержимым данного потока. - virtual void GetImageParams(int *pnBitsPerComponent, StreamColorSpaceMode *peCSMode) - { - } - - // Возвращется следующий поток из стека. - virtual Stream *GetNextStream() - { - return NULL; - } - - // Применяем фильтры к данному потоку, описанные в параметрах словаря. - // Возвращается новый поток. - Stream *AddFilters(Object *pDict); - - private: - - Stream *ApplyFilter(char *sName, Stream *pStream, Object *pParams); - - private: - - int m_nRef; // счетчик ссылок - - }; - - //------------------------------------------------------------------------ - // BaseStream - // - // Это основной класс для всех потоков и чтения из файла. - //------------------------------------------------------------------------ - - class BaseStream : public Stream - { - public: - - BaseStream(Object *pDict); - virtual ~BaseStream(); - virtual Stream *MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict) = 0; - virtual void SetPos(unsigned int unPos, int nDirection = 0) = 0; - virtual bool IsBinary(bool bLast = true) - { - return bLast; - } - virtual BaseStream *GetBaseStream() - { - return this; - } - virtual Stream *GetUndecodedStream() - { - return this; - } - virtual Dict *GetDict() - { - return m_pDict.GetDict(); - } - virtual StringExt *GetFileName() - { - return NULL; - } - - // Запрашиваем/устанавливаем позицию первого байта в потоке файла. - virtual unsigned int GetStartPos() = 0; - virtual void SetStartPos(int nDelta) = 0; - - private: - - Object m_pDict; - }; - - //------------------------------------------------------------------------ - // FilterStream - // - // Это основной класс для всех потоков, к которым примене фильтр. - //------------------------------------------------------------------------ - - class FilterStream : public Stream - { - public: - - FilterStream(Stream *pStream); - virtual ~FilterStream(); - virtual void Close(); - virtual int GetPos() - { - return m_pStream->GetPos(); - } - virtual void SetPos(unsigned int unPos, int nDirection = 0); - virtual BaseStream *GetBaseStream() - { - return m_pStream->GetBaseStream(); - } - virtual Stream *GetUndecodedStream() - { - return m_pStream->GetUndecodedStream(); - } - virtual Dict *GetDict() - { - return m_pStream->GetDict(); - } - virtual Stream *GetNextStream() - { - return m_pStream; - } - - protected: - - Stream *m_pStream; - }; - - //------------------------------------------------------------------------ - // ImageStream - //------------------------------------------------------------------------ - - class ImageStream - { - public: - - // Создаем Image object по картинке с заданными параметрами( тут имеются ввиду - // реальные параметры картинки, а не те что могут прийти в Predictor). - ImageStream(Stream *pStream, int nWidth, int nComponents, int nBitsPerComponent); - - ~ImageStream(); - - void Reset(); - - // Считываем следующий пиксел из потока. pPixel должно указывать на место достаточное, - // для хранения как минимум m_nComponentsPerPixel элементов. - bool GetPixel(unsigned char *pPixel); - - unsigned char *GetNextLine(); - - void SkipLine(); - - private: - - Stream *m_pStream; // Основной поток - int m_nWidth; // Количество пикселей в строке - int m_nComponentsPerPixel; // Количество компонент на один пиксел - int m_nBitsPerComponent; // Количество бит в компоненте - int m_nComponentsPerLine; // Количество компонент в одной строке - unsigned char *m_pLineBuffer; // Буффер для одной строки изображения - int m_nLinePos; // Текущая позиция в m_pLineBuffer - }; - - //------------------------------------------------------------------------ - // StreamPredictor (Predictor - дополнительный фильтр для картинок) - //------------------------------------------------------------------------ - - class StreamPredictor - { - public: - - // Создаем Predictor object. Параметры, которые задаются здесь, могут - // не совпадать с реальными параметрами картинки. - StreamPredictor(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent); - - ~StreamPredictor(); - - bool CheckValidate() - { - return m_bSuccess; - } - - - int LookChar(); - int GetChar(); - - private: - - bool GetNextLine(); - - private: - - Stream *m_pStream; // Основной поток - int m_nPredictor; // Predictor - int m_nWidth; // Количество пикселей в строке - int m_nComponentsPerPixel; // Количество компонент на один пиксел - int m_nBitsPerComponent; // Количество бит в компоненте - int m_nComponentsPerLine; // Количество компонент в одной строке - int m_nBytesPerPixel; // Количество байт в одном пикселе - int m_nBytesPerLine; // Количество байт в строке - unsigned char *m_pLineBuffer; // Буффер для одной строки изображения - int m_nLinePos; // Текущая позиция в m_pLineBuffer - - bool m_bSuccess; - }; - - //------------------------------------------------------------------------ - // FileStream - //------------------------------------------------------------------------ - -#define FileStreamBufferSize 1024 - - class FileStream : public BaseStream - { - public: - - FileStream(FILE *pFile, unsigned int unStart, bool bLimited, unsigned int nLength, Object *pDict); - virtual ~FileStream(); - - virtual Stream *MakeSubStream(unsigned int unStart, bool bLimited, unsigned int nLength, Object *pDict); - virtual StreamType GetType() - { - return strFile; - } - virtual void Reset(); - virtual void Close(); - inline virtual int GetChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer++ & 0xff); - } - inline virtual int LookChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer & 0xff); - } - inline virtual int GetPos() - { - return m_unBufferPos + (m_pBufferPointer - m_sBuffer); - } - virtual void SetPos(unsigned int unPos, int nDirection = 0); - virtual unsigned int GetStartPos() - { - return m_unStart; - } - virtual void SetStartPos(int nDelta); - - private: - - bool FillBuffer(); - - private: - - FILE *m_pFile; - unsigned int m_unStart; - bool m_bLimited; - unsigned int m_unLength; - char m_sBuffer[FileStreamBufferSize]; - char *m_pBufferPointer; - char *m_pBufferEnd; - unsigned int m_unBufferPos; - int m_nSavePos; - bool m_bSaved; - }; - //------------------------------------------------------------------------ - // MemoryStream - //------------------------------------------------------------------------ - - class MemoryStream : public BaseStream - { - public: - - MemoryStream(char *sBuffer, unsigned int unStart, unsigned int unLength, Object *pDict); - virtual ~MemoryStream(); - virtual Stream *MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual void Close(); - virtual int GetChar() - { - return (m_pBufferPointer < m_pBufferEnd) ? (*m_pBufferPointer++ & 0xff) : EOF; - } - virtual int LookChar() - { - return (m_pBufferPointer < m_pBufferEnd) ? (*m_pBufferPointer & 0xff) : EOF; - } - virtual int GetPos() - { - return (int)(m_pBufferPointer - m_sBuffer); - } - virtual void SetPos(unsigned int unPos, int nDirection = 0); - virtual unsigned int GetStartPos() - { - return m_unStart; - } - virtual void SetStartPos(int delta); - - char* getCurrent(); - unsigned int getCurrentLength(); - - private: - - char *m_sBuffer; - unsigned int m_unStart; - unsigned int m_unLength; - char *m_pBufferEnd; - char *m_pBufferPointer; - bool m_bNeedFree; - }; - - //------------------------------------------------------------------------ - // EmbedStream - // - // Специальный тип потока, используемый для внутренныих(внедренных) потоков - // (Inline images). Читаем напрямую из Base stream -- после удаления - // EmbedStream, чтение из Base stream будет совершаться для оставшейся части - // потока. Это соверешнно подругому, чем просто создать новый поток - // FileStream (используя MakeSubStream). - //------------------------------------------------------------------------ - - class EmbedStream : public BaseStream - { - public: - - EmbedStream(Stream *pStream, Object *pDict, bool bLimited, unsigned int unLength); - virtual ~EmbedStream(); - virtual Stream *MakeSubStream(unsigned int unStart, bool bLimited, unsigned int unLength, Object *pDict); - virtual StreamType GetType() - { - return m_pStream->GetType(); - } - virtual void Reset() - { - } - virtual void Close(){} - virtual int GetChar(); - virtual int LookChar(); - virtual int GetPos() - { - return m_pStream->GetPos(); - } - virtual void SetPos(unsigned int unPos, int nDirection = 0); - virtual unsigned int GetStartPos(); - virtual void SetStartPos(int nDelta); - - private: - - Stream *m_pStream; - bool m_bLimited; - unsigned int m_unLength; - }; - - //------------------------------------------------------------------------ - // ASCIIHexStream - //------------------------------------------------------------------------ - - class ASCIIHexStream : public FilterStream - { - public: - - ASCIIHexStream(Stream *pStream); - virtual ~ASCIIHexStream(); - virtual StreamType GetType() - { - return strASCIIHex; - } - virtual void Reset(); - virtual int GetChar() - { - int nChar = LookChar(); - m_nBuffer = EOF; - return nChar; - } - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - int m_nBuffer; - bool m_bEOF; - }; - - //------------------------------------------------------------------------ - // ASCII85Stream - //------------------------------------------------------------------------ - - class ASCII85Stream : public FilterStream - { - public: - - ASCII85Stream(Stream *pStream); - virtual ~ASCII85Stream(); - virtual StreamType GetType() - { - return strASCII85; - } - virtual void Reset(); - virtual int GetChar() - { - int nChar = LookChar(); - ++m_nIndex; - return nChar; - } - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - int m_arrC[5]; // Имена массивов C и B взяты из спецификации - int m_arrB[4]; - int m_nIndex; - int m_nCount; - bool m_bEOF; - }; - - //------------------------------------------------------------------------ - // LZWStream - //------------------------------------------------------------------------ - - class LZWStream : public FilterStream - { - public: - - LZWStream(Stream *pStream, int nPredictor, int nColumns, int nColors, int nBitPerPixel, int nEarlyChange); - virtual ~LZWStream(); - virtual StreamType GetType() - { - return strLZW; - } - virtual void Reset(); - virtual int GetChar(); - virtual int LookChar(); - virtual int GetRawChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - bool ProcessNextCode(); - void ClearTable(); - int GetCode(); - - private: - - StreamPredictor *m_pPredictor; // Predictor (еще один дополнительный фильтр) - int m_nEarlyChange; // Параметр и словаря для LZW фильтра - bool m_bEOF; // Конец потока? - int m_nInputBuffer; // Input buffer - int m_nInputBits; // Количество бит в буффере - struct - { - int nLength; - int nHead; - unsigned char unTail; - } m_pTable[4097]; // Таблица для декодирования - int m_nNextCode; // Следующий код - int m_nNextBits; // Число бит в следующем коде - int m_nPrevCode; // Предыдущий код в потоке - int m_nNewChar; // Новый символ, который мы добавим в таблицу - unsigned char m_arrCurBuffer[4097]; // Буффер для текущей последовательности - int m_nCurLength; // Длина текущей последовательности - int m_nCurPos; // Позиция в текущей последовательности - bool m_bFirst; // Является ли данный код первым после очищения таблицы - }; - - //------------------------------------------------------------------------ - // RunLengthStream - //------------------------------------------------------------------------ - - class RunLengthStream : public FilterStream - { - public: - - RunLengthStream(Stream *pStream); - virtual ~RunLengthStream(); - virtual StreamType GetType() - { - return strRunLength; - } - virtual void Reset(); - virtual int GetChar() - { - return (m_pBufferPointer >= m_pEndOfBuffer && !FillBuffer()) ? EOF : (*m_pBufferPointer++ & 0xff); - } - virtual int LookChar() - { - return (m_pBufferPointer >= m_pEndOfBuffer && !FillBuffer()) ? EOF : (*m_pBufferPointer & 0xff); - } - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - bool FillBuffer(); - - private: - - char m_sBuffer[128]; // Буфер - char *m_pBufferPointer; // Указатель на следующий символ в буфере - char *m_pEndOfBuffer; // Указатель на конец буфера - bool m_bEOF; - }; - - //------------------------------------------------------------------------ - // CCITTFaxStream - //------------------------------------------------------------------------ - - struct CCITTCodeTable; - - class CCITTFaxStream : public FilterStream - { - public: - - CCITTFaxStream(Stream *pStream, int nK, bool bEndOfLine, bool bByteAlign, int nColumns, int nRows, bool bEndOfBlock, bool bBlackIs1); - virtual ~CCITTFaxStream(); - virtual StreamType GetType() - { - return strCCITTFax; - } - virtual void Reset(); - virtual int GetChar() - { - int nChar = LookChar(); - m_nCharBuffer = EOF; - return nChar; - } - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - short Get2DCode(); - short GetWhiteCode(); - short GetBlackCode(); - short LookBits(int nCount); - void SkipBits(int nCount) - { - if ((m_nInputBits -= nCount) < 0) - m_nInputBits = 0; - } - - private: - - int m_nK; // Параметр 'K', определяющий тип кодировки - bool m_bEndOfLine; // Параметр 'EndOfLine' - bool m_bByteAlign; // Параметр 'EncodedByteAlign' - int m_nColumns; // Параметр 'Columns' - int m_nRows; // Параметр 'Rows' - bool m_bEndOfBlock; // Параметр 'EndOfBlock' - bool m_bBlackIs1; // Параметр 'BlackIs1' - - bool m_bEOF; // - bool m_bNextLine2D; // True, если следующая строка использует кодировку 2D - int m_mCurRow; // Текущая строка - int m_nInputBuffer; // Input buffer - int m_nInputBits; // Количество бит в Input buffer - short *m_pRefLine; // Ссылочная строка, меняющую элементы - int m_nCurPosRL; // Текущая позиция в m_pRefLine - short *m_pCodingLine; // Кодирующая строка, меняющая элементы - int m_nCurPosCL; // Текущая позиция в m_pCodingLine - int m_nOutputBits; // - int m_nCharBuffer; // - }; - - //------------------------------------------------------------------------ - // DCTStream - //------------------------------------------------------------------------ - - struct DCTCompInfo - { - int nID; // ID данного элемента - int nXResolution; // Разрешение по горизонтали - int nYResolution; // Разрешение по вертикали - int nQuantTableNum; // Номер таблицы квантования - int nPrevDC; // - }; - - struct DCTScanInfo - { - bool arrbComponent[4]; // arrbComponent[i] = true, если i-ая компонента включена в даннуб структуру - int nComponentsCount; // количество компонент в данной структуре - int arrDCHuffTable[4]; // номера таблиц DC Huffman - int arrACHuffTable[4]; // номера таблиц AC Huffman - int nFirstKoef; // первый DCT коэффициент - int nLastKoef; // последний DCT коэффициент - int nApproxH; - int nApproxL; - }; - - struct DCTHuffTable - { - unsigned char arrunFirstSymbol[17]; // Первый символ в данной группе - unsigned short arrunFirstCode[17]; // Первый код в данной группе - unsigned short arrunCodesCount[17]; // Количество кодов в данной группе - unsigned char arrunSymbols[256]; // Сами символы - }; - - class DCTStream : public FilterStream - { - public: - - DCTStream(Stream *pStream, int nColorTransform); - virtual ~DCTStream(); - virtual StreamType GetType() - { - return strDCT; - } - virtual void Reset(); - virtual void Close(); - virtual int GetChar(); - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - Stream *GetRawStream() - { - return m_pStream; - } - - private: - - void Restart(); - bool ReadMCURow(); - void ReadScan(); - bool ReadDataUnit(DCTHuffTable *pDCHuffTable, DCTHuffTable *pACHuffTable, int *pnPrevDC, int arrData[64]); - bool ReadProgressiveDataUnit(DCTHuffTable *pDCHuffTable, DCTHuffTable *pACHuffTable, int *pnPrevDC, int arrData[64]); - void DecodeImage(); - void TransformDataUnit(unsigned short *pQuantTable, int arrDataIn[64], unsigned char arrDataOut[64]); - int ReadHuffSymbol(DCTHuffTable *pTable); - int ReadAmp(int nSize); - int ReadBit(); - bool ReadHeader(); - bool ReadBaselineSOF(); - bool ReadProgressiveSOF(); - bool ReadScanInfo(); - bool ReadQuantTables(); - bool ReadHuffmanTables(); - bool ReadRestartInterval(); - bool ReadJFIFMarker(); - bool ReadAdobeMarker(); - bool ReadTrailer(); - int ReadMarker(); - int Read16(); - - private: - - bool m_bProgressive; // True, если мод progressive - bool m_bInterleaved; // True, если мод interleaved - int m_nWidth; // ширина изображения - int m_nHeight; // высота изображения - int m_nMCUWidth; // ширина min coding unit(MCU) - int m_nMCUHeight; // высота min coding unit(MCU) - int m_nBufferWidth; // ширина FrameBuffer - int m_nBufferHeight; // высота FrameBuffer - DCTCompInfo m_arrCompInfo[4]; // Структура Info для каждой компоненты - DCTScanInfo m_oCurScanInfo; // Структура Info для текущего Scan - int m_nComponentsCount; // Количество компонент изображения - int m_nColorTransform; // Преобразования пространства цветов: - // -1 = непоределено - // 0 = нет преобразования - // 1 = YUV/YUVK -> RGB/CMYK - bool m_bJFIFMarker; // True, если есть маркер APP0 JFIF - bool m_bAdobeMarker; // True, если есть маркер APP14 Adobe - int m_nRestartInterval; // в MCU - unsigned short m_arrQuantTables[4][64]; // Таблицы квантования - int m_nQuantTablesCount; // количество таблицы квантования - DCTHuffTable m_arrDCHuffTables[4]; // Таблицы DC Huffman - DCTHuffTable m_arrACHuffTables[4]; // Таблицы AC Huffman - int m_nDCHuffTablesCount; // Количество таблиц DC Huffman - int m_nACHuffTablesCount; // Количество таблиц AC Huffman - unsigned char *m_pppRowBuffer[4][32]; // Буфер для MCU (non-progressive mode) - int *m_ppFrameBuffer[4]; // Буфер для фрэйма (progressive mode) - - int m_nCurComponent; // Текущие параметры для кртинки/MCU - int m_nX; // - int m_nY; // - int m_nDY; // - - int m_nRestartCtr; // количество оставишхся MCU до рестарта - int m_nRestartMarker; // - int m_nEOBRun; // количество оставшихся EOB(end-of-block) в текущей группе - - int m_nInputBuffer; // Буфер для кодов разной длины - int m_nInputBits; // Число корректных бит в Input buffer - - }; - - //------------------------------------------------------------------------ - // FlateZlibStream - //------------------------------------------------------------------------ - -#define flateZlibWindow 32768 // Размер буфера -#define flateZlibMask 32767 // (flateZlibWindow - 1) - - class FlateZlibStream : public FilterStream - { - public: - - FlateZlibStream(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent); - virtual ~FlateZlibStream(); - virtual StreamType GetType() - { - return strFlate; - } - virtual void Reset(); - virtual int GetChar(); - virtual int LookChar(); - virtual int GetRawChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - void ReadSome(); - - private: - - CInflate m_oZStream; // Zlib поток - StreamPredictor *m_pPredictor; // Predictor - unsigned int m_nInSize; // Размер входного буффера - unsigned char m_arrInBuffer[flateZlibWindow]; // Входной буффер - unsigned char m_arrBuffer[flateZlibWindow]; // Буфер для результата декодирования - int m_nBufferCurPos; // Текущая позиция в буфере - int m_nRemain; // Число корректных байт в буфере - bool m_bEndOfBlock; // True, когда достигли конца блока - bool m_bEOF; // True, когда достигли конца потока - }; - - - //------------------------------------------------------------------------ - // FlateStream - //------------------------------------------------------------------------ - -#define flateWindow 32768 // Размер буфера -#define flateMask (flateWindow-1) -#define flateMaxHuffman 15 // макимальная длина кода Huffman -#define flateMaxCodeLenCodes 19 // max # code length codes -#define flateMaxLitCodes 288 // max # literal codes -#define flateMaxDistCodes 30 // max # distance codes - - struct FlateHuffmanCode - { - unsigned short nLength; // длина кода в битах - unsigned short nValue; // значение данного коду - }; - - struct FlateHuffmanTable - { - FlateHuffmanCode *pCodes; // таблица кодов - int nMaxLen; // макимальная длина кода - }; - - struct FlateDecode - { - int nExtraBitsCount; // количество дополнительных бит - int nFirst; // первая длина - }; - - class FlateStream : public FilterStream - { - public: - - FlateStream(Stream *pStream, int nPredictor, int nWidth, int nComponents, int nBitsPerComponent); - virtual ~FlateStream(); - virtual StreamType GetType() - { - return strFlate; - } - virtual void Reset(); - virtual int GetChar(); - virtual int LookChar(); - virtual int GetRawChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent); - virtual bool IsBinary(bool bLast = true); - - private: - - void ReadSome(); - bool StartBlock(); - void LoadFixedCodes(); - bool ReadDynamicCodes(); - void ConvertHuffmanCodes(int *pLengths, int nCount, FlateHuffmanTable *pTable); - int GetHuffmanCodeWord(FlateHuffmanTable *pTable); - int GetCodeWord(int nBits); - - private: - - StreamPredictor *m_pPredictor; // Predictor - unsigned char m_arrBuffer[flateWindow]; // Буфер для результата декодирования - int m_nBufferCurPos; // Текущая позиция в буфере - int m_nRemain; // Число корректных байт в буфере - int m_nCodeBuffer; // Бефер исходных кодов - int m_nCodeSize; // Число бит в m_nCodeBuffer - int m_arrCodeLengths[flateMaxLitCodes + flateMaxDistCodes]; // Длины кодов(и для самих слов и для расстояний) - FlateHuffmanTable m_oLiteratCodeTable; // Таблица буквенных кодов - FlateHuffmanTable m_oDistanceCodeTable; // Таблица кодов-расстояний - bool m_bCompressedBlock; // True, если читаем сжатый блок - int m_nUncompBlockLen; // Оставшаяся длина несжатого блока - bool m_bEndOfBlock; // True, когда достигли конца блока - bool m_bEOF; // True, когда достигли конца потока - - static int m_arrCodeLenCodeMap[flateMaxCodeLenCodes]; // - static FlateDecode m_arrLengthDecode[flateMaxLitCodes - 257]; // - static FlateDecode m_arrDistanceDecode[flateMaxDistCodes]; // - static FlateHuffmanTable m_oFixedLiteralCodeTable; // - static FlateHuffmanTable m_oFixedDistanceCodeTable; // - }; - - //------------------------------------------------------------------------ - // EOFStream - //------------------------------------------------------------------------ - - class EOFStream : public FilterStream - { - public: - - EOFStream(Stream *pStream); - virtual ~EOFStream(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset() - { - } - virtual int GetChar() - { - return EOF; - } - virtual int LookChar() - { - return EOF; - } - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - virtual bool IsBinary(bool bLast = true) - { - return false; - } - }; - - //------------------------------------------------------------------------ - // FixedLengthEncoder - //------------------------------------------------------------------------ - - class FixedLengthEncoder : public FilterStream - { - public: - - FixedLengthEncoder(Stream *pStream, int nLength); - ~FixedLengthEncoder(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual int GetChar(); - virtual int LookChar(); - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - virtual bool IsBinary(bool bLast = true); - virtual bool IsEncoder() - { - return true; - } - - private: - - int m_nLength; - int m_nCount; - }; - - //------------------------------------------------------------------------ - // ASCIIHexEncoder - //------------------------------------------------------------------------ - - class ASCIIHexEncoder : public FilterStream - { - public: - - ASCIIHexEncoder(Stream *pStream); - virtual ~ASCIIHexEncoder(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual int GetChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer++ & 0xff); - } - virtual int LookChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer & 0xff); - } - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - virtual bool IsBinary(bool bLast = true) - { - return false; - } - virtual bool IsEncoder() - { - return true; - } - - private: - - bool FillBuffer(); - - private: - - char m_sBuffer[4]; - char *m_pBufferPointer; - char *m_pBufferEnd; - int m_nLineLength; - bool m_bEOF; - }; - - //------------------------------------------------------------------------ - // ASCII85Encoder - //------------------------------------------------------------------------ - - class ASCII85Encoder : public FilterStream - { - public: - - ASCII85Encoder(Stream *pStream); - virtual ~ASCII85Encoder(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual int GetChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer++ & 0xff); - } - virtual int LookChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer & 0xff); - } - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - virtual bool IsBinary(bool bLast = true) - { - return false; - } - virtual bool IsEncoder() - { - return true; - } - private: - - bool FillBuffer(); - - private: - - char m_sBuffer[8]; - char *m_pBufferPointer; - char *m_pBufferEnd; - int m_nLineLength; - bool m_bEOF; - }; - - //------------------------------------------------------------------------ - // RunLengthEncoder - //------------------------------------------------------------------------ - - class RunLengthEncoder : public FilterStream - { - public: - - RunLengthEncoder(Stream *pStream); - virtual ~RunLengthEncoder(); - virtual StreamType GetType() - { - return strWeird; - } - virtual void Reset(); - virtual int GetChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer++ & 0xff); - } - virtual int LookChar() - { - return (m_pBufferPointer >= m_pBufferEnd && !FillBuffer()) ? EOF : (*m_pBufferPointer & 0xff); - } - virtual StringExt *GetPSFilter(int nPSLevel, char *sIndent) - { - return NULL; - } - virtual bool IsBinary(bool bLast = true) - { - return true; - } - virtual bool IsEncoder() - { - return true; - } - - private: - - bool FillBuffer(); - - private: - - char m_sBuffer[131]; - char *m_pBufferPointer; - char *m_pBufferEnd; - char *m_pNextEnd; - bool m_bEOF; - }; -} - -#endif // _PDF_READER_STREAM_H diff --git a/PdfReader/old/StringExt.cpp b/PdfReader/old/StringExt.cpp deleted file mode 100644 index 6bc8fbc265..0000000000 --- a/PdfReader/old/StringExt.cpp +++ /dev/null @@ -1,794 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "StringExt.h" - -namespace PdfReader -{ - union StringExtFormatArg - { - int iValue; - unsigned int uiValue; - long lValue; - unsigned long ulValue; - double fValue; - char cValue; - char *sValue; - StringExt *seValue; - }; - - enum StringExtFormatType - { - fmtIntDecimal, - fmtIntHex, - fmtIntOctal, - fmtIntBinary, - fmtUIntDecimal, - fmtUIntHex, - fmtUIntOctal, - fmtUIntBinary, - fmtLongDecimal, - fmtLongHex, - fmtLongOctal, - fmtLongBinary, - fmtULongDecimal, - fmtULongHex, - fmtULongOctal, - fmtULongBinary, - fmtDouble, - fmtDoubleTrim, - fmtChar, - fmtString, - fmtStringExt, - fmtSpace - }; - - static char *c_arrsFormatStrings[] = - { - "d", "x", "o", "b", "ud", "ux", "uo", "ub", - "ld", "lx", "lo", "lb", "uld", "ulx", "ulo", "ulb", - "f", "g", - "c", - "s", - "t", - "w", - NULL - }; - - //------------------------------------------------------------------------ - - static inline int Size(int nLen) - { - int nDelta; - for (nDelta = 8; nDelta < nLen && nDelta < 0x100000; nDelta <<= 1); - // ((nLen + 1) + (delta - 1)) & ~(delta - 1) - return (nLen + nDelta) & ~(nDelta - 1); - } - - inline void StringExt::Resize(int nLength) - { - char *sTemp = NULL; - - if (!m_sData) - m_sData = new char[Size(nLength)]; - else if (Size(nLength) != Size(m_nLength)) - { - sTemp = new char[Size(nLength)]; - if (nLength < m_nLength) - { - memcpy(sTemp, m_sData, nLength); - sTemp[nLength] = '\0'; - } - else - memcpy(sTemp, m_sData, m_nLength + 1); - delete[] m_sData; - m_sData = sTemp; - } - } - - StringExt::StringExt() - { - m_sData = NULL; - Resize(m_nLength = 0); - m_sData[0] = '\0'; - } - - StringExt::StringExt(std::wstring& wsString) - { - int nLen = wsString.length(); - - m_sData = NULL; - Resize(m_nLength = nLen); - for (int nPos = 0; nPos < nLen; nPos++) - { - m_sData[nPos] = (unsigned char)wsString.at(nPos); - } - } - - StringExt::StringExt(const wchar_t* _wsString) - { - std::wstring wsString(_wsString); - int nLen = wsString.length(); - - m_sData = NULL; - Resize(m_nLength = nLen); - for (int nPos = 0; nPos < nLen; nPos++) - { - m_sData[nPos] = (unsigned char)wsString.at(nPos); - } - } - - StringExt::StringExt(const char *sSrc) - { - int nLen = strlen(sSrc); - - m_sData = NULL; - Resize(m_nLength = nLen); - memcpy(m_sData, sSrc, nLen + 1); - } - - StringExt::StringExt(const char *sSrc, int nLength) - { - m_sData = NULL; - Resize(m_nLength = nLength); - memcpy(m_sData, sSrc, m_nLength * sizeof(char)); - m_sData[m_nLength] = '\0'; - } - - StringExt::StringExt(StringExt *seSrc, int nIndex, int nLength) - { - m_sData = NULL; - Resize(m_nLength = nLength); - memcpy(m_sData, seSrc->GetBuffer() + nIndex, m_nLength); - m_sData[m_nLength] = '\0'; - } - - StringExt::StringExt(StringExt *seSrc) - { - m_sData = NULL; - Resize(m_nLength = seSrc->GetLength()); - memcpy(m_sData, seSrc->GetBuffer(), m_nLength + 1); - } - - StringExt::StringExt(StringExt *seString1, StringExt *seString2) - { - int nLen1 = seString1->GetLength(); - int nLen2 = seString2->GetLength(); - - m_sData = NULL; - Resize(m_nLength = nLen1 + nLen2); - memcpy(m_sData, seString1->GetBuffer(), nLen1); - memcpy(m_sData + nLen1, seString2->GetBuffer(), nLen2 + 1); - } - - StringExt *StringExt::FromInt(int nValue) - { - char sBuffer[24]; - char *pData = NULL; - int nLen; - - FormatInt(nValue, sBuffer, sizeof(sBuffer), false, 0, 10, &pData, &nLen); - return new StringExt(pData, nLen); - } - - StringExt *StringExt::Format(char *sFormat, ...) - { - va_list sArgList; - StringExt *seResult = new StringExt(); - va_start(sArgList, sFormat); - seResult->AppendFormatV(sFormat, sArgList); - va_end(sArgList); - return seResult; - } - - StringExt *StringExt::FormatV(char *sFormat, va_list sArgList) - { - StringExt *seResult = new StringExt(); - seResult->AppendFormatV(sFormat, sArgList); - return seResult; - } - - StringExt::~StringExt() - { - delete[] m_sData; - } - - StringExt *StringExt::Clear() - { - m_sData[m_nLength = 0] = '\0'; - Resize(0); - return this; - } - - StringExt *StringExt::Append(char nChar) - { - Resize(m_nLength + 1); - m_sData[m_nLength++] = nChar; - m_sData[m_nLength] = '\0'; - return this; - } - - StringExt *StringExt::Append(StringExt *seString) - { - int nLen = seString->GetLength(); - - Resize(m_nLength + nLen); - memcpy(m_sData + m_nLength, seString->GetBuffer(), nLen + 1); - m_nLength += nLen; - return this; - } - - StringExt *StringExt::Append(const char *sString) - { - int nLen = strlen(sString); - - Resize(m_nLength + nLen); - memcpy(m_sData + m_nLength, sString, nLen + 1); - m_nLength += nLen; - return this; - } - - StringExt *StringExt::Append(const char *sString, int nLength) - { - Resize(m_nLength + nLength); - memcpy(m_sData + m_nLength, sString, nLength); - m_nLength += nLength; - m_sData[m_nLength] = '\0'; - return this; - } - - StringExt *StringExt::AppendFormat(char *sFormat, ...) - { - va_list sArgList; - va_start(sArgList, sFormat); - AppendFormatV(sFormat, sArgList); - va_end(sArgList); - return this; - } - - StringExt *StringExt::AppendFormatV(char *sFormat, va_list sArgList) - { - StringExtFormatArg uArg; - int nIndex, nWidth, nPrecision; - bool bReverseAlign, bZeroFill; - StringExtFormatType eFormatType; - char sBuffer[65]; - int nLen; - char *pCur, *pTemp, *sTemp; - - int nArgsLen = 0; - int nArgsSize = 8; - StringExtFormatArg *arrArgs = (StringExtFormatArg *)MemUtilsMallocArray(nArgsSize, sizeof(StringExtFormatArg)); - - pCur = sFormat; - while (*pCur) - { - if (*pCur == '{') - { - ++pCur; - if (*pCur == '{') - { - ++pCur; - Append('{'); - } - else - { - // Разбираем форматированную строку - if (!(*pCur >= '0' && *pCur <= '9')) - break; - nIndex = *pCur - '0'; - for (++pCur; *pCur >= '0' && *pCur <= '9'; ++pCur) - nIndex = 10 * nIndex + (*pCur - '0'); - - if (*pCur != ':') - break; - ++pCur; - if (*pCur == '-') - { - bReverseAlign = true; - ++pCur; - } - else - bReverseAlign = false; - nWidth = 0; - bZeroFill = *pCur == '0'; - for (; *pCur >= '0' && *pCur <= '9'; ++pCur) - nWidth = 10 * nWidth + (*pCur - '0'); - if (*pCur == '.') - { - ++pCur; - nPrecision = 0; - for (; *pCur >= '0' && *pCur <= '9'; ++pCur) - { - nPrecision = 10 * nPrecision + (*pCur - '0'); - } - } - else - { - nPrecision = 0; - } - for (eFormatType = (StringExtFormatType)0; - c_arrsFormatStrings[eFormatType]; - eFormatType = (StringExtFormatType)(eFormatType + 1)) - { - if (!strncmp(pCur, c_arrsFormatStrings[eFormatType], strlen(c_arrsFormatStrings[eFormatType]))) - { - break; - } - } - if (!c_arrsFormatStrings[eFormatType]) - { - break; - } - pCur += strlen(c_arrsFormatStrings[eFormatType]); - if (*pCur != '}') - { - break; - } - ++pCur; - // fetch the argument - if (nIndex > nArgsLen) - { - break; - } - if (nIndex == nArgsLen) - { - if (nArgsLen == nArgsSize) - { - nArgsSize *= 2; - arrArgs = (StringExtFormatArg *)MemUtilsReallocArray(arrArgs, nArgsSize, sizeof(StringExtFormatArg)); - } - switch (eFormatType) - { - case fmtIntDecimal: - case fmtIntHex: - case fmtIntOctal: - case fmtIntBinary: - case fmtSpace: - arrArgs[nArgsLen].iValue = va_arg(sArgList, int); - break; - case fmtUIntDecimal: - case fmtUIntHex: - case fmtUIntOctal: - case fmtUIntBinary: - arrArgs[nArgsLen].uiValue = va_arg(sArgList, unsigned int); - break; - case fmtLongDecimal: - case fmtLongHex: - case fmtLongOctal: - case fmtLongBinary: - arrArgs[nArgsLen].lValue = va_arg(sArgList, long); - break; - case fmtULongDecimal: - case fmtULongHex: - case fmtULongOctal: - case fmtULongBinary: - arrArgs[nArgsLen].ulValue = va_arg(sArgList, unsigned long); - break; - case fmtDouble: - case fmtDoubleTrim: - arrArgs[nArgsLen].fValue = va_arg(sArgList, double); - break; - case fmtChar: - arrArgs[nArgsLen].cValue = (char)va_arg(sArgList, int); - break; - case fmtString: - arrArgs[nArgsLen].sValue = va_arg(sArgList, char *); - break; - case fmtStringExt: - arrArgs[nArgsLen].seValue = va_arg(sArgList, StringExt *); - break; - } - ++nArgsLen; - } - - uArg = arrArgs[nIndex]; - switch (eFormatType) - { - case fmtIntDecimal: - FormatInt(uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen); - break; - case fmtIntHex: - FormatInt(uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen); - break; - case fmtIntOctal: - FormatInt(uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen); - break; - case fmtIntBinary: - FormatInt(uArg.iValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen); - break; - case fmtUIntDecimal: - FormatUInt(uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen); - break; - case fmtUIntHex: - FormatUInt(uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen); - break; - case fmtUIntOctal: - FormatUInt(uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen); - break; - case fmtUIntBinary: - FormatUInt(uArg.uiValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen); - break; - case fmtLongDecimal: - FormatInt(uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen); - break; - case fmtLongHex: - FormatInt(uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen); - break; - case fmtLongOctal: - FormatInt(uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen); - break; - case fmtLongBinary: - FormatInt(uArg.lValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen); - break; - case fmtULongDecimal: - FormatUInt(uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 10, &sTemp, &nLen); - break; - case fmtULongHex: - FormatUInt(uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 16, &sTemp, &nLen); - break; - case fmtULongOctal: - FormatUInt(uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 8, &sTemp, &nLen); - break; - case fmtULongBinary: - FormatUInt(uArg.ulValue, sBuffer, sizeof(sBuffer), bZeroFill, nWidth, 2, &sTemp, &nLen); - break; - case fmtDouble: - FormatDouble(uArg.fValue, sBuffer, sizeof(sBuffer), nPrecision, false, &sTemp, &nLen); - break; - case fmtDoubleTrim: - FormatDouble(uArg.fValue, sBuffer, sizeof(sBuffer), nPrecision, true, &sTemp, &nLen); - break; - case fmtChar: - sBuffer[0] = uArg.cValue; - sTemp = sBuffer; - nLen = 1; - bReverseAlign = !bReverseAlign; - break; - case fmtString: - sTemp = uArg.sValue; - nLen = strlen(sTemp); - bReverseAlign = !bReverseAlign; - break; - case fmtStringExt: - sTemp = uArg.seValue->GetBuffer(); - nLen = uArg.seValue->GetLength(); - bReverseAlign = !bReverseAlign; - break; - case fmtSpace: - sTemp = sBuffer; - nLen = 0; - nWidth = uArg.iValue; - break; - default: - sTemp = sBuffer; - nLen = 0; - nWidth = uArg.iValue; - break; - } - // Добавляем аргумент в нужном формате, с нужным прилеганием - if (!bReverseAlign && nLen < nWidth) - { - for (int nCounter = nLen; nCounter < nWidth; ++nCounter) - Append(' '); - } - Append(sTemp, nLen); - if (bReverseAlign && nLen < nWidth) - { - for (int nCounter = nLen; nCounter < nWidth; ++nCounter) - Append(' '); - } - } - } - else if (*pCur == '}') - { - ++pCur; - if (*pCur == '}') - ++pCur; - Append('}'); - } - else - { - for (pTemp = pCur + 1; *pTemp && *pTemp != '{' && *pTemp != '}'; ++pTemp); - Append(pCur, pTemp - pCur); - pCur = pTemp; - } - } - MemUtilsFree(arrArgs); - return this; - } - - void StringExt::FormatInt(long nValue, char *sBuffer, int nBufferSize, bool bZeroFill, int nWidth, int nBase, char **ppData, int *pnLen) - { - static char c_sValues[17] = "0123456789abcdef"; - bool bNegative = false; - int nStart; - - int nCur = nBufferSize; - if ((bNegative = nValue < 0)) - { - nValue = -nValue; - } - nStart = bNegative ? 1 : 0; - if (nValue == 0) - { - sBuffer[--nCur] = '0'; - } - else - { - while (nCur > nStart && nValue) - { - sBuffer[--nCur] = c_sValues[nValue % nBase]; - nValue /= nBase; - } - } - if (bZeroFill) - { - for (int nCounter = nBufferSize - nCur; nCur > nStart && nCounter < nWidth - nStart; ++nCounter) - { - sBuffer[--nCur] = '0'; - } - } - if (bNegative) - { - sBuffer[--nCur] = '-'; - } - *ppData = sBuffer + nCur; - *pnLen = nBufferSize - nCur; - } - - void StringExt::FormatUInt(unsigned long nValue, char *sBuffer, int nBufferSize, bool bZeroFill, int nWidth, int nBase, char **ppData, int *pnLen) - { - static char c_sValues[17] = "0123456789abcdef"; - - int nCur = nBufferSize; - if (nValue == 0) - { - sBuffer[--nCur] = '0'; - } - else - { - while (nCur > 0 && nValue) - { - sBuffer[--nCur] = c_sValues[nValue % nBase]; - nValue /= nBase; - } - } - if (bZeroFill) - { - for (int nCounter = nBufferSize - nCur; nCur > 0 && nCounter < nWidth; ++nCounter) - { - sBuffer[--nCur] = '0'; - } - } - *ppData = sBuffer + nCur; - *pnLen = nBufferSize - nCur; - } - - void StringExt::FormatDouble(double dValue, char *sBuffer, int nBufferSize, int nPrecision, bool bTrim, char **ppData, int *pnLen) - { - bool bNegative = false, bStarted = false; - double dTemp = 0; - int nInt; - - if (bNegative = (dValue < 0)) - dValue = -dValue; - - dValue = floor(dValue * pow((double)10, nPrecision) + 0.5); - int nCur = nBufferSize; - bStarted = !bTrim; - for (int nCounter = 0; nCounter < nPrecision && nCur > 1; ++nCounter) - { - dTemp = floor(0.1 * (dValue + 0.5)); - nInt = (int)floor(dValue - 10 * dTemp + 0.5); - if (bStarted || nInt != 0) - { - sBuffer[--nCur] = '0' + nInt; - bStarted = true; - } - dValue = dTemp; - } - if (nCur > 1 && bStarted) - sBuffer[--nCur] = '.'; - if (nCur > 1) - { - do { - dTemp = floor(0.1 * (dValue + 0.5)); - nInt = (int)floor(dValue - 10 * dTemp + 0.5); - sBuffer[--nCur] = '0' + nInt; - dValue = dTemp; - } while (nCur > 1 && dValue); - } - if (bNegative) - sBuffer[--nCur] = '-'; - - *ppData = sBuffer + nCur; - *pnLen = nBufferSize - nCur; - } - - StringExt *StringExt::Insert(int nIndex, char nChar) - { - Resize(m_nLength + 1); - for (int nJ = m_nLength + 1; nJ > nIndex; --nJ) - m_sData[nJ] = m_sData[nJ - 1]; - m_sData[nIndex] = nChar; - ++m_nLength; - return this; - } - - StringExt *StringExt::Insert(int nIndex, StringExt *seString) - { - int nLen = seString->GetLength(); - Resize(m_nLength + nLen); - for (int nJ = m_nLength; nJ >= nIndex; --nJ) - m_sData[nJ + nLen] = m_sData[nJ]; - memcpy(m_sData + nIndex, seString->GetBuffer(), nLen); - m_nLength += nLen; - return this; - } - - StringExt *StringExt::Insert(int nIndex, const char *sString) - { - int nLen = strlen(sString); - - Resize(m_nLength + nLen); - for (int nJ = m_nLength; nJ >= nIndex; --nJ) - m_sData[nJ + nLen] = m_sData[nJ]; - memcpy(m_sData + nIndex, sString, nLen); - m_nLength += nLen; - return this; - } - - StringExt *StringExt::Insert(int nIndex, const char *sString, int nLength) - { - Resize(m_nLength + nLength); - for (int nJ = m_nLength; nJ >= nIndex; --nJ) - m_sData[nJ + nLength] = m_sData[nJ]; - memcpy(m_sData + nIndex, sString, nLength); - m_nLength += nLength; - return this; - } - - StringExt *StringExt::Delete(int nIndex, int nCount) - { - if (nCount > 0) - { - if (nIndex + nCount > m_nLength) - nCount = m_nLength - nIndex; - for (int nJ = nIndex; nJ <= m_nLength - nCount; ++nJ) - { - m_sData[nJ] = m_sData[nJ + nCount]; - } - Resize(m_nLength -= nCount); - } - return this; - } - - StringExt *StringExt::MakeUpper() - { - for (int nIndex = 0; nIndex < m_nLength; ++nIndex) - { - if (islower(m_sData[nIndex])) - m_sData[nIndex] = toupper(m_sData[nIndex]); - } - return this; - } - - StringExt *StringExt::MakeLower() - { - for (int nIndex = 0; nIndex < m_nLength; ++nIndex) - { - if (isupper(m_sData[nIndex])) - m_sData[nIndex] = tolower(m_sData[nIndex]); - } - return this; - } - - int StringExt::Compare(StringExt *seOther) - { - int nIndex = 0; - char *pThis, *pOther; - - int nThisLen = m_nLength; - int nOtherLen = seOther->m_nLength; - for (nIndex = 0, pThis = m_sData, pOther = seOther->m_sData; nIndex < nThisLen && nIndex < nOtherLen; ++nIndex, ++pThis, ++pOther) - { - int nRes = *pThis - *pOther; - if (0 != nRes) - return nRes; - } - return nThisLen - nOtherLen; - } - - int StringExt::CompareN(StringExt *seOther, int nCount) - { - int nIndex; - char *pThis, *pOther; - - int nThisLen = m_nLength; - int nOtherLen = seOther->m_nLength; - for (nIndex = 0, pThis = m_sData, pOther = seOther->m_sData; nIndex < nThisLen && nIndex < nOtherLen && nIndex < nCount; ++nIndex, ++pThis, ++pOther) - { - int nRes = *pThis - *pOther; - if (0 != nRes) - return nRes; - } - if (nIndex == nCount) - return 0; - return nThisLen - nOtherLen; - } - - int StringExt::Compare(const char *sOther) - { - int nIndex; - const char *pThis, *pOther; - - int nThisLen = m_nLength; - for (nIndex = 0, pThis = m_sData, pOther = sOther; nIndex < nThisLen && *pOther; ++nIndex, ++pThis, ++pOther) - { - int nRes = *pThis - *pOther; - if (0 != nRes) - return nRes; - } - if (nIndex < nThisLen) - return 1; - if (*pOther) - return -1; - return 0; - } - - int StringExt::CompareN(const char *sOther, int nCount) - { - int nIndex; - const char *pThis, *pOther; - - int nThisLen = m_nLength; - for (nIndex = 0, pThis = m_sData, pOther = sOther; nIndex < nThisLen && *pOther && nIndex < nCount; ++nIndex, ++pThis, ++pOther) - { - int nRes = *pThis - *pOther; - if (0 != nRes) - return nRes; - } - if (nIndex == nCount) - return 0; - if (nIndex < nThisLen) - return 1; - if (*pOther) - return -1; - return 0; - } -} \ No newline at end of file diff --git a/PdfReader/old/StringExt.h b/PdfReader/old/StringExt.h deleted file mode 100644 index 90fcca645a..0000000000 --- a/PdfReader/old/StringExt.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_STRING_EXT_H -#define _PDF_READER_STRING_EXT_H - -#include -#include -#include "../../DesktopEditor/common/StringExt.h" -#include - -namespace PdfReader -{ - //--------------------------------------------------------------------------------------- - // WString - аналог BSTR - //--------------------------------------------------------------------------------------- - typedef wchar_t* WString; - - static WString AllocWString(const std::wstring& wsString) - { - int nLen = wsString.length(); - WString wsResult = new wchar_t[nLen + 1]; - wsResult[nLen] = 0x0000; - - for (int nIndex = 0; nIndex < nLen; nIndex++) - { - wsResult[nIndex] = (wchar_t)wsString.at(nIndex); - } - - return wsResult; - } - static WString AllocWString(const wchar_t* wsString) - { - return AllocWString(std::wstring(wsString)); - } - static WString AllocWString(WString wsString) - { - return AllocWString(std::wstring(wsString)); - } - static void FreeWString(WString wString) - { - if (wString) - delete[] wString; - } - - static std::wstring* AStringToPWString(const char* sString) - { - return new std::wstring(NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)sString, (long)strlen(sString))); - } - static std::wstring AStringToWString(const char* sString) - { - return std::wstring(NSStringExt::CConverter::GetUnicodeFromSingleByteString((unsigned char*)sString, (long)strlen(sString))); - } - - - //--------------------------------------------------------------------------------------- - // класс StringExt - аналог CString - //--------------------------------------------------------------------------------------- - - class StringExt - { - - public: - - // Создаем пустую строку. - StringExt(); - - StringExt(std::wstring& wsString); - - StringExt(const wchar_t* wsString); - - // Создаем строку из Сишной строки. - StringExt(const char *sString); - - // Создаем строку из символов в . Данная строка - // может содержать нулевые символы. - StringExt(const char *sString, int nLength); - - // Создаем строку из символов, начиная с , строки . - StringExt(StringExt *seString, int nIndex, int nLength); - - // Копируем строку. - StringExt(StringExt *seString); - StringExt *Copy() - { - return new StringExt(this); - } - - // Соединяем две строки. - StringExt(StringExt *seString1, StringExt *seString2); - - // Переводим целое значение в строку. - static StringExt *FromInt(int nValue); - - // Создаем форматированную строку. Функция подобна printf, но без проблем - // с переполнением строки. Формат выглядит следующим образом: - // {:[][.]} - // где: - // - номер аргумента (нумерация начинается с 0). - // -- PS: сами аргументы должны идти по порядку, а использовать их можно - // многократно и в любом порядке. - // - ширина поля, если она отрицательна, тогда прилежание будет - // сменено на противоположное, а пустые места будут заполнены нулями. - // - количество знаков после запятой - // - тип один из слудющих: - // d, x, o, b -- целое(int) в десятичной, шестнадцатиричной, восьмиричной - // и двоичной системах исчисления - // ud, ux, uo, ub -- тоже самое, только беззнаковое целое(uint) - // ld, lx, lo, lb, uld, ulx, ulo, ulb -- аналогичной long и ulong - // f, g -- double - // c -- char - // s -- string (char *) - // t -- StringExt * - // w -- Пробелы; значение аргументы означает количество пробелов - // Для вывода фигурных скобок надо использовать {{ и }}. - static StringExt *Format(char *sFormat, ...); - static StringExt *FormatV(char *sFormat, va_list sArgList); - - // Деструктор. - ~StringExt(); - - int GetLength() - { - return m_nLength; - } - - // Возвращаем строку в виде char*. - char *GetBuffer() - { - return m_sData; - } - unsigned char *GetUBuffer() - { - return (unsigned char*)m_sData; - } - std::wstring GetWString() - { - return NSStringExt::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)m_sData, m_nLength); - } - - char GetAt(int nIndex) - { - return m_sData[nIndex]; - } - void SetAt(int nIndex, char nChar) - { - m_sData[nIndex] = nChar; - } - - // Очищаем строку. - StringExt *Clear(); - - // Добавляем символ или строку. - StringExt *Append(char nChar); - StringExt *Append(StringExt *seString); - StringExt *Append(const char *sString); - StringExt *Append(const char *sString, int nLength); - - // Добавляем форматированную строку. - StringExt *AppendFormat(char *sFormat, ...); - StringExt *AppendFormatV(char *sFormat, va_list sArgList); - - // Вставляем символ или строку. - StringExt *Insert(int nIndex, char nChar); - StringExt *Insert(int nIndex, StringExt *seString); - StringExt *Insert(int nIndex, const char *sString); - StringExt *Insert(int nIndex, const char *sString, int nLength); - - // Удаляем один символ или массив символов. - StringExt *Delete(int nIndex, int nCount = 1); - - // Делаем в строке все символы большими/маленькими буквами. - StringExt *MakeUpper(); - StringExt *MakeLower(); - - // Сравнение двух строк: -1:< 0:= +1:> - int Compare(StringExt *seString); - int CompareN(StringExt *seString, int nCount); - int Compare(const char *sString); - int CompareN(const char *sString, int nCount); - - private: - - void Resize(int nLength); - - static void FormatInt(long nValue, char *sBuffer, int nBufferSize, bool bZeroFill, int nWidth, int nBase, char **ppData, int *nLen); - static void FormatUInt(unsigned long nValue, char *sBuffer, int nBufferSize, bool bZeroFill, int nWidth, int nBase, char **ppData, int *nLen); - static void FormatDouble(double nValue, char *sBuffer, int nBufferSize, int nPrecision, bool bTrim, char **ppData, int *nLen); - - private: - - int m_nLength; - char *m_sData; - - }; -} - -#endif //_PDF_READER_STRING_EXT_H diff --git a/PdfReader/old/UTF8.h b/PdfReader/old/UTF8.h deleted file mode 100644 index 83a1ecfc58..0000000000 --- a/PdfReader/old/UTF8.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_UTF8_H -#define _PDF_READER_UTF8_H - -namespace PdfReader -{ - static int MapUTF8(Unicode nUnicode, char *sBuffer, int nBufferSize) - { - if (nUnicode <= 0x0000007f) - { - if (nBufferSize < 1) - { - return 0; - } - sBuffer[0] = (char)nUnicode; - return 1; - } - else if (nUnicode <= 0x000007ff) - { - if (nBufferSize < 2) - { - return 0; - } - sBuffer[0] = (char)(0xc0 + (nUnicode >> 6)); - sBuffer[1] = (char)(0x80 + (nUnicode & 0x3f)); - return 2; - } - else if (nUnicode <= 0x0000ffff) - { - if (nBufferSize < 3) - { - return 0; - } - sBuffer[0] = (char)(0xe0 + (nUnicode >> 12)); - sBuffer[1] = (char)(0x80 + ((nUnicode >> 6) & 0x3f)); - sBuffer[2] = (char)(0x80 + (nUnicode & 0x3f)); - return 3; - } - else if (nUnicode <= 0x0010ffff) - { - if (nBufferSize < 4) - { - return 0; - } - sBuffer[0] = (char)(0xf0 + (nUnicode >> 18)); - sBuffer[1] = (char)(0x80 + ((nUnicode >> 12) & 0x3f)); - sBuffer[2] = (char)(0x80 + ((nUnicode >> 6) & 0x3f)); - sBuffer[3] = (char)(0x80 + (nUnicode & 0x3f)); - return 4; - } - else - { - return 0; - } - } - - static int MapUCS2(Unicode nUnicode, char *sBuffer, int nBufferSize) - { - if (nUnicode <= 0xffff) - { - if (nBufferSize < 2) - { - return 0; - } - sBuffer[0] = (char)((nUnicode >> 8) & 0xff); - sBuffer[1] = (char)(nUnicode & 0xff); - return 2; - } - else - { - return 0; - } - } -} - -#endif // _PDF_READER_UTF8_H \ No newline at end of file diff --git a/PdfReader/old/UnicodeMap.cpp b/PdfReader/old/UnicodeMap.cpp deleted file mode 100644 index d61a063492..0000000000 --- a/PdfReader/old/UnicodeMap.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include "MemoryUtils.h" -#include "File.h" -#include "StringExt.h" -#include "List.h" -#include "GlobalParams.h" -#include "UnicodeMap.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" -#include "CharTypes.h" - -//------------------------------------------------------------------------------------------------------------------------------- - -#define maxExtCode 16 - -namespace PdfReader -{ - struct UnicodeMapExt - { - Unicode nUnicode; - char arrCode[maxExtCode]; - unsigned int unBytesCount; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - - UnicodeMap *UnicodeMap::Parse(StringExt *seEncodingName, GlobalParams *pGlobalParams) - { - FILE *pFile = NULL; - if (pGlobalParams && !(pFile = pGlobalParams->GetUnicodeMapFile(seEncodingName))) - { - // TO DO: Error "Couldn't find UnicodeMap file for the encoding" - return NULL; - } - - UnicodeMap *pMap = new UnicodeMap(seEncodingName->Copy()); - - int nSize = 8; - pMap->m_pRanges = (UnicodeMapRange *)MemUtilsMallocArray(nSize, sizeof(UnicodeMapRange)); - int nEMapsSize = 0; - - int nLineNum = 1; - char sBuffer[256]; - while (GetLine(sBuffer, sizeof(sBuffer), pFile)) - { - char *sToken1, *sToken2, *sToken3; - if ((sToken1 = strtok(sBuffer, " \t\r\n")) && (sToken2 = strtok(NULL, " \t\r\n"))) - { - if (!(sToken3 = strtok(NULL, " \t\r\n"))) - { - sToken3 = sToken2; - sToken2 = sToken1; - } - int nBytesCount = strlen(sToken3) / 2; - - if (nBytesCount <= 4) - { - if (pMap->m_nLen == nSize) - { - nSize *= 2; - pMap->m_pRanges = (UnicodeMapRange *)MemUtilsReallocArray(pMap->m_pRanges, nSize, sizeof(UnicodeMapRange)); - } - UnicodeMapRange *pRange = &pMap->m_pRanges[pMap->m_nLen]; - sscanf(sToken1, "%x", &pRange->nStart); - sscanf(sToken2, "%x", &pRange->nEnd); - sscanf(sToken3, "%x", &pRange->unCode); - pRange->nBytesCount = nBytesCount; - ++pMap->m_nLen; - } - else if (sToken2 == sToken1) - { - if (pMap->m_nEMapsLen == nEMapsSize) - { - nEMapsSize += 16; - pMap->m_pEMaps = (UnicodeMapExt *)MemUtilsReallocArray(pMap->m_pEMaps, nEMapsSize, sizeof(UnicodeMapExt)); - } - UnicodeMapExt *pEMap = &pMap->m_pEMaps[pMap->m_nEMapsLen]; - sscanf(sToken1, "%x", &pEMap->nUnicode); - for (int nIndex = 0; nIndex < nBytesCount; ++nIndex) - { - int nValue = 0; - sscanf(sToken3 + nIndex * 2, "%2x", &nValue); - pEMap->arrCode[nIndex] = (char)nValue; - } - pEMap->unBytesCount = nBytesCount; - ++pMap->m_nEMapsLen; - } - else - { - // TO DO: Error "Bad line in unicodeMap file for encoding" - } - } - else - { - // TO DO: Error "Bad line in unicodeMap file for encoding" - } - ++nLineNum; - } - - fclose(pFile); - - return pMap; - } - - UnicodeMap::UnicodeMap(StringExt *seEncodingName) - { - m_seEncodingName = seEncodingName; - m_bUnicodeOut = false; - m_eType = unicodeMapUser; - - m_pRanges = NULL; - m_nLen = 0; - - m_pEMaps = NULL; - m_nEMapsLen = 0; - - m_nRefCount = 1; - - m_oCS.InitializeCriticalSection(); - } - - UnicodeMap::UnicodeMap(char *sEncodingName, bool bUnicodeOut, UnicodeMapRange *pRanges, int nLen) - { - m_seEncodingName = new StringExt(sEncodingName); - m_bUnicodeOut = bUnicodeOut; - m_eType = unicodeMapResident; - - m_pRanges = pRanges; - m_nLen = nLen; - - m_pEMaps = NULL; - m_nEMapsLen = 0; - - m_nRefCount = 1; - - m_oCS.InitializeCriticalSection(); - } - - UnicodeMap::UnicodeMap(char *sEncodingName, bool bUnicodeOut, UnicodeMapFunc pFunction) - { - m_seEncodingName = new StringExt(sEncodingName); - m_bUnicodeOut = bUnicodeOut; - m_eType = unicodeMapFunc; - - m_pFunction = pFunction; - - m_pEMaps = NULL; - m_nEMapsLen = 0; - - m_nRefCount = 1; - - m_oCS.InitializeCriticalSection(); - } - - UnicodeMap::~UnicodeMap() - { - if (m_seEncodingName) - delete m_seEncodingName; - - if (m_eType == unicodeMapUser && m_pRanges) - { - MemUtilsFree(m_pRanges); - } - - if (m_pEMaps) - { - MemUtilsFree(m_pEMaps); - } - - m_oCS.DeleteCriticalSection(); - } - - void UnicodeMap::AddRef() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - - ++m_nRefCount; - - RELEASEOBJECT(pCS); - } - - void UnicodeMap::Release() - { - CTemporaryCS *pCS = new CTemporaryCS(&m_oCS); - - bool bDone = (--m_nRefCount == 0); - - RELEASEOBJECT(pCS); - - if (bDone) - { - delete this; - } - } - - bool UnicodeMap::Match(StringExt *seEncodingName) - { - return (!m_seEncodingName->Compare(seEncodingName)); - } - - int UnicodeMap::MapUnicode(Unicode nUnicode, char *sBuffer, int nBufferSize) - { - if (m_eType == unicodeMapFunc) - { - return (*m_pFunction)(nUnicode, sBuffer, nBufferSize); - } - - int nFirst = 0; - int nLast = m_nLen; - if (nUnicode >= m_pRanges[nFirst].nStart) - { - // m_pRanges[nFirst].nStart <= nUnicode < m_pRanges[nLast].nStart - while (nLast - nFirst > 1) - { - int nMiddle = (nFirst + nLast) / 2; - if (nUnicode >= m_pRanges[nMiddle].nStart) - { - nFirst = nMiddle; - } - else if (nUnicode < m_pRanges[nMiddle].nStart) - { - nLast = nMiddle; - } - } - - if (nUnicode <= m_pRanges[nFirst].nEnd) - { - int nLen = m_pRanges[nFirst].nBytesCount; - if (nLen > nBufferSize) - { - return 0; - } - unsigned int unCode = m_pRanges[nFirst].unCode + (nUnicode - m_pRanges[nFirst].nStart); - for (int nIndex = nLen - 1; nIndex >= 0; --nIndex) - { - sBuffer[nIndex] = (char)(unCode & 0xff); - unCode >>= 8; - } - return nLen; - } - } - - for (int nIndex = 0; nIndex < m_nEMapsLen; ++nIndex) - { - if (m_pEMaps[nIndex].nUnicode == nUnicode) - { - int nLen = m_pEMaps[nIndex].unBytesCount; - for (int nJ = 0; nJ < nLen; ++nJ) - { - sBuffer[nJ] = m_pEMaps[nIndex].arrCode[nJ]; - } - return nLen; - } - } - - return 0; - } - - //------------------------------------------------------------------------------------------------------------------------------- - - UnicodeMapCache::UnicodeMapCache() - { - for (int nIndex = 0; nIndex < unicodeMapCacheSize; ++nIndex) - { - m_ppCache[nIndex] = NULL; - } - } - - UnicodeMapCache::~UnicodeMapCache() - { - for (int nIndex = 0; nIndex < unicodeMapCacheSize; ++nIndex) - { - if (m_ppCache[nIndex]) - { - m_ppCache[nIndex]->Release(); - } - } - } - - UnicodeMap *UnicodeMapCache::GetUnicodeMap(StringExt *seEncodingName, GlobalParams *pGlobalParams) - { - if (m_ppCache[0] && m_ppCache[0]->Match(seEncodingName)) - { - m_ppCache[0]->AddRef(); - return m_ppCache[0]; - } - UnicodeMap *pMap = NULL; - for (int nIndex = 1; nIndex < unicodeMapCacheSize; ++nIndex) - { - if (m_ppCache[nIndex] && m_ppCache[nIndex]->Match(seEncodingName)) - { - pMap = m_ppCache[nIndex]; - for (int nJ = nIndex; nJ >= 1; --nJ) - { - m_ppCache[nJ] = m_ppCache[nJ - 1]; - } - m_ppCache[0] = pMap; - pMap->AddRef(); - return pMap; - } - } - if ((pMap = UnicodeMap::Parse(seEncodingName, pGlobalParams))) - { - if (m_ppCache[unicodeMapCacheSize - 1]) - { - m_ppCache[unicodeMapCacheSize - 1]->Release(); - } - for (int nJ = unicodeMapCacheSize - 1; nJ >= 1; --nJ) - { - m_ppCache[nJ] = m_ppCache[nJ - 1]; - } - m_ppCache[0] = pMap; - pMap->AddRef(); - return pMap; - } - return NULL; - } -} diff --git a/PdfReader/old/UnicodeMap.h b/PdfReader/old/UnicodeMap.h deleted file mode 100644 index a8b2bb7104..0000000000 --- a/PdfReader/old/UnicodeMap.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_UNICODE_MAP_H -#define _PDF_READER_UNICODE_MAP_H - -#include "CharTypes.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" - -namespace PdfReader -{ - class StringExt; - - //------------------------------------------------------------------------------------------------------------------------------- - - enum UnicodeMapType - { - unicodeMapUser, // Чтение из файла - unicodeMapResident, // Статический список - unicodeMapFunc // Указатель на функцию - }; - - typedef int(*UnicodeMapFunc)(Unicode nUnicode, char *sBuffer, int nBufferSize); - - struct UnicodeMapRange - { - Unicode nStart; // Диапазон юникодных символов - Unicode nEnd; // - unsigned int unCode; // Первый код - unsigned int nBytesCount; // - }; - - struct UnicodeMapExt; - - //------------------------------------------------------------------------------------------------------------------------------- - // UnicodeMap - //------------------------------------------------------------------------------------------------------------------------------- - - class UnicodeMap - { - public: - - // Создаем UnicodeMap по имени . Устанавливаем счетчик ссылок равный 1. - static UnicodeMap *Parse(StringExt *seEncodingName, GlobalParams *pGlobalParams); - - // Создаем Resident UnicodeMap. - UnicodeMap(char *sEncodingName, bool bUnicodeOut, UnicodeMapRange *pRanges, int nLen); - - // Создаем Resident UnicodeMap, который использует функцию вместо диапазона значений. - UnicodeMap(char *sEncodingName, bool bUnicodeOut, UnicodeMapFunc pFunction); - - ~UnicodeMap(); - - // Счетчик ссылок - void AddRef(); - void Release(); - - StringExt *GetEncodingName() - { - return m_seEncodingName; - } - - bool IsUnicode() - { - return m_bUnicodeOut; - } - - - // Совпадают ли названия кодировок? - bool Match(StringExt *seEncodingName); - - // Находим образ текущего юникодного значения в кодировке. Заполняем результатом и возвращаем - // количество используемых байт. Никаких строковых разделителей (типа \0) не пишем. - int MapUnicode(Unicode nUnicode, char *sBuffer, int nBufferSize); - - private: - - UnicodeMap(StringExt *seEncodingName); - - private: - - StringExt *m_seEncodingName; - UnicodeMapType m_eType; - bool m_bUnicodeOut; - union - { - UnicodeMapRange *m_pRanges; // Для типов: User, Resident - UnicodeMapFunc m_pFunction; // Для типа Func - }; - int m_nLen; // User, Resident - UnicodeMapExt *m_pEMaps; // User - int m_nEMapsLen; // User - - int m_nRefCount; - - NSCriticalSection::CRITICAL_SECTION m_oCS; - }; - - //------------------------------------------------------------------------------------------------------------------------------- - // UnicodeMapCache - //------------------------------------------------------------------------------------------------------------------------------- - -#define unicodeMapCacheSize 4 - - class UnicodeMapCache - { - public: - - UnicodeMapCache(); - ~UnicodeMapCache(); - - UnicodeMap *GetUnicodeMap(StringExt *seEncodingName, GlobalParams *pGlobalParams); - - private: - - UnicodeMap *m_ppCache[unicodeMapCacheSize]; - }; -} - -#endif // _PDF_READER_UNICODE_MAP_H diff --git a/PdfReader/old/UnicodeMapTables.h b/PdfReader/old/UnicodeMapTables.h deleted file mode 100644 index da04b06067..0000000000 --- a/PdfReader/old/UnicodeMapTables.h +++ /dev/null @@ -1,396 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_UNICODE_MAP_TABLES_H -#define _PDF_READER_UNICODE_MAP_TABLES_H - -namespace PdfReader -{ - static UnicodeMapRange c_arrLatin1UnicodeMapRanges[] = - { - { 0x000a, 0x000a, 0x0a, 1 }, - { 0x000c, 0x000d, 0x0c, 1 }, - { 0x0020, 0x007e, 0x20, 1 }, - { 0x00a0, 0x00a0, 0x20, 1 }, - { 0x00a1, 0x00ac, 0xa1, 1 }, - { 0x00ae, 0x00ff, 0xae, 1 }, - { 0x010c, 0x010c, 0x43, 1 }, - { 0x010d, 0x010d, 0x63, 1 }, - { 0x0131, 0x0131, 0x69, 1 }, - { 0x0141, 0x0141, 0x4c, 1 }, - { 0x0142, 0x0142, 0x6c, 1 }, - { 0x0152, 0x0152, 0x4f45, 2 }, - { 0x0153, 0x0153, 0x6f65, 2 }, - { 0x0160, 0x0160, 0x53, 1 }, - { 0x0161, 0x0161, 0x73, 1 }, - { 0x0178, 0x0178, 0x59, 1 }, - { 0x017d, 0x017d, 0x5a, 1 }, - { 0x017e, 0x017e, 0x7a, 1 }, - { 0x02c6, 0x02c6, 0x5e, 1 }, - { 0x02da, 0x02da, 0xb0, 1 }, - { 0x02dc, 0x02dc, 0x7e, 1 }, - { 0x2013, 0x2013, 0xad, 1 }, - { 0x2014, 0x2014, 0x2d2d, 2 }, - { 0x2018, 0x2018, 0x60, 1 }, - { 0x2019, 0x2019, 0x27, 1 }, - { 0x201a, 0x201a, 0x2c, 1 }, - { 0x201c, 0x201c, 0x22, 1 }, - { 0x201d, 0x201d, 0x22, 1 }, - { 0x201e, 0x201e, 0x2c2c, 2 }, - { 0x2022, 0x2022, 0xb7, 1 }, - { 0x2026, 0x2026, 0x2e2e2e, 3 }, - { 0x2039, 0x2039, 0x3c, 1 }, - { 0x203a, 0x203a, 0x3e, 1 }, - { 0x2044, 0x2044, 0x2f, 1 }, - { 0x2122, 0x2122, 0x544d, 2 }, - { 0x2212, 0x2212, 0x2d, 1 }, - { 0xf6f9, 0xf6f9, 0x4c, 1 }, - { 0xf6fa, 0xf6fa, 0x4f45, 2 }, - { 0xf6fc, 0xf6fc, 0xb0, 1 }, - { 0xf6fd, 0xf6fd, 0x53, 1 }, - { 0xf6fe, 0xf6fe, 0x7e, 1 }, - { 0xf6ff, 0xf6ff, 0x5a, 1 }, - { 0xf721, 0xf721, 0x21, 1 }, - { 0xf724, 0xf724, 0x24, 1 }, - { 0xf726, 0xf726, 0x26, 1 }, - { 0xf730, 0xf739, 0x30, 1 }, - { 0xf73f, 0xf73f, 0x3f, 1 }, - { 0xf761, 0xf77a, 0x41, 1 }, - { 0xf7a1, 0xf7a2, 0xa1, 1 }, - { 0xf7bf, 0xf7bf, 0xbf, 1 }, - { 0xf7e0, 0xf7f6, 0xc0, 1 }, - { 0xf7f8, 0xf7fe, 0xd8, 1 }, - { 0xf7ff, 0xf7ff, 0x59, 1 }, - { 0xfb00, 0xfb00, 0x6666, 2 }, - { 0xfb01, 0xfb01, 0x6669, 2 }, - { 0xfb02, 0xfb02, 0x666c, 2 }, - { 0xfb03, 0xfb03, 0x666669, 3 }, - { 0xfb04, 0xfb04, 0x66666c, 3 } - }; -#define Latin1UnicodeMapLen (sizeof(c_arrLatin1UnicodeMapRanges) / sizeof(UnicodeMapRange)) - - static UnicodeMapRange c_arrASCII7UnicodeMapRanges[] = - { - { 0x000a, 0x000a, 0x0a, 1 }, - { 0x000c, 0x000d, 0x0c, 1 }, - { 0x0020, 0x005f, 0x20, 1 }, - { 0x0061, 0x007e, 0x61, 1 }, - { 0x00a6, 0x00a6, 0x7c, 1 }, - { 0x00a9, 0x00a9, 0x286329, 3 }, - { 0x00ae, 0x00ae, 0x285229, 3 }, - { 0x00b7, 0x00b7, 0x2a, 1 }, - { 0x00bc, 0x00bc, 0x312f34, 3 }, - { 0x00bd, 0x00bd, 0x312f32, 3 }, - { 0x00be, 0x00be, 0x332f34, 3 }, - { 0x00c0, 0x00c0, 0x41, 1 }, - { 0x00c1, 0x00c1, 0x41, 1 }, - { 0x00c2, 0x00c2, 0x41, 1 }, - { 0x00c3, 0x00c3, 0x41, 1 }, - { 0x00c4, 0x00c4, 0x41, 1 }, - { 0x00c5, 0x00c5, 0x41, 1 }, - { 0x00c6, 0x00c6, 0x4145, 2 }, - { 0x00c7, 0x00c7, 0x43, 1 }, - { 0x00c8, 0x00c8, 0x45, 1 }, - { 0x00c9, 0x00c9, 0x45, 1 }, - { 0x00ca, 0x00ca, 0x45, 1 }, - { 0x00cb, 0x00cb, 0x45, 1 }, - { 0x00cc, 0x00cc, 0x49, 1 }, - { 0x00cd, 0x00cd, 0x49, 1 }, - { 0x00ce, 0x00ce, 0x49, 1 }, - { 0x00cf, 0x00cf, 0x49, 1 }, - { 0x00d1, 0x00d2, 0x4e, 1 }, - { 0x00d3, 0x00d3, 0x4f, 1 }, - { 0x00d4, 0x00d4, 0x4f, 1 }, - { 0x00d5, 0x00d5, 0x4f, 1 }, - { 0x00d6, 0x00d6, 0x4f, 1 }, - { 0x00d7, 0x00d7, 0x78, 1 }, - { 0x00d8, 0x00d8, 0x4f, 1 }, - { 0x00d9, 0x00d9, 0x55, 1 }, - { 0x00da, 0x00da, 0x55, 1 }, - { 0x00db, 0x00db, 0x55, 1 }, - { 0x00dc, 0x00dc, 0x55, 1 }, - { 0x00dd, 0x00dd, 0x59, 1 }, - { 0x00e0, 0x00e0, 0x61, 1 }, - { 0x00e1, 0x00e1, 0x61, 1 }, - { 0x00e2, 0x00e2, 0x61, 1 }, - { 0x00e3, 0x00e3, 0x61, 1 }, - { 0x00e4, 0x00e4, 0x61, 1 }, - { 0x00e5, 0x00e5, 0x61, 1 }, - { 0x00e6, 0x00e6, 0x6165, 2 }, - { 0x00e7, 0x00e7, 0x63, 1 }, - { 0x00e8, 0x00e8, 0x65, 1 }, - { 0x00e9, 0x00e9, 0x65, 1 }, - { 0x00ea, 0x00ea, 0x65, 1 }, - { 0x00eb, 0x00eb, 0x65, 1 }, - { 0x00ec, 0x00ec, 0x69, 1 }, - { 0x00ed, 0x00ed, 0x69, 1 }, - { 0x00ee, 0x00ee, 0x69, 1 }, - { 0x00ef, 0x00ef, 0x69, 1 }, - { 0x00f1, 0x00f2, 0x6e, 1 }, - { 0x00f3, 0x00f3, 0x6f, 1 }, - { 0x00f4, 0x00f4, 0x6f, 1 }, - { 0x00f5, 0x00f5, 0x6f, 1 }, - { 0x00f6, 0x00f6, 0x6f, 1 }, - { 0x00f7, 0x00f7, 0x2f, 1 }, - { 0x00f8, 0x00f8, 0x6f, 1 }, - { 0x00f9, 0x00f9, 0x75, 1 }, - { 0x00fa, 0x00fa, 0x75, 1 }, - { 0x00fb, 0x00fb, 0x75, 1 }, - { 0x00fc, 0x00fc, 0x75, 1 }, - { 0x00fd, 0x00fd, 0x79, 1 }, - { 0x00ff, 0x00ff, 0x79, 1 }, - { 0x0131, 0x0131, 0x69, 1 }, - { 0x0141, 0x0141, 0x4c, 1 }, - { 0x0152, 0x0152, 0x4f45, 2 }, - { 0x0153, 0x0153, 0x6f65, 2 }, - { 0x0160, 0x0160, 0x53, 1 }, - { 0x0178, 0x0178, 0x59, 1 }, - { 0x017d, 0x017d, 0x5a, 1 }, - { 0x2013, 0x2013, 0x2d, 1 }, - { 0x2014, 0x2014, 0x2d2d, 2 }, - { 0x2018, 0x2018, 0x60, 1 }, - { 0x2019, 0x2019, 0x27, 1 }, - { 0x201c, 0x201c, 0x22, 1 }, - { 0x201d, 0x201d, 0x22, 1 }, - { 0x2022, 0x2022, 0x2a, 1 }, - { 0x2026, 0x2026, 0x2e2e2e, 3 }, - { 0x2122, 0x2122, 0x544d, 2 }, - { 0x2212, 0x2212, 0x2d, 1 }, - { 0xf6f9, 0xf6f9, 0x4c, 1 }, - { 0xf6fa, 0xf6fa, 0x4f45, 2 }, - { 0xf6fd, 0xf6fd, 0x53, 1 }, - { 0xf6fe, 0xf6fe, 0x7e, 1 }, - { 0xf6ff, 0xf6ff, 0x5a, 1 }, - { 0xf721, 0xf721, 0x21, 1 }, - { 0xf724, 0xf724, 0x24, 1 }, - { 0xf726, 0xf726, 0x26, 1 }, - { 0xf730, 0xf739, 0x30, 1 }, - { 0xf73f, 0xf73f, 0x3f, 1 }, - { 0xf761, 0xf77a, 0x41, 1 }, - { 0xf7e0, 0xf7e0, 0x41, 1 }, - { 0xf7e1, 0xf7e1, 0x41, 1 }, - { 0xf7e2, 0xf7e2, 0x41, 1 }, - { 0xf7e3, 0xf7e3, 0x41, 1 }, - { 0xf7e4, 0xf7e4, 0x41, 1 }, - { 0xf7e5, 0xf7e5, 0x41, 1 }, - { 0xf7e6, 0xf7e6, 0x4145, 2 }, - { 0xf7e7, 0xf7e7, 0x43, 1 }, - { 0xf7e8, 0xf7e8, 0x45, 1 }, - { 0xf7e9, 0xf7e9, 0x45, 1 }, - { 0xf7ea, 0xf7ea, 0x45, 1 }, - { 0xf7eb, 0xf7eb, 0x45, 1 }, - { 0xf7ec, 0xf7ec, 0x49, 1 }, - { 0xf7ed, 0xf7ed, 0x49, 1 }, - { 0xf7ee, 0xf7ee, 0x49, 1 }, - { 0xf7ef, 0xf7ef, 0x49, 1 }, - { 0xf7f1, 0xf7f2, 0x4e, 1 }, - { 0xf7f3, 0xf7f3, 0x4f, 1 }, - { 0xf7f4, 0xf7f4, 0x4f, 1 }, - { 0xf7f5, 0xf7f5, 0x4f, 1 }, - { 0xf7f6, 0xf7f6, 0x4f, 1 }, - { 0xf7f8, 0xf7f8, 0x4f, 1 }, - { 0xf7f9, 0xf7f9, 0x55, 1 }, - { 0xf7fa, 0xf7fa, 0x55, 1 }, - { 0xf7fb, 0xf7fb, 0x55, 1 }, - { 0xf7fc, 0xf7fc, 0x55, 1 }, - { 0xf7fd, 0xf7fd, 0x59, 1 }, - { 0xf7ff, 0xf7ff, 0x59, 1 }, - { 0xfb00, 0xfb00, 0x6666, 2 }, - { 0xfb01, 0xfb01, 0x6669, 2 }, - { 0xfb02, 0xfb02, 0x666c, 2 }, - { 0xfb03, 0xfb03, 0x666669, 3 }, - { 0xfb04, 0xfb04, 0x66666c, 3 } - }; -#define ASCII7UnicodeMapLen (sizeof(c_arrASCII7UnicodeMapRanges) / sizeof(UnicodeMapRange)) - - static UnicodeMapRange c_arrSymbolUnicodeMapRanges[] = - { - { 0x0020, 0x0021, 0x20, 1 }, - { 0x0023, 0x0023, 0x23, 1 }, - { 0x0025, 0x0026, 0x25, 1 }, - { 0x0028, 0x0029, 0x28, 1 }, - { 0x002b, 0x002c, 0x2b, 1 }, - { 0x002e, 0x003f, 0x2e, 1 }, - { 0x005b, 0x005b, 0x5b, 1 }, - { 0x005d, 0x005d, 0x5d, 1 }, - { 0x005f, 0x005f, 0x5f, 1 }, - { 0x007b, 0x007d, 0x7b, 1 }, - { 0x00ac, 0x00ac, 0xd8, 1 }, - { 0x00b0, 0x00b1, 0xb0, 1 }, - { 0x00b5, 0x00b5, 0x6d, 1 }, - { 0x00d7, 0x00d7, 0xb4, 1 }, - { 0x00f7, 0x00f7, 0xb8, 1 }, - { 0x0192, 0x0192, 0xa6, 1 }, - { 0x0391, 0x0392, 0x41, 1 }, - { 0x0393, 0x0393, 0x47, 1 }, - { 0x0395, 0x0395, 0x45, 1 }, - { 0x0396, 0x0396, 0x5a, 1 }, - { 0x0397, 0x0397, 0x48, 1 }, - { 0x0398, 0x0398, 0x51, 1 }, - { 0x0399, 0x0399, 0x49, 1 }, - { 0x039a, 0x039d, 0x4b, 1 }, - { 0x039e, 0x039e, 0x58, 1 }, - { 0x039f, 0x03a0, 0x4f, 1 }, - { 0x03a1, 0x03a1, 0x52, 1 }, - { 0x03a3, 0x03a5, 0x53, 1 }, - { 0x03a6, 0x03a6, 0x46, 1 }, - { 0x03a7, 0x03a7, 0x43, 1 }, - { 0x03a8, 0x03a8, 0x59, 1 }, - { 0x03b1, 0x03b2, 0x61, 1 }, - { 0x03b3, 0x03b3, 0x67, 1 }, - { 0x03b4, 0x03b5, 0x64, 1 }, - { 0x03b6, 0x03b6, 0x7a, 1 }, - { 0x03b7, 0x03b7, 0x68, 1 }, - { 0x03b8, 0x03b8, 0x71, 1 }, - { 0x03b9, 0x03b9, 0x69, 1 }, - { 0x03ba, 0x03bb, 0x6b, 1 }, - { 0x03bd, 0x03bd, 0x6e, 1 }, - { 0x03be, 0x03be, 0x78, 1 }, - { 0x03bf, 0x03c0, 0x6f, 1 }, - { 0x03c1, 0x03c1, 0x72, 1 }, - { 0x03c2, 0x03c2, 0x56, 1 }, - { 0x03c3, 0x03c5, 0x73, 1 }, - { 0x03c6, 0x03c6, 0x66, 1 }, - { 0x03c7, 0x03c7, 0x63, 1 }, - { 0x03c8, 0x03c8, 0x79, 1 }, - { 0x03c9, 0x03c9, 0x77, 1 }, - { 0x03d1, 0x03d1, 0x4a, 1 }, - { 0x03d2, 0x03d2, 0xa1, 1 }, - { 0x03d5, 0x03d5, 0x6a, 1 }, - { 0x03d6, 0x03d6, 0x76, 1 }, - { 0x2022, 0x2022, 0xb7, 1 }, - { 0x2026, 0x2026, 0xbc, 1 }, - { 0x2032, 0x2032, 0xa2, 1 }, - { 0x2033, 0x2033, 0xb2, 1 }, - { 0x2044, 0x2044, 0xa4, 1 }, - { 0x2111, 0x2111, 0xc1, 1 }, - { 0x2118, 0x2118, 0xc3, 1 }, - { 0x211c, 0x211c, 0xc2, 1 }, - { 0x2126, 0x2126, 0x57, 1 }, - { 0x2135, 0x2135, 0xc0, 1 }, - { 0x2190, 0x2193, 0xac, 1 }, - { 0x2194, 0x2194, 0xab, 1 }, - { 0x21b5, 0x21b5, 0xbf, 1 }, - { 0x21d0, 0x21d3, 0xdc, 1 }, - { 0x21d4, 0x21d4, 0xdb, 1 }, - { 0x2200, 0x2200, 0x22, 1 }, - { 0x2202, 0x2202, 0xb6, 1 }, - { 0x2203, 0x2203, 0x24, 1 }, - { 0x2205, 0x2205, 0xc6, 1 }, - { 0x2206, 0x2206, 0x44, 1 }, - { 0x2207, 0x2207, 0xd1, 1 }, - { 0x2208, 0x2209, 0xce, 1 }, - { 0x220b, 0x220b, 0x27, 1 }, - { 0x220f, 0x220f, 0xd5, 1 }, - { 0x2211, 0x2211, 0xe5, 1 }, - { 0x2212, 0x2212, 0x2d, 1 }, - { 0x2217, 0x2217, 0x2a, 1 }, - { 0x221a, 0x221a, 0xd6, 1 }, - { 0x221d, 0x221d, 0xb5, 1 }, - { 0x221e, 0x221e, 0xa5, 1 }, - { 0x2220, 0x2220, 0xd0, 1 }, - { 0x2227, 0x2228, 0xd9, 1 }, - { 0x2229, 0x222a, 0xc7, 1 }, - { 0x222b, 0x222b, 0xf2, 1 }, - { 0x2234, 0x2234, 0x5c, 1 }, - { 0x223c, 0x223c, 0x7e, 1 }, - { 0x2245, 0x2245, 0x40, 1 }, - { 0x2248, 0x2248, 0xbb, 1 }, - { 0x2260, 0x2261, 0xb9, 1 }, - { 0x2264, 0x2264, 0xa3, 1 }, - { 0x2265, 0x2265, 0xb3, 1 }, - { 0x2282, 0x2282, 0xcc, 1 }, - { 0x2283, 0x2283, 0xc9, 1 }, - { 0x2284, 0x2284, 0xcb, 1 }, - { 0x2286, 0x2286, 0xcd, 1 }, - { 0x2287, 0x2287, 0xca, 1 }, - { 0x2295, 0x2295, 0xc5, 1 }, - { 0x2297, 0x2297, 0xc4, 1 }, - { 0x22a5, 0x22a5, 0x5e, 1 }, - { 0x22c5, 0x22c5, 0xd7, 1 }, - { 0x2320, 0x2320, 0xf3, 1 }, - { 0x2321, 0x2321, 0xf5, 1 }, - { 0x2329, 0x2329, 0xe1, 1 }, - { 0x232a, 0x232a, 0xf1, 1 }, - { 0x25ca, 0x25ca, 0xe0, 1 }, - { 0x2660, 0x2660, 0xaa, 1 }, - { 0x2663, 0x2663, 0xa7, 1 }, - { 0x2665, 0x2665, 0xa9, 1 }, - { 0x2666, 0x2666, 0xa8, 1 }, - { 0xf6d9, 0xf6d9, 0xd3, 1 }, - { 0xf6da, 0xf6da, 0xd2, 1 }, - { 0xf6db, 0xf6db, 0xd4, 1 }, - { 0xf8e5, 0xf8e5, 0x60, 1 }, - { 0xf8e6, 0xf8e7, 0xbd, 1 }, - { 0xf8e8, 0xf8ea, 0xe2, 1 }, - { 0xf8eb, 0xf8f4, 0xe6, 1 }, - { 0xf8f5, 0xf8f5, 0xf4, 1 }, - { 0xf8f6, 0xf8fe, 0xf6, 1 } - }; -#define SymbolUnicodeMapLen (sizeof(c_arrSymbolUnicodeMapRanges) / sizeof(UnicodeMapRange)) - - static UnicodeMapRange c_arrZapfDingbatsUnicodeMapRanges[] = - { - { 0x0020, 0x0020, 0x20, 1 }, - { 0x2192, 0x2192, 0xd5, 1 }, - { 0x2194, 0x2195, 0xd6, 1 }, - { 0x2460, 0x2469, 0xac, 1 }, - { 0x25a0, 0x25a0, 0x6e, 1 }, - { 0x25b2, 0x25b2, 0x73, 1 }, - { 0x25bc, 0x25bc, 0x74, 1 }, - { 0x25c6, 0x25c6, 0x75, 1 }, - { 0x25cf, 0x25cf, 0x6c, 1 }, - { 0x25d7, 0x25d7, 0x77, 1 }, - { 0x2605, 0x2605, 0x48, 1 }, - { 0x260e, 0x260e, 0x25, 1 }, - { 0x261b, 0x261b, 0x2a, 1 }, - { 0x261e, 0x261e, 0x2b, 1 }, - { 0x2660, 0x2660, 0xab, 1 }, - { 0x2663, 0x2663, 0xa8, 1 }, - { 0x2665, 0x2665, 0xaa, 1 }, - { 0x2666, 0x2666, 0xa9, 1 }, - { 0x2701, 0x2704, 0x21, 1 }, - { 0x2706, 0x2709, 0x26, 1 }, - { 0x270c, 0x2727, 0x2c, 1 }, - { 0x2729, 0x274b, 0x49, 1 }, - { 0x274d, 0x274d, 0x6d, 1 }, - { 0x274f, 0x2752, 0x6f, 1 }, - { 0x2756, 0x2756, 0x76, 1 }, - { 0x2758, 0x275e, 0x78, 1 }, - { 0x2761, 0x2767, 0xa1, 1 }, - { 0x2776, 0x2794, 0xb6, 1 }, - { 0x2798, 0x27af, 0xd8, 1 }, - { 0x27b1, 0x27be, 0xf1, 1 } - }; -#define ZapfDingbatsUnicodeMapLen (sizeof(c_arrZapfDingbatsUnicodeMapRanges) / sizeof(UnicodeMapRange)) -} - -#endif // _PDF_READER_UNICODE_MAP_TABLES_H \ No newline at end of file diff --git a/PdfReader/old/XRef.cpp b/PdfReader/old/XRef.cpp deleted file mode 100644 index 7f5501ce80..0000000000 --- a/PdfReader/old/XRef.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include -#include -#include -#include -#include "MemoryUtils.h" -#include "Object.h" -#include "Stream.h" -#include "Lexer.h" -#include "Parser.h" -#include "Dict.h" -#include "ErrorConstants.h" -#include "XRef.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" - -namespace PdfReader -{ -#define XrefSearchSize 1024 // Читаем столько байт, начиная с конца файла, чтобы найти 'startxref' - - //--------------------------------------------------------------------------------------------------------------------------- - // Permission bits - //--------------------------------------------------------------------------------------------------------------------------- - -#define PermissionPrint ( 1 << 2 ) -#define PermissionChange ( 1 << 3 ) -#define PermissionCopy ( 1 << 4 ) -#define PermissionNotes ( 1 << 5 ) -#define DefaultPermissionFlags 0xfffc - - //--------------------------------------------------------------------------------------------------------------------------- - // ObjectStream - //--------------------------------------------------------------------------------------------------------------------------- - - class ObjectStream - { - public: - - ObjectStream(XRef *pXref, int nObjectStreamNum); - - ~ObjectStream(); - - int GetObjectStreamNum() - { - return m_nObjectStreamNum; - } - - Object *GetObject(int nObjectIndex, int nObjectNum, Object *pObject); - - private: - - int m_nObjectStreamNum; // Порядковый номер объекта(Stream Objects) - int m_nObjectsCount; // Количество объектов в потоке - Object *m_arrObjects; // Список объектов в потоке - int *m_arrObjectsNums; // Порядковые номера объектов в потоке - - }; - - ObjectStream::ObjectStream(XRef *pXref, int nObjectStreamNum) - { - Object oTempObject1, oTempObject2; - - m_nObjectStreamNum = nObjectStreamNum; - m_nObjectsCount = 0; - m_arrObjects = NULL; - m_arrObjectsNums = NULL; - - Object oObjectStream; - if (!pXref->Fetch(m_nObjectStreamNum, 0, &oObjectStream)->IsStream()) - { - oObjectStream.Free(); - return; - } - - if (!oObjectStream.StreamGetDict()->Search("N", &oTempObject1)->IsInt()) - { - oTempObject1.Free(); - oObjectStream.Free(); - return; - } - m_nObjectsCount = oTempObject1.GetInt(); - oTempObject1.Free(); - - if (m_nObjectsCount <= 0) - { - oObjectStream.Free(); - return; - } - - if (!oObjectStream.StreamGetDict()->Search("First", &oTempObject1)->IsInt()) - { - oTempObject1.Free(); - oObjectStream.Free(); - return; - } - - int nFirst = oTempObject1.GetInt(); - oTempObject1.Free(); - - if (nFirst < 0) - { - oObjectStream.Free(); - return; - } - - m_arrObjects = new Object[m_nObjectsCount]; - m_arrObjectsNums = (int *)MemUtilsMallocArray(m_nObjectsCount, sizeof(int)); - int *arrnOffsets = (int *)MemUtilsMallocArray(m_nObjectsCount, sizeof(int)); - - oObjectStream.StreamReset(); - oTempObject1.InitNull(); - - Stream *pStream = new EmbedStream(oObjectStream.GetStream(), &oTempObject1, true, nFirst); - Parser *pParser = new Parser(pXref, new Lexer(pXref, pStream), false); - for (int nIndex = 0; nIndex < m_nObjectsCount; ++nIndex) - { - pParser->GetObject(&oTempObject1); - pParser->GetObject(&oTempObject2); - - if (!oTempObject1.IsInt() || !oTempObject2.IsInt()) - { - oTempObject1.Free(); - oTempObject2.Free(); - delete pParser; - MemUtilsFree(arrnOffsets); - oObjectStream.Free(); - return; - } - m_arrObjectsNums[nIndex] = oTempObject1.GetInt(); - arrnOffsets[nIndex] = oTempObject2.GetInt(); - oTempObject1.Free(); - oTempObject2.Free(); - if (m_arrObjectsNums[nIndex] < 0 || arrnOffsets[nIndex] < 0 || (nIndex > 0 && arrnOffsets[nIndex] < arrnOffsets[nIndex - 1])) - { - delete pParser; - MemUtilsFree(arrnOffsets); - oObjectStream.Free(); - return; - } - } - while (pStream->GetChar() != EOF); - delete pParser; - - // Сдвигаемся к началу первого объекта - for (int nIndex = nFirst; nIndex < arrnOffsets[0]; ++nIndex) - { - oObjectStream.GetStream()->GetChar(); - } - - for (int nIndex = 0; nIndex < m_nObjectsCount; ++nIndex) - { - oTempObject1.InitNull(); - if (nIndex == m_nObjectsCount - 1) - { - pStream = new EmbedStream(oObjectStream.GetStream(), &oTempObject1, false, 0); - } - else - { - pStream = new EmbedStream(oObjectStream.GetStream(), &oTempObject1, true, arrnOffsets[nIndex + 1] - arrnOffsets[nIndex]); - } - pParser = new Parser(pXref, new Lexer(pXref, pStream), false); - pParser->GetObject(&m_arrObjects[nIndex]); - while (pStream->GetChar() != EOF); - delete pParser; - } - - MemUtilsFree(arrnOffsets); - - oObjectStream.Free(); - return; - } - - ObjectStream::~ObjectStream() - { - if (m_arrObjects) - { - for (int nIndex = 0; nIndex < m_nObjectsCount; ++nIndex) - { - m_arrObjects[nIndex].Free(); - } - delete[] m_arrObjects; - } - MemUtilsFree(m_arrObjectsNums); - } - - Object *ObjectStream::GetObject(int nObjectIndex, int nObjectNum, Object *pObject) - { - if (nObjectIndex < 0 || nObjectIndex >= m_nObjectsCount || nObjectNum != m_arrObjectsNums[nObjectIndex]) - { - return pObject->InitNull(); - } - return m_arrObjects[nObjectIndex].Copy(pObject); - } - - //------------------------------------------------------------------------ - // XRef - //------------------------------------------------------------------------ - - XRef::XRef(BaseStream *pStream) - { - m_oCS.InitializeCriticalSection(); - - m_arrDecryptKey = NULL; - - m_bValidXref = true; - m_eErrorCode = errorNone; - m_nEntrySize = 0; - m_arrEntries = NULL; - m_punStreamEnds = NULL; - m_nStreamEndsCount = 0; - m_pObjectStream = NULL; - - m_bEncrypted = false; - m_nPermissionFlags = DefaultPermissionFlags; - m_bOwnerPassword = false; - - // Если нет ссылки на данный объект, а ссылка нам нужна как идентефикатор, то выбираем некотый уникальный номер - // (поскольку корректное версионное число состоит из 5 цифр, поэтому любое 6-циферное число будет безопасным решением) - m_unRefGenCounter = 100000; - - // Читаем Trailer - m_pStream = pStream; - m_nStart = m_pStream->GetStartPos(); - unsigned int nPos = GetStartXref(); - - // Если возникла проблема при поиске 'startxref', пытаемся восстановить - // таблицу xref - - if (0 == nPos) - { - if (!(m_bValidXref = ConstructXRef())) - { - m_eErrorCode = errorDamaged; - return; - } - } - else // читаем таблицу Xref - { - while (ReadXRef(&nPos)); - - // Если возникла проблема при поиске 'startxref', пытаемся восстановить - // таблицу xref - if (!m_bValidXref) - { - if (!(m_bValidXref = ConstructXRef())) - { - m_eErrorCode = errorDamaged; - return; - } - } - } - - Object oTempObject; - - m_oTrailerDict.DictLookupAndCopy("Root", &oTempObject); - if (oTempObject.IsRef()) - { - m_nRootNum = oTempObject.GetRefNum(); - m_nRootGen = oTempObject.GetRefGen(); - oTempObject.Free(); - } - else - { - oTempObject.Free(); - if (!(m_bValidXref = ConstructXRef())) - { - m_eErrorCode = errorDamaged; - return; - } - } - - // Теперь устанавливаем в словарь Trailer ссылку на таблиу xref, чтобы мы могли - // по данной таблице находить косвенные объекты - m_oTrailerDict.GetDict()->SetXRef(this); - } - - XRef::~XRef() - { - MemUtilsFree(m_arrEntries); - m_oTrailerDict.Free(); - if (m_punStreamEnds) - { - MemUtilsFree(m_punStreamEnds); - } - if (m_pObjectStream) - { - delete m_pObjectStream; - } - - if (NULL != m_arrDecryptKey) - MemUtilsFree(m_arrDecryptKey); - - m_oCS.DeleteCriticalSection(); - } - - unsigned int XRef::GetStartXref() - { - char sBuffer[XrefSearchSize + 1]; - char *pCurChar; - int nChar = 0, nPos = 0, nCur = 0; - - // считываем последние xrefSearchSize байт - m_pStream->SetPos(XrefSearchSize, -1); - for (nPos = 0; nPos < XrefSearchSize; ++nPos) - { - if ((nChar = m_pStream->GetChar()) == EOF) - { - break; - } - sBuffer[nPos] = nChar; - } - sBuffer[nPos] = '\0'; - - // ищем startxref - for (nCur = nPos - 9; nCur >= 0; --nCur) - { - if (!strncmp(&sBuffer[nCur], "startxref", 9)) - { - break; - } - } - if (nCur < 0) - return 0; - - for (pCurChar = &sBuffer[nCur + 9]; isspace(*pCurChar); ++pCurChar); - - m_unLastXRefOffset = StrintToUInt(pCurChar); - - return m_unLastXRefOffset; - } - - // Считываем одну секцию таблицы Xref. Также считываем соответствующий словарь Trailer - // и возвращаем указатель на предыдущий. - bool XRef::ReadXRef(unsigned int *punPos) - { - Object oObject; - bool bResult = true; - - oObject.InitNull(); - Parser *pParser = new Parser(NULL, new Lexer(NULL, m_pStream->MakeSubStream(m_nStart + *punPos, false, 0, &oObject)), true); - pParser->GetObject(&oObject); - - // Парсим таблицу xref в старой форме - if (oObject.IsCommand("xref")) - { - oObject.Free(); - bResult = ReadXRefTable(pParser, punPos); - } - // Парсим таблицу xref, когда она записана в виде потока - else if (oObject.IsInt()) - { - oObject.Free(); - if (!pParser->GetObject(&oObject)->IsInt()) - { - oObject.Free(); - delete pParser; - m_bValidXref = false; - return false; - } - oObject.Free(); - if (!pParser->GetObject(&oObject)->IsCommand("obj")) - { - oObject.Free(); - delete pParser; - m_bValidXref = false; - return false; - } - oObject.Free(); - if (!pParser->GetObject(&oObject)->IsStream()) - { - oObject.Free(); - delete pParser; - m_bValidXref = false; - return false; - } - bResult = ReadXRefStream(oObject.GetStream(), punPos); - oObject.Free(); - - } - else - { - oObject.Free(); - delete pParser; - m_bValidXref = false; - return false; - } - - delete pParser; - return bResult; - } - - bool XRef::ReadXRefTable(Parser *pParser, unsigned int *punPos) - { - Object oTempObject; - - while (1) - { - // сначала в секции идут номер первого объекта и количество объектов - pParser->GetObject(&oTempObject); - if (oTempObject.IsCommand("trailer")) - { - oTempObject.Free(); - break; - } - if (!oTempObject.IsInt()) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - int nFirst = oTempObject.GetInt(); - oTempObject.Free(); - if (!pParser->GetObject(&oTempObject)->IsInt()) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - int nCount = oTempObject.GetInt(); - oTempObject.Free(); - - if (nFirst < 0 || nCount < 0 || nFirst + nCount < 0) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - if (nFirst + nCount > m_nEntrySize) - { - int nNewSize = 0; - for (nNewSize = m_nEntrySize ? 2 * m_nEntrySize : 1024; nFirst + nCount > nNewSize && nNewSize > 0; nNewSize <<= 1); - if (nNewSize < 0) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - m_arrEntries = (XRefEntry *)MemUtilsReallocArray(m_arrEntries, nNewSize, sizeof(XRefEntry)); - for (int nIndex = m_nEntrySize; nIndex < nNewSize; ++nIndex) - { - m_arrEntries[nIndex].unOffset = 0xffffffff; - m_arrEntries[nIndex].eType = xrefEntryFree; - } - m_nEntrySize = nNewSize; - } - for (int nIndex = nFirst; nIndex < nFirst + nCount; ++nIndex) - { - // формат: nnnnnnnnnn ggggg n eol - // nnnnnnnnnn - байтовый сдвиг - // ggggg - Generation number(номер версии объекта) - // n - Ключ, определяющий используется ли объект - // eol - Конец строки(два символа) - if (!pParser->GetObject(&oTempObject)->IsInt()) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - - XRefEntry oEntry; - oEntry.unOffset = (unsigned int)oTempObject.GetInt(); - oTempObject.Free(); - if (!pParser->GetObject(&oTempObject)->IsInt()) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - oEntry.nGen = oTempObject.GetInt(); - oTempObject.Free(); - pParser->GetObject(&oTempObject); - if (oTempObject.IsCommand("n")) - { - oEntry.eType = xrefEntryUncompressed; - } - else if (oTempObject.IsCommand("f")) - { - oEntry.eType = xrefEntryFree; - } - else - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - oTempObject.Free(); - if (m_arrEntries[nIndex].unOffset == 0xffffffff) - { - m_arrEntries[nIndex] = oEntry; - // в PDF файлах, созданных с помощью Intellectual Property - // Network, имеется баг: таблица Xref начинается с объекта - // под номером 1, вместо 0. - if (nIndex == 1 && nFirst == 1 && m_arrEntries[1].unOffset == 0 && m_arrEntries[1].nGen == 65535 && m_arrEntries[1].eType == xrefEntryFree) - { - nIndex = nFirst = 0; - m_arrEntries[0] = m_arrEntries[1]; - m_arrEntries[1].unOffset = 0xffffffff; - } - } - } - } - - // Читаем словарь Trailer - if (!pParser->GetObject(&oTempObject)->IsDict()) - { - oTempObject.Free(); - m_bValidXref = false; - return false; - } - - // Считываем указатель 'Prev' - Object oPrev; - bool bPrev = false; - oTempObject.GetDict()->SearchAndCopy("Prev", &oPrev); - if (oPrev.IsInt()) - { - *punPos = (unsigned int)oPrev.GetInt(); - bPrev = true; - } - else if (oPrev.IsRef()) - { - // Некоторые программы пишут "/Prev NNN 0 R" вместо "/Prev NNN" - *punPos = (unsigned int)oPrev.GetRefNum(); - bPrev = true; - } - else - { - bPrev = false; - } - oPrev.Free(); - - // Сохраняем первый словарь Trailer - if (m_oTrailerDict.IsNone()) - { - oTempObject.Copy(&m_oTrailerDict); - } - - // Проверяем есть ли элемент 'XRefStm' - if (oTempObject.GetDict()->Search("XRefStm", &oPrev)->IsInt()) - { - unsigned int unPos2 = (unsigned int)oPrev.GetInt(); - ReadXRef(&unPos2); - if (!m_bValidXref) - { - oPrev.Free(); - oTempObject.Free(); - m_bValidXref = false; - return false; - } - } - oPrev.Free(); - - oTempObject.Free(); - return bPrev; - } - - bool XRef::ReadXRefStream(Stream *pXrefStream, unsigned int *punPos) - { - int arrW[3]; - - Dict *pDict = pXrefStream->GetDict(); - Object oTemp; - - if (!pDict->SearchAndCopy("Size", &oTemp)->IsInt()) - { - oTemp.Free(); - m_bValidXref = false; - return false; - } - int nNewSize = oTemp.GetInt(); - oTemp.Free(); - - if (nNewSize < 0) - { - oTemp.Free(); - m_bValidXref = false; - return false; - } - if (nNewSize > m_nEntrySize) - { - m_arrEntries = (XRefEntry *)MemUtilsReallocArray(m_arrEntries, nNewSize, sizeof(XRefEntry)); - for (int nIndex = m_nEntrySize; nIndex < nNewSize; ++nIndex) - { - m_arrEntries[nIndex].unOffset = 0xffffffff; - m_arrEntries[nIndex].eType = xrefEntryFree; - } - m_nEntrySize = nNewSize; - } - - if (!pDict->SearchAndCopy("W", &oTemp)->IsArray() || oTemp.ArrayGetLength() < 3) - { - oTemp.Free(); - m_bValidXref = false; - return false; - } - for (int nIndex = 0; nIndex < 3; ++nIndex) - { - Object oWItem; - if (!oTemp.ArrayGet(nIndex, &oWItem)->IsInt()) - { - oWItem.Free(); - oTemp.Free(); - m_bValidXref = false; - return false; - } - arrW[nIndex] = oWItem.GetInt(); - oWItem.Free(); - if (arrW[nIndex] < 0 || arrW[nIndex] > 4 && arrW[nIndex] != 8) - { - oTemp.Free(); - m_bValidXref = false; - return false; - } - } - oTemp.Free(); - - pXrefStream->Reset(); - Object oIndex; - pDict->SearchAndCopy("Index", &oIndex); - - if (oIndex.IsArray()) - { - for (int nIndex = 0; nIndex + 1 < oIndex.ArrayGetLength(); nIndex += 2) - { - if (!oIndex.ArrayGet(nIndex, &oTemp)->IsInt()) - { - oIndex.Free(); - oTemp.Free(); - m_bValidXref = false; - return false; - } - int nFirst = oTemp.GetInt(); - oTemp.Free(); - if (!oIndex.ArrayGet(nIndex + 1, &oTemp)->IsInt()) - { - oIndex.Free(); - oTemp.Free(); - m_bValidXref = false; - return false; - } - int nCount = oTemp.GetInt(); - oTemp.Free(); - if (nFirst < 0 || nCount < 0 || !ReadXRefStreamSection(pXrefStream, arrW, nFirst, nCount)) - { - oIndex.Free(); - m_bValidXref = false; - return false; - } - } - } - else - { - if (!ReadXRefStreamSection(pXrefStream, arrW, 0, nNewSize)) - { - oIndex.Free(); - m_bValidXref = false; - return false; - } - } - oIndex.Free(); - - pDict->SearchAndCopy("Prev", &oTemp); - bool bPrev = false; - if (oTemp.IsInt()) - { - *punPos = (unsigned int)oTemp.GetInt(); - bPrev = true; - } - else - { - bPrev = false; - } - oTemp.Free(); - if (m_oTrailerDict.IsNone()) - { - m_oTrailerDict.InitDict(pDict); - } - - return bPrev; - } - - bool XRef::ReadXRefStreamSection(Stream *pXrefStream, int *arrW, int nFirst, int nCount) - { - if (nFirst + nCount < 0) - { - return false; - } - if (nFirst + nCount > m_nEntrySize) - { - int nNewSize = 0; - for (nNewSize = m_nEntrySize ? 2 * m_nEntrySize : 1024; nFirst + nCount > nNewSize && nNewSize > 0; nNewSize <<= 1); - if (nNewSize < 0) - { - return false; - } - m_arrEntries = (XRefEntry *)MemUtilsReallocArray(m_arrEntries, nNewSize, sizeof(XRefEntry)); - for (int nIndex = m_nEntrySize; nIndex < nNewSize; ++nIndex) - { - m_arrEntries[nIndex].unOffset = 0xffffffff; - m_arrEntries[nIndex].eType = xrefEntryFree; - } - m_nEntrySize = nNewSize; - } - for (int nIndex = nFirst; nIndex < nFirst + nCount; ++nIndex) - { - int nType = -1; - int nChar = 0, nGen = 0, nJ = 0; - unsigned int unOffset = 0; - if (arrW[0] == 0) - { - nType = 1; - } - else - { - for (nType = 0, nJ = 0; nJ < arrW[0]; ++nJ) - { - if ((nChar = pXrefStream->GetChar()) == EOF) - { - return false; - } - nType = (nType << 8) + nChar; - } - } - for (unOffset = 0, nJ = 0; nJ < arrW[1]; ++nJ) - { - if ((nChar = pXrefStream->GetChar()) == EOF) - { - return false; - } - unOffset = (unOffset << 8) + nChar; - } - for (nGen = 0, nJ = 0; nJ < arrW[2]; ++nJ) - { - if ((nChar = pXrefStream->GetChar()) == EOF) - { - return false; - } - nGen = (nGen << 8) + nChar; - } - if (m_arrEntries[nIndex].unOffset == 0xffffffff) - { - switch (nType) - { - case 0: - m_arrEntries[nIndex].unOffset = unOffset; - m_arrEntries[nIndex].nGen = nGen; - m_arrEntries[nIndex].eType = xrefEntryFree; - break; - case 1: - m_arrEntries[nIndex].unOffset = unOffset; - m_arrEntries[nIndex].nGen = nGen; - m_arrEntries[nIndex].eType = xrefEntryUncompressed; - break; - case 2: - m_arrEntries[nIndex].unOffset = unOffset; - m_arrEntries[nIndex].nGen = nGen; - m_arrEntries[nIndex].eType = xrefEntryCompressed; - break; - default: - return false; - } - } - } - - return true; - } - - // Пробуем построить таблицу Xref для поврежденного файла. - bool XRef::ConstructXRef() - { - bool bGetRoot = false; - - MemUtilsFree(m_arrEntries); - m_nEntrySize = 0; - m_arrEntries = NULL; - - // TO DO : Error "PDF file is damaged - attempting to reconstruct xref table..." - m_nStreamEndsCount = 0; - - int nStreamEndsSize = 0; - - m_pStream->Reset(); - - while (1) - { - unsigned int nPos = m_pStream->GetPos(); - char sBuffer[256]; - if (!m_pStream->GetLine(sBuffer, 256)) - { - break; - } - unsigned char *pCur = (unsigned char*)sBuffer; - - // Пропускаем пробелы - while (*pCur && Lexer::IsSpace(*pCur & 0xff)) ++pCur; - - // Cчитываем словарь Trailer - if (!strncmp((char*)pCur, "trailer", 7)) - { - Object oTemp; - oTemp.InitNull(); - Parser *pParser = new Parser(NULL, new Lexer(NULL, m_pStream->MakeSubStream(nPos + 7, false, 0, &oTemp)), false); - Object oNewTrailerDict; - pParser->GetObject(&oNewTrailerDict); - if (oNewTrailerDict.IsDict()) - { - oNewTrailerDict.DictLookupAndCopy("Root", &oTemp); - if (oTemp.IsRef()) - { - m_nRootNum = oTemp.GetRefNum(); - m_nRootGen = oTemp.GetRefGen(); - if (!m_oTrailerDict.IsNone()) - { - m_oTrailerDict.Free(); - } - oNewTrailerDict.Copy(&m_oTrailerDict); - bGetRoot = true; - } - oTemp.Free(); - } - oNewTrailerDict.Free(); - delete pParser; - } - else if (isdigit(*pCur)) // Ищем объект - { - int nNum = atoi((char*)pCur); - if (nNum > 0) - { - do { - ++pCur; - } while (*pCur && isdigit(*pCur)); - if (isspace(*pCur)) - { - do { - ++pCur; - } while (*pCur && isspace(*pCur)); - if (isdigit(*pCur)) - { - int nGen = atoi((char*)pCur); - do { - ++pCur; - } while (*pCur && isdigit(*pCur)); - if (isspace(*pCur)) - { - do { - ++pCur; - } while (*pCur && isspace(*pCur)); - if (!strncmp((char*)pCur, "obj", 3)) - { - if (nNum >= m_nEntrySize) - { - int nNewSize = (nNum + 1 + 255) & ~255; - if (nNewSize < 0) - { - // TO DO: Error "Bad object number" - return false; - } - m_arrEntries = (XRefEntry *)MemUtilsReallocArray(m_arrEntries, nNewSize, sizeof(XRefEntry)); - for (int nIndex = m_nEntrySize; nIndex < nNewSize; ++nIndex) - { - m_arrEntries[nIndex].unOffset = 0xffffffff; - m_arrEntries[nIndex].eType = xrefEntryFree; - } - m_nEntrySize = nNewSize; - } - if (m_arrEntries[nNum].eType == xrefEntryFree || nGen >= m_arrEntries[nNum].nGen) - { - m_arrEntries[nNum].unOffset = nPos - m_nStart; - m_arrEntries[nNum].nGen = nGen; - m_arrEntries[nNum].eType = xrefEntryUncompressed; - } - } - } - } - } - } - - } - else if (!strncmp((char*)pCur, "endstream", 9)) - { - if (m_nStreamEndsCount == nStreamEndsSize) - { - nStreamEndsSize += 64; - m_punStreamEnds = (unsigned int *)MemUtilsReallocArray(m_punStreamEnds, nStreamEndsSize, sizeof(int)); - } - m_punStreamEnds[m_nStreamEndsCount++] = nPos; - } - } - - if (bGetRoot) - return true; - - // TO DO: Error "Couldn't find trailer dictionary" - return false; - } - - void XRef::SetEncryption(int nPermissionFlags, bool bOwnerPassword, unsigned char *sDecryptKey, int nKeyLength, int nEncryptVersion, CryptAlgorithm eEncryptAlgorithm) - { - m_bEncrypted = true; - - m_nPermissionFlags = nPermissionFlags; - m_bOwnerPassword = bOwnerPassword; - m_nKeyLength = nKeyLength; - - if (NULL != m_arrDecryptKey) - MemUtilsFree(m_arrDecryptKey); - m_arrDecryptKey = (unsigned char*)MemUtilsMalloc(m_nKeyLength); - - for (int nIndex = 0; nIndex < m_nKeyLength; ++nIndex) - { - m_arrDecryptKey[nIndex] = sDecryptKey[nIndex]; - } - m_nEncryptVersion = nEncryptVersion; - m_eEncryptAlgorithm = eEncryptAlgorithm; - } - - bool XRef::CheckPrint(bool bIgnoreOwnerPassword) - { - return (!bIgnoreOwnerPassword && m_bOwnerPassword) || (m_nPermissionFlags & PermissionPrint); - } - - bool XRef::CheckChange(bool bIgnoreOwnerPassword) - { - return (!bIgnoreOwnerPassword && m_bOwnerPassword) || (m_nPermissionFlags & PermissionChange); - } - - bool XRef::CheckCopy(bool bIgnoreOwnerPassword) - { - return (!bIgnoreOwnerPassword && m_bOwnerPassword) || (m_nPermissionFlags & PermissionCopy); - } - - bool XRef::CheckAddNotes(bool bIgnoreOwnerPassword) - { - return (!bIgnoreOwnerPassword && m_bOwnerPassword) || (m_nPermissionFlags & PermissionNotes); - } - - Object *XRef::Fetch(int nNum, int nGen, Object *pObject) - { - CTemporaryCS oCS(&m_oCS); - - if (nNum < 0 || nNum >= m_nEntrySize) - { - return pObject->InitNull(); - } - bool bObjNum = false, bObjGen = false, bObjContent = false; - int count_obj_parser = 3; - Object oObjNum;//, oObjGen, oObjContent; - - Parser *pParser = NULL; - XRefEntry *pEntry = &m_arrEntries[nNum]; - switch (pEntry->eType) - { - case xrefEntryUncompressed: - if (pEntry->nGen != nGen) - { - return pObject->InitNull(); - } - oObjNum.InitNull(); - pParser = new Parser(this, new Lexer(this, m_pStream->MakeSubStream(m_nStart + pEntry->unOffset, false, 0, &oObjNum)), true); - - for (int i = 0; i < count_obj_parser; i++) - { - Object obj; - pParser->GetObject(&obj); - - if (obj.IsCommand("ndobj")) //reformed.pdf - { - count_obj_parser++; - } - else - { - //todooo порядок запросов ??? - if (!bObjContent && obj.IsCommand("obj")) bObjContent = true; - if (obj.IsInt()) - { - if (!bObjNum && obj.GetInt() == nNum) bObjNum = true; - else if (!bObjGen && obj.GetInt() == nGen) bObjGen = true; - } - } - - obj.Free(); - } - if (!bObjContent || !bObjGen || !bObjNum) - { - delete pParser; - return pObject->InitNull(); - } - //pParser->GetObject(&oObjNum); - //pParser->GetObject(&oObjGen); - //pParser->GetObject(&oObjContent); - //if (!oObjNum.IsInt() || oObjNum.GetInt() != nNum || !oObjGen.IsInt() || oObjGen.GetInt() != nGen || !oObjContent.IsCommand("obj")) - //{ - // oObjNum.Free(); - // oObjGen.Free(); - // oObjContent.Free(); - // delete pParser; - // return pObject->InitNull(); - //} - pParser->GetObject(pObject, m_bEncrypted ? m_arrDecryptKey : (unsigned char *)NULL, m_eEncryptAlgorithm, m_nKeyLength, nNum, nGen); - //oObjNum.Free(); - //oObjGen.Free(); - //oObjContent.Free(); - delete pParser; - break; - - case xrefEntryCompressed: - if (nGen != 0) - { - return pObject->InitNull(); - } - if (!m_pObjectStream || m_pObjectStream->GetObjectStreamNum() != (int)pEntry->unOffset) - { - if (m_pObjectStream) - { - delete m_pObjectStream; - } - m_pObjectStream = new ObjectStream(this, pEntry->unOffset); - } - m_pObjectStream->GetObject(pEntry->nGen, nNum, pObject); - break; - - default: - return pObject->InitNull(); - } - - return pObject; - } - - Object *XRef::GetDocInfo(Object *pObject) - { - CTemporaryCS oCS(&m_oCS); - - return m_oTrailerDict.DictLookup("Info", pObject); - } - Object *XRef::GetDocInfoCopy(Object *pObject) - { - CTemporaryCS oCS(&m_oCS); - - return m_oTrailerDict.DictLookupAndCopy("Info", pObject); - } - - bool XRef::GetStreamEnd(unsigned int nStreamStart, unsigned int *pnStreamEnd) - { - if (m_nStreamEndsCount == 0 || nStreamStart > m_punStreamEnds[m_nStreamEndsCount - 1]) - return false; - - int nStart = -1; - int nEnd = m_nStreamEndsCount - 1; - // m_punStreamEnds[ nStart ] < streamStart <= m_punStreamEnds[ nEnd ] - while (nEnd - nStart > 1) - { - int nMid = (nStart + nEnd) / 2; - if (nStreamStart <= m_punStreamEnds[nMid]) - { - nEnd = nMid; - } - else - { - nStart = nMid; - } - } - *pnStreamEnd = m_punStreamEnds[nEnd]; - return true; - } - void XRef::AllObjectsToXml(std::wstring &wsXml, bool bParseStreams) - { - for (int nNum = 0; nNum < m_nEntrySize; ++nNum) - { - XRefEntry* pEntry = &m_arrEntries[nNum]; - if (xrefEntryFree != pEntry->eType) - { - - Object oTemp; - Fetch(nNum, 0/*pEntry->nGen*/, &oTemp); - - if (oTemp.IsDict() || oTemp.IsStream()) - { - if (xrefEntryCompressed == pEntry->eType) - wsXml += L"nGen*/) + L"\" compressed=\"true\">"; - else - wsXml += L"nGen*/) + L"\">"; - - if (oTemp.IsDict()) - { - oTemp.ToXml(wsXml); - } - else if (oTemp.IsStream()) - { - Dict* pStreamDict = oTemp.StreamGetDict(); - pStreamDict->ToXml(wsXml); - wsXml += L""; - - if (bParseStreams) - { - Stream* pStream = oTemp.GetStream(); - pStream->Reset(); - - Object oFilter, oTempFilter; - pStreamDict->Search("Filter", &oFilter); - std::string sStream; - if (oFilter.IsNull() || oFilter.IsName("FlateDecode") - || (oFilter.IsArray() && 1 == oFilter.GetArray()->GetCount() && oFilter.GetArray()->Get(0, &oTempFilter) && oTempFilter.IsName("FlateDecode"))) - { - int nChar; - while (EOF != (nChar = pStream->GetChar())) - { - char sTemp[1] = {(char)nChar}; - - switch (sTemp[0]) - { - case '\"': sStream += """; break; - case '&': sStream += "&"; break; - case '<': sStream += "<"; break; - case '>': sStream += ">"; break; - default: sStream += sTemp; break; - } - } - } - else - { - wsXml += L"BinaryData"; - } - - Object::AppendStringToXml(wsXml, sStream); - } - - wsXml += L""; - } - - wsXml += L""; - } - - oTemp.Free(); - } - } - } - - unsigned int XRef::StrintToUInt(char *sString) - { - char *pCur; - int nIndex = 0; - - unsigned int unRes = 0; - for (pCur = sString, nIndex = 0; *pCur && isdigit(*pCur) && nIndex < 10; ++pCur, ++nIndex) - { - unRes = 10 * unRes + (*pCur - '0'); - } - return unRes; - } -} diff --git a/PdfReader/old/XRef.h b/PdfReader/old/XRef.h deleted file mode 100644 index 55da215318..0000000000 --- a/PdfReader/old/XRef.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_READER_XREF_H -#define _PDF_READER_XREF_H - -#include "Object.h" -#include "Stream.h" -#include "../../DesktopEditor/graphics/TemporaryCS.h" -#include "ErrorConstants.h" - -namespace PdfReader -{ - class Dict; - class Stream; - class Parser; - class ObjectStream; - - //------------------------------------------------------------------------ - // XRef - //------------------------------------------------------------------------ - - enum XRefEntryType - { - xrefEntryFree, - xrefEntryUncompressed, - xrefEntryCompressed - }; - - struct XRefEntry - { - unsigned int unOffset; - int nGen; - XRefEntryType eType; - }; - - class XRef - { - public: - - XRef(BaseStream *pStream); - - ~XRef(); - - bool CheckValidate() - { - return m_bValidXref; - } - - // Если CheckValidate вернул false - EError GetErrorCode() - { - return m_eErrorCode; - } - - void SetEncryption(int nPermissionFlags, bool bOwnerPassword, unsigned char *sDecryptKey, int nKeyLength, int nEncryptVersion, CryptAlgorithm eEncryptAlgorithm); - - bool CheckEncrypted() - { - return m_bEncrypted; - } - - // Проверяем ограничения. - bool CheckPrint(bool bIgnoreOwnerPassword = false); - bool CheckChange(bool bIgnoreOwnerPassword = false); - bool CheckCopy(bool bIgnoreOwnerPassword = false); - bool CheckAddNotes(bool bIgnoreOwnerPassword = false); - - Object *GetCatalog(Object *pObject) - { - return Fetch(m_nRootNum, m_nRootGen, pObject); - } - - // Вытаскиваем косвенный объект. - Object *Fetch(int nNum, int nGen, Object *pObject); - - Object *GetDocInfo(Object *pObject); - Object *GetDocInfoCopy(Object *pObject); - - int GetObjectsCount() - { - return m_nEntrySize; - } - - unsigned int GetLastXRefPos() - { - return m_unLastXRefOffset; - } - - - // объект Root (Catalog) - int GetRootNum() - { - return m_nRootNum; - } - int GetRootGen() - { - return m_nRootGen; - } - - // Получаем конечную позицию в поврежденном файле. - // Возвращаем false, если позиция неизвестна или файл не поврежден. - bool GetStreamEnd(unsigned int nStreamStart, unsigned int *pnStreamEnd); - - int GetSize() - { - return m_nEntrySize; - } - XRefEntry *GetEntry(int nIndex) - { - return &m_arrEntries[nIndex]; - } - Object *GetTrailerDict() - { - return &m_oTrailerDict; - } - unsigned int GenerateUniqueRefGen() - { - return m_unRefGenCounter++; - } - void AllObjectsToXml(std::wstring& wsXml, bool bParseStreams); - - private: - - unsigned int GetStartXref(); - bool ReadXRef(unsigned int *punPos); - bool ReadXRefTable(Parser *pParser, unsigned int *punPos); - bool ReadXRefStreamSection(Stream *pXrefStream, int *arrW, int nFirst, int nCount); - bool ReadXRefStream(Stream *pXrefStream, unsigned int *punPos); - bool ConstructXRef(); - unsigned int StrintToUInt(char *sString); - - private: - - BaseStream *m_pStream; // Основной поток - unsigned int m_nStart; // Сдвиг в потоке - - XRefEntry *m_arrEntries; // Элементы таблицы Xref - int m_nEntrySize; // Размер элемента в списке m_arrEntries - int m_nRootNum; // Номер объекта Root (Catalog) - int m_nRootGen; // Номер версии объекта Root (Catalog) - - bool m_bValidXref; // Проверяем корректность таблицы Xref - EError m_eErrorCode; // Номер ошибки, если m_bValidXref = false - - Object m_oTrailerDict; // Словарь Trailer - - unsigned int m_unLastXRefOffset; // Сдвиг последней таблицы Xref - unsigned int *m_punStreamEnds; // Позиция конца потока - используется только для поврежденных файлов - - int m_nStreamEndsCount; // Количество корректных элементов в m_punStreamEnds - ObjectStream *m_pObjectStream; // Object Stream - bool m_bEncrypted; // Поток зашифрован или нет? - int m_nPermissionFlags; // Различные ограничения - bool m_bOwnerPassword; // Проверяем правильный ли был введен пароль владельца файла - unsigned char* m_arrDecryptKey; // Ключ для расшифровки - int m_nKeyLength; // Размер ключа в байтах - int m_nEncryptVersion; // Версия шифровки - CryptAlgorithm m_eEncryptAlgorithm; // Алгоритм шифрования - - unsigned int m_unRefGenCounter; // Специальный счетчик для генерации уникальных ссылок для встроенных объектов - - NSCriticalSection::CRITICAL_SECTION m_oCS; - }; -} - -#endif // _PDF_READER_XREF_H diff --git a/PdfReader/test/PDF_viewer.pro b/PdfReader/test/PDF_viewer.pro deleted file mode 100644 index 51af70f2f3..0000000000 --- a/PdfReader/test/PDF_viewer.pro +++ /dev/null @@ -1,35 +0,0 @@ -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -CONFIG += c++11 - -# You can make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - main.cpp \ - mainwindow.cpp - -HEADERS += \ - mainwindow.h - -FORMS += \ - mainwindow.ui - -INCLUDEPATH += \ - $$PWD/../lib/goo \ - $$PWD/../lib/fofi \ - $$PWD/../lib/splash \ - $$PWD/../lib - -PWD_ROOT_DIR = $$PWD -CORE_ROOT_DIR = $$PWD/../../../core - -include($$CORE_ROOT_DIR/Common/base.pri) - - -ADD_DEPENDENCY(kernel, graphics, UnicodeConverter, PdfReader) - -core_linux:include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) diff --git a/PdfReader/test/main.cpp b/PdfReader/test/main.cpp deleted file mode 100644 index fd3e533415..0000000000 --- a/PdfReader/test/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "mainwindow.h" - -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - return a.exec(); -} diff --git a/PdfReader/test/mainwindow.cpp b/PdfReader/test/mainwindow.cpp deleted file mode 100644 index c17702ed7a..0000000000 --- a/PdfReader/test/mainwindow.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" -#include - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) -{ - ui->setupUi(this); - - m_nPosX = 0; - m_nPosY = 0; - m_dScale = 1.0; - m_pReader = NULL; - m_pImage = NULL; - m_eZoomType = ZoomType::pageHeight; - - m_pLabel = new QLabel(ui->mainView); - m_pLabel->setScaledContents(true); - - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); - - m_pFonts = oWorker.Check(); - - m_pFontManager = m_pFonts->GenerateFontManager(); - NSFonts::IFontsCache* pFontsCache = NSFonts::NSFontCache::Create(); - pFontsCache->SetStreams(m_pFonts->GetStreams()); - pFontsCache->SetCacheSize(16); - m_pFontManager->SetOwnerCache(pFontsCache); - m_pImageCache = NSImages::NSFilesCache::Create(m_pFonts); - - QSettings settings("OnlyOffice (R)", "PDF Reader Test"); - restoreGeometry(settings.value("mainWindowGeometry").toByteArray()); - restoreState(settings.value("mainWindowState").toByteArray()); - ui->FileNameLineEdit->setText(settings.value("mainWindowFilePath").toString()); - m_sFile = ui->FileNameLineEdit->text(); - ui->PageLineEdit->setText("1"); - -#ifdef QT_DEBUG - OpenFile(); -#endif - -} - -MainWindow::~MainWindow() -{ - if (m_pFontManager) m_pFontManager->Release(); - if (m_pFonts) m_pFonts->Release(); - if (m_pImageCache) m_pImageCache->Release(); - if (m_pReader) delete m_pReader; - delete ui; -} - -void MainWindow::OpenFile() -{ - if (!m_pReader) - { - m_pReader = new PdfReader::CPdfReader(m_pFonts); - m_pReader->SetCMapFolder(L".//..//..//..//..//Resources//CMap//"); - } - - m_pReader->Close(); - - if (!m_pReader->LoadFromFile(m_sFile.toStdWString())) - return; - - ui->PageLineEdit->setText("1"); - RenderPage(); -} - -bool MainWindow::RenderOnByteData(int nPage, BYTE*& pBgraData, int& w, int& h) -{ - if (!m_pReader) - return false; - - double dWidth, dHeight; - double dDpiX, dDpiY; - m_pReader->GetPageInfo(nPage, &dWidth, &dHeight, &dDpiX, &dDpiY); - - int nWidth = (int)dWidth; - int nHeight = (int)dHeight; - - double dScale = GetPageScaleByZoomType(dWidth * dDpiX / 72.0, dHeight * dDpiY / 72.0); - nWidth = (int)(dScale * nWidth); - nHeight = (int)(dScale * nHeight); - - w = nWidth; - h = nHeight; - - pBgraData = new BYTE[nWidth * nHeight * 4]; - if (!pBgraData) - return false; - - memset(pBgraData, 0xff, nWidth * nHeight * 4); - CBgraFrame oFrame; - oFrame.put_Data(pBgraData); - oFrame.put_Width(nWidth); - oFrame.put_Height(nHeight); - oFrame.put_Stride(4 * nWidth); - - NSGraphics::IGraphicsRenderer* pRenderer = NSGraphics::Create(); - pRenderer->SetFontManager(m_pFontManager); - pRenderer->CreateFromBgraFrame(&oFrame); - pRenderer->SetSwapRGB(true); - pRenderer->put_Width(dWidth * 25.4 / dDpiX); - pRenderer->put_Height(dHeight * 25.4 / dDpiY); - - m_pReader->DrawPageOnRenderer(pRenderer, nPage, NULL); - pRenderer->Release(); - - // иначе удалится память при деструктопе CBgraFrame - oFrame.put_Data(NULL); - return true; -} - -void MainWindow::SetImage() -{ - int nX = 0; - int nY = 0; - int nW = m_pImage->width(); - int nH = m_pImage->height(); - - int nBaseW = ui->mainView->width(); - int nBaseH = ui->mainView->height(); - if (nW <= nBaseW) - { - nX = (int)((nBaseW - nW) / 2); - } - else - { - if (nX > 0) - nX = 0; - if (nX + nW < nBaseW) - nX = nBaseW - nW; - } - - if (nH <= nBaseH) - { - nY = (int)((nBaseH - nH) / 2); - } - else - { - if (nY > 0) - nY = 0; - if (nY + nH < nBaseH) - nY = nBaseH - nH; - } - - ui->verticalScrollBar->setMaximum((nH > nBaseH) ? (nH - nBaseH) : 0); - ui->horizontalScrollBar->setMaximum((nW > nBaseW) ? (nW - nBaseW) : 0); - - m_pLabel->setGeometry(nX, nY, nW, nH); - m_pLabel->setPixmap(QPixmap::fromImage(*m_pImage)); - - m_nPosX = nX; - m_nPosY = nY; - ui->verticalScrollBar->setValue(0); - ui->horizontalScrollBar->setValue(0); -} - -void MainWindow::on_OpenFileButton_clicked() -{ - m_sFile = QFileDialog::getOpenFileName(this, tr("Open PDF"), ui->FileNameLineEdit->text(), tr("PDF Files (*.pdf)")); - if (!m_sFile.isEmpty()) - { - ui->FileNameLineEdit->setText(m_sFile); - OpenFile(); - } -} - -void cleanUpPixels(void* pixels) -{ - BYTE* arrPixels = (BYTE*)pixels; - delete [] arrPixels; -} -void MainWindow::on_RenderButton_clicked() -{ - RenderPage(); -} - -void MainWindow::on_ScaleSlider_sliderMoved(int position) -{ - if (!m_pReader) - return; - - m_eZoomType = ZoomType::custom; - m_dScale = (double)position / 100; - RenderPage(); -} - -void MainWindow::on_LeftButton_clicked() -{ - if (!IsFileOpened()) - return ui->PageLineEdit->setText(""); - - int nPage = ui->PageLineEdit->text().toUInt(); - nPage = std::max(1, std::min(m_pReader->GetPagesCount(), nPage - 1)); - - ui->PageLineEdit->setText(std::to_string(nPage).c_str()); - RenderPage(); -} - -void MainWindow::on_RightButton_clicked() -{ - if (!IsFileOpened()) - return ui->PageLineEdit->setText(""); - - int nPage = ui->PageLineEdit->text().toUInt(); - nPage = std::max(1, std::min(m_pReader->GetPagesCount(), nPage + 1)); - - ui->PageLineEdit->setText(std::to_string(nPage).c_str()); - RenderPage(); -} - -void MainWindow::on_verticalScrollBar_valueChanged(int value) -{ - if (!IsFileOpened()) - return; - - m_nPosY = value; - m_pLabel->move(m_pLabel->x(), -m_nPosY); -} - -void MainWindow::on_horizontalScrollBar_valueChanged(int value) -{ - if (!m_pReader) - return; - m_nPosX = value; - m_pLabel->move(-m_nPosX, m_pLabel->y()); -} -void MainWindow::resizeEvent(QResizeEvent* event) -{ - QMainWindow::resizeEvent(event); - - int nW = this->width(); - int nH = this->height(); - - ui->LeftButton->move(nW / 2 - 120, nH - 67); - ui->RightButton->move(nW / 2 + 40, nH - 67); - ui->RenderButton->move(nW / 2 - 40, nH - 67); - - ui->OpenFileButton->move(nW - 91, 10); - ui->FileNameLineEdit->setMaximumWidth(nW - 110); - ui->FileNameLineEdit->setMinimumWidth(nW - 110); - - ui->ScaleSlider->move(nW - 200, nH - 57); - ui->label->move(nW - 200 + ui->ScaleSlider->width() / 2 - ui->label->width() / 2, nH - 87); - - ui->PageLineEdit->move(nW / 2 - ui->PageLineEdit->width() / 2, nH - 97); - - ui->verticalScrollBar->move(nW - 31, 40); - ui->verticalScrollBar->setMinimumHeight(nH - 176); - ui->verticalScrollBar->setMaximumHeight(nH - 176); - - ui->horizontalScrollBar->move(10, nH - 137); - ui->horizontalScrollBar->setMaximumWidth(nW - 40); - ui->horizontalScrollBar->setMinimumWidth(nW - 40); - - ui->mainView->move(10, 40); - ui->mainView->setMinimumWidth(nW - 40); - ui->mainView->setMaximumWidth(nW - 40); - ui->mainView->setMinimumHeight(nH - 176); - ui->mainView->setMaximumHeight(nH - 176); - RenderPage(); -} -void MainWindow::closeEvent(QCloseEvent *event) -{ - QSettings settings("OnlyOffice (R)", "PDF Reader Test"); - settings.setValue("mainWindowGeometry", saveGeometry()); - settings.setValue("mainWindowState", saveState()); - settings.setValue("mainWindowFilePath", ui->FileNameLineEdit->text()); -} -bool MainWindow::IsFileOpened() -{ - return m_pReader && !m_pReader->GetError(); -} -double MainWindow::GetPageScaleByZoomType(const double& dPageWidth, const double& dPageHeight) -{ - double dScale = m_dScale; - - if (ZoomType::pageWidth == m_eZoomType) - { - int nViewWidth = ui->mainView->width(); - dScale = nViewWidth / dPageWidth; - } - else if (ZoomType::pageHeight == m_eZoomType) - { - int nViewHeight = ui->mainView->height(); - dScale = nViewHeight / dPageHeight; - } - - return dScale; -} -void MainWindow::RenderPage() -{ - if (!IsFileOpened()) - return; - - int page = ui->PageLineEdit->text().toInt(); - - int nPagesCount = m_pReader->GetPagesCount(); - if (nPagesCount <= 0) - return; - - page = std::max(1, std::min(nPagesCount, page)); - - int w, h; - BYTE *data; - if (!RenderOnByteData(page - 1, data, w, h)) - return; - - if (m_pImage) - delete m_pImage; - - m_pImage = new QImage(data, w, h, 4 * w, QImage::Format_RGBA8888, &cleanUpPixels, data); - SetImage(); -} diff --git a/PdfReader/test/mainwindow.h b/PdfReader/test/mainwindow.h deleted file mode 100644 index 3c192b4fce..0000000000 --- a/PdfReader/test/mainwindow.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include -#include "../../../DesktopEditor/graphics/pro/Graphics.h" -#include "../../../DesktopEditor/fontengine/ApplicationFontsWorker.h" -#include "../../../DesktopEditor/common/Directory.h" -#include "../../PdfReader.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class MainWindow; } -QT_END_NAMESPACE - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); - -private slots: - void on_LeftButton_clicked(); - void on_RightButton_clicked(); - void on_RenderButton_clicked(); - - void on_OpenFileButton_clicked(); - - void on_ScaleSlider_sliderMoved(int position); - void on_verticalScrollBar_valueChanged(int value); - void on_horizontalScrollBar_valueChanged(int value); - -protected: - - void resizeEvent(QResizeEvent *event); - void closeEvent(QCloseEvent *event); - -private: - - void RenderPage(); - bool RenderOnByteData(int nPage, BYTE*& pBgraData, int& w, int& h); - void SetImage(); - void OpenFile(); - - bool IsFileOpened(); - double GetPageScaleByZoomType(const double& dPageWidth, const double& dPageHeight); - -private: - - enum ZoomType - { - pageWidth, - pageHeight, - custom - }; - - QImage* m_pImage; - QLabel* m_pLabel; - - QString m_sFile; - int m_nPosX; - int m_nPosY; - double m_dScale; - ZoomType m_eZoomType; - - // шрифты системы - NSFonts::IApplicationFonts* m_pFonts; - - // кэши для отрисовщика - NSFonts::IFontManager* m_pFontManager; - NSImages::IImageFilesCache* m_pImageCache; - - PdfReader::CPdfReader* m_pReader; - - Ui::MainWindow *ui; -}; -#endif // MAINWINDOW_H diff --git a/PdfReader/test/mainwindow.ui b/PdfReader/test/mainwindow.ui deleted file mode 100644 index 563ae4f558..0000000000 --- a/PdfReader/test/mainwindow.ui +++ /dev/null @@ -1,195 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 851 - 706 - - - - MainWindow - - - - - - 370 - 610 - 113 - 26 - - - - 745 - - - - - - 390 - 640 - 80 - 26 - - - - Display - - - - - - 470 - 640 - 80 - 26 - - - - Right - - - - - - 310 - 640 - 80 - 26 - - - - Left - - - - - - 760 - 10 - 81 - 26 - - - - Open File - - - - - - 10 - 10 - 741 - 26 - - - - - 0 - 0 - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - 10 - 570 - 811 - 16 - - - - 0 - - - Qt::Horizontal - - - - - - 820 - 40 - 16 - 531 - - - - 0 - - - Qt::Vertical - - - - - - 610 - 640 - 160 - 16 - - - - 50 - - - 600 - - - Qt::Horizontal - - - - - - 620 - 610 - 58 - 18 - - - - Zoom - - - - - - 10 - 50 - 801 - 511 - - - - - - - - 0 - 0 - 851 - 17 - - - - - PDF viewer - - - - - - - - diff --git a/PdfWriter/OnlineOfficeBinToPdf.cpp b/PdfWriter/OnlineOfficeBinToPdf.cpp deleted file mode 100644 index 138cb54a7a..0000000000 --- a/PdfWriter/OnlineOfficeBinToPdf.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "OnlineOfficeBinToPdf.h" - -#include "../DesktopEditor/common/File.h" -#include "../DesktopEditor/common/Directory.h" -#include "../DesktopEditor/common/Base64.h" -#include "../DesktopEditor/common/StringExt.h" - -#include "../DesktopEditor/graphics/MetafileToRenderer.h" -#include "../DesktopEditor/raster/BgraFrame.h" - -namespace NSOnlineOfficeBinToPdf -{ - class CMetafileToRenderterPDF : public IMetafileToRenderter - { - public: - CMetafileToRenderterPDF(IRenderer* pRenderer) : IMetafileToRenderter(pRenderer) - { - } - - public: - virtual void SetLinearGradiant(const double& x0, const double& y0, const double& x1, const double& y1) - { - ((CPdfRenderer*)m_pRenderer)->SetLinearGradient(x0, y0, x1, y1); - } - - virtual void SetRadialGradiant(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1) - { - ((CPdfRenderer*)m_pRenderer)->SetRadialGradient(dX0, dY0, dR0, dX1, dY1, dR1); - } - }; - - static bool ConvertBufferToPdf(CPdfRenderer* pPdf, BYTE* pBuffer, LONG lBufferLen, CConvertFromBinParams* pParams) - { - CMetafileToRenderterPDF oCorrector(pPdf); - oCorrector.SetTempDirectory(pPdf->GetTempDirectory()); - if (pParams) - { - oCorrector.SetMediaDirectory(pParams->m_sMediaDirectory); - oCorrector.SetInternalMediaDirectory(pParams->m_sInternalMediaDirectory); - oCorrector.SetThemesDirectory(pParams->m_sThemesDirectory); - - if (pParams->m_bIsUsePicker) - oCorrector.InitPicker(pPdf->GetApplicationFonts()); - } - NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pBuffer, lBufferLen, &oCorrector); - - return true; - } - bool ConvertBinToPdf(CPdfRenderer* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary, CConvertFromBinParams* pParams) - { - NSFile::CFileBinary oFile; - if (!oFile.OpenFile(wsSrcFile)) - return false; - - DWORD dwFileSize = oFile.GetFileSize(); - BYTE* pFileContent = new BYTE[dwFileSize]; - if (!pFileContent) - { - oFile.CloseFile(); - return false; - } - - DWORD dwReaded; - oFile.ReadFile(pFileContent, dwFileSize, dwReaded); - oFile.CloseFile(); - - bool bIsNeedDestroy = (NULL == pParams) ? true : false; - if (bIsNeedDestroy) - pParams = new CConvertFromBinParams(); - - if (pParams->m_sMediaDirectory.empty()) - pParams->m_sMediaDirectory = NSFile::GetDirectoryName(wsSrcFile); - - if (bBinary) - { - ConvertBufferToPdf(pPdf, pFileContent, dwFileSize, pParams); - } - else - { - int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize); - BYTE* pBuffer = new BYTE[nBufferLen]; - if (!pBuffer) - { - RELEASEARRAYOBJECTS(pFileContent); - - if (bIsNeedDestroy) - RELEASEOBJECT(pParams); - return false; - } - - if (NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)) - { - ConvertBufferToPdf(pPdf, pBuffer, nBufferLen, pParams); - } - else - { - RELEASEARRAYOBJECTS(pBuffer); - RELEASEARRAYOBJECTS(pFileContent); - - if (bIsNeedDestroy) - RELEASEOBJECT(pParams); - return false; - } - - RELEASEARRAYOBJECTS(pBuffer); - } - RELEASEARRAYOBJECTS(pFileContent); - - if (bIsNeedDestroy) - RELEASEOBJECT(pParams); - - if (!wsDstFile.empty()) - { - if (0 != pPdf->SaveToFile(wsDstFile)) - return false; - } - - return true; - } -} diff --git a/PdfWriter/OnlineOfficeBinToPdf.h b/PdfWriter/OnlineOfficeBinToPdf.h deleted file mode 100644 index c8b13a84c3..0000000000 --- a/PdfWriter/OnlineOfficeBinToPdf.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_ONLINEOFFICEBINTOPDF_H -#define _PDF_WRITER_ONLINEOFFICEBINTOPDF_H - -#include -#include "PdfRenderer.h" - -namespace NSOnlineOfficeBinToPdf -{ - bool ConvertBinToPdf(CPdfRenderer* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary, CConvertFromBinParams* pParams); -} - -#endif // _PDF_WRITER_ONLINEOFFICEBINTOPDF_H - diff --git a/PdfWriter/PdfRenderer.cpp b/PdfWriter/PdfRenderer.cpp deleted file mode 100644 index 2970d453f6..0000000000 --- a/PdfWriter/PdfRenderer.cpp +++ /dev/null @@ -1,2995 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#include "../DesktopEditor/common/File.h" -#include "../DesktopEditor/common/Directory.h" - -#include "PdfRenderer.h" - -#include "Src/Document.h" -#include "Src/Pages.h" -#include "Src/Image.h" -#include "Src/Font.h" -#include "Src/FontCidTT.h" -#include "Src/FontTT.h" -#include "Src/Annotation.h" -#include "Src/Destination.h" -#include "Src/Field.h" - -#include "../DesktopEditor/graphics/Image.h" -#include "../DesktopEditor/graphics/structures.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include "../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" -#include "../DesktopEditor/graphics/pro/Image.h" - -#include "../UnicodeConverter/UnicodeConverter.h" -#include "../Common/Network/FileTransporter/include/FileTransporter.h" - -#include "OnlineOfficeBinToPdf.h" - -#include - -#if defined(GetTempPath) -#undef GetTempPath -#endif - -#if defined(CreateFile) -#undef CreateFile -#endif - -#if defined(CreateDirectory) -#undef CreateDirectory -#endif - -#define MM_2_PT(X) ((X) * 72.0 / 25.4) -#define PT_2_MM(X) ((X) * 25.4 / 72.0) - -#define LONG_2_BOOL(X) ((X) ? true : false) - -#ifdef DrawText -#undef DrawText -#endif - -#ifdef LoadImage -#undef LoadImage -#endif - -using namespace PdfWriter; - -#define HI_SURROGATE_START 0xD800 -#define HI_SURROGATE_END 0xDBFF -#define LO_SURROGATE_START 0xDC00 -#define LO_SURROGATE_END 0xDFFF - - -static unsigned int* WStringToUtf32(const std::wstring& wsUnicodeText, unsigned int& unLen) -{ - if (wsUnicodeText.size() <= 0) - return NULL; - - unsigned int* pUnicodes = new unsigned int[wsUnicodeText.size()]; - if (!pUnicodes) - return NULL; - - unsigned int* pOutput = pUnicodes; - unLen = 0; - if (2 == sizeof(wchar_t)) - { - const wchar_t* wsEnd = wsUnicodeText.c_str() + wsUnicodeText.size(); - wchar_t* wsInput = (wchar_t*)wsUnicodeText.c_str(); - - wchar_t wLeading, wTrailing; - unsigned int unCode; - while (wsInput < wsEnd) - { - wLeading = *wsInput++; - if (wLeading < 0xD800 || wLeading > 0xDFFF) - { - pUnicodes[unLen++] = (unsigned int)wLeading; - } - else if (wLeading >= 0xDC00) - { - // Такого не должно быть - continue; - } - else - { - unCode = (wLeading & 0x3FF) << 10; - wTrailing = *wsInput++; - if (wTrailing < 0xDC00 || wTrailing > 0xDFFF) - { - // Такого не должно быть - continue; - } - else - { - pUnicodes[unLen++] = ((unCode | (wTrailing & 0x3FF)) + 0x10000); - } - } - } - } - else - { - unLen = wsUnicodeText.size(); - for (unsigned int unIndex = 0; unIndex < unLen; unIndex++) - { - pUnicodes[unIndex] = (unsigned int)wsUnicodeText.at(unIndex); - } - } - - return pUnicodes; -} - -// Этих типов браша нет в рендерере, мы их используем, когда конвертим из веба -static const long c_BrushTypeLinearGradient = 8001; -static const long c_BrushTypeRadialGradient = 8002; - -enum ERendererCommandType -{ - renderercommandtype_Text = 0x01, - renderercommandtype_Image = 0x02, - renderercommandtype_Path = 0x03, - renderercommandtype_Clip = 0x04 -}; -//---------------------------------------------------------------------------------------- -// -// CRendererCommandBase -// -//---------------------------------------------------------------------------------------- -class CRendererCommandBase -{ -public: - virtual ~CRendererCommandBase(){}; - virtual ERendererCommandType GetType() = 0; -}; -//---------------------------------------------------------------------------------------- -// -// CRendererTextCommand -// -//---------------------------------------------------------------------------------------- -class CRendererTextCommand : public CRendererCommandBase -{ -public: - CRendererTextCommand(unsigned char* pCodes, unsigned int nLen, const double& dX, const double& dY) - { - m_pCodes = pCodes; - m_nLen = nLen; - m_dX = dX; - m_dY = dY; - m_pFont = NULL; - m_dSize = -1; - m_lColor = 0; - m_nAlpha = 255; - m_dCharSpace = 0; - m_dHorScaling = 100; - m_nMode = (int)textrenderingmode_Fill; - - m_bNeedDoItalic = false; - m_bNeedDoBold = false; - } - ~CRendererTextCommand() - { - if (m_pCodes) - delete[] m_pCodes; - } - ERendererCommandType GetType() - { - return renderercommandtype_Text; - } - - inline double GetX() const - { - return m_dX; - } - inline double GetY() const - { - return m_dY; - } - inline unsigned char* GetCodes() const - { - return m_pCodes; - } - inline unsigned int GetCodesLen() const - { - return m_nLen; - } - inline void SetFont(CFontDict* pFont) - { - m_pFont = pFont; - } - inline void SetSize(const double& dSize) - { - m_dSize = dSize; - } - inline void SetColor(const LONG& lColor) - { - m_lColor = lColor; - } - inline void SetAlpha(const BYTE& nAlpha) - { - m_nAlpha = nAlpha; - } - inline void SetCharSpace(const double& dCharSpace) - { - m_dCharSpace = dCharSpace; - } - inline void SetHorScaling(const double& dKoef) - { - m_dHorScaling = dKoef; - } - inline void SetMode(const int& nMode) - { - m_nMode = nMode; - } - inline void SetNeedDoItalic(const bool& bItalic) - { - - - - m_bNeedDoItalic = bItalic; - } - inline void SetNeedDoBold(const bool& bBold) - { - m_bNeedDoBold = bBold; - } - inline CFontDict* GetFont() const - { - return m_pFont; - } - inline double GetSize() const - { - return m_dSize; - } - inline LONG GetColor() const - { - return m_lColor; - } - inline BYTE GetAlpha() const - { - return m_nAlpha; - } - inline double GetSpace() const - { - return m_dCharSpace; - } - inline double GetHorScaling() const - { - return m_dHorScaling; - } - inline int GetMode() const - { - return m_nMode; - } - inline bool IsNeedDoItalic() const - { - return m_bNeedDoItalic; - } - inline bool IsNeedDoBold() const - { - return m_bNeedDoBold; - } - -private: - - unsigned char* m_pCodes; - unsigned int m_nLen; - double m_dX; - double m_dY; - - CFontDict* m_pFont; - bool m_bNeedDoItalic; - bool m_bNeedDoBold; - double m_dSize; - LONG m_lColor; - BYTE m_nAlpha; - double m_dCharSpace; - int m_nMode; - double m_dHorScaling; -}; -//---------------------------------------------------------------------------------------- -// -// CCommandManager -// -//---------------------------------------------------------------------------------------- -CPdfRenderer::CCommandManager::CCommandManager(CPdfRenderer* pRenderer) : m_pRenderer(pRenderer) -{ -} -CPdfRenderer::CCommandManager::~CCommandManager() -{ - Clear(); -} -CRendererTextCommand* CPdfRenderer::CCommandManager::AddText(unsigned char* pCodes, unsigned int nLen, const double& dX, const double& dY) -{ - CRendererCommandBase* pCommand = new CRendererTextCommand(pCodes, nLen, dX, dY); - Add(pCommand); - return (CRendererTextCommand*)pCommand; -} -void CPdfRenderer::CCommandManager::Add(CRendererCommandBase* pCommand) -{ - if (pCommand) - { - if (m_vCommands.size() > 0 && pCommand->GetType() != m_vCommands.at(0)->GetType()) - Flush(); - - m_vCommands.push_back(pCommand); - } -} -void CPdfRenderer::CCommandManager::Flush() -{ - int nCommandsCount = m_vCommands.size(); - if (nCommandsCount > 0) - { - CPage* pPage = m_pRenderer->m_pPage; - pPage->GrSave(); - - pPage->SetTransform(m_oTransform.m11, m_oTransform.m12, m_oTransform.m21, m_oTransform.m22, m_oTransform.dx, m_oTransform.dy); - - ERendererCommandType eType = m_vCommands.at(0)->GetType(); - if (renderercommandtype_Text == eType) - { - pPage->BeginText(); - CRendererTextCommand* pText = NULL; - - CFontDict* pTextFont = NULL; - double dTextSize = -1; - LONG lTextColor = 0; - BYTE nTextAlpha = 255; - double dTextSpace = 0; - double dHorScaling = 100; - ETextRenderingMode eMode = textrenderingmode_Fill; - bool isNeedDoBold = false; - bool isNeedDoItalic = false; - double dLineWidth = -1; - - double dPrevX = -1000; - double dPrevY = -1000; - unsigned short ushPrevCode = 0; - - CTextLine oTextLine; - for (int nIndex = 0; nIndex < nCommandsCount; nIndex++) - { - pText = (CRendererTextCommand*)m_vCommands.at(nIndex); - if (!pText) - continue; - - if (pTextFont != pText->GetFont() || fabs(dTextSize - pText->GetSize()) > 0.001) - { - oTextLine.Flush(pPage); - pTextFont = pText->GetFont(); - dTextSize = pText->GetSize(); - pPage->SetFontAndSize(pTextFont, dTextSize); - } - - if (lTextColor != pText->GetColor()) - { - oTextLine.Flush(pPage); - lTextColor = pText->GetColor(); - TColor oColor = lTextColor; - pPage->SetFillColor(oColor.r, oColor.g, oColor.b); - pPage->SetStrokeColor(oColor.r, oColor.g, oColor.b); - } - - if (nTextAlpha != pText->GetAlpha()) - { - oTextLine.Flush(pPage); - nTextAlpha = pText->GetAlpha(); - pPage->SetFillAlpha(nTextAlpha); - pPage->SetStrokeAlpha(nTextAlpha); - } - - if (fabs(dTextSpace - pText->GetSpace()) > 0.001) - { - oTextLine.Flush(pPage); - dTextSpace = pText->GetSpace(); - pPage->SetCharSpace(dTextSpace); - } - - if ((int)eMode != pText->GetMode() || isNeedDoBold != pText->IsNeedDoBold()) - { - oTextLine.Flush(pPage); - eMode = (ETextRenderingMode)pText->GetMode(); - isNeedDoBold = pText->IsNeedDoBold(); - - if (isNeedDoBold && eMode == textrenderingmode_Fill) - { - double dNewLineWidth = dTextSize / 12 * 0.343; - if (fabs(dLineWidth - dNewLineWidth) > 0.001) - { - dLineWidth = dNewLineWidth; - pPage->SetLineWidth(dLineWidth); - } - - pPage->SetTextRenderingMode(textrenderingmode_FillThenStroke); - } - else - { - pPage->SetTextRenderingMode(eMode); - } - } - - if (fabs(dHorScaling - pText->GetHorScaling()) > 0.001) - { - oTextLine.Flush(pPage); - dHorScaling = pText->GetHorScaling(); - pPage->SetHorizontalScalling(dHorScaling); - } - - if (isNeedDoItalic != pText->IsNeedDoItalic()) - { - oTextLine.Flush(pPage); - - if (pText->IsNeedDoItalic()) - pPage->SetTextMatrix(1, 0, 0.26, 1, 0, 0); - else - pPage->SetTextMatrix(1, 0, 0, 1, 0, 0); - - isNeedDoItalic = pText->IsNeedDoItalic(); - } - - unsigned char* pCodes = pText->GetCodes(); - unsigned short ushCode = (pCodes[0] << 8) + pCodes[1]; - unsigned int unLen = pText->GetCodesLen(); - double dX = pText->GetX(); - double dY = pText->GetY(); - double dTextSize = pText->GetSize(); - double dWidth = ((CFontCidTrueType*)pText->GetFont())->GetWidth(ushCode) / 1000.0 * dTextSize; - - if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize)) - { - oTextLine.Flush(pPage); - if (!oTextLine.Add(pCodes, unLen, dX, dY, dWidth, dTextSize)) - { - pPage->DrawText(dX, dY, pCodes, unLen); - } - } - } - - oTextLine.Flush(pPage); - pPage->EndText(); - } - - pPage->GrRestore(); - } - - Clear(); -} -void CPdfRenderer::CCommandManager::Clear() -{ - for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++) - { - CRendererCommandBase* pCommand = m_vCommands.at(nIndex); - delete pCommand; - } - m_vCommands.clear(); -} -void CPdfRenderer::CCommandManager::SetTransform(const CTransform& oTransform) -{ - m_oTransform = oTransform; -} -void CPdfRenderer::CCommandManager::SetTransform(const double& m11, const double& m12, const double& m21, const double& m22, const double& dx, const double& dy) -{ - m_oTransform.Set(m11, m12, m21, m22, dx, dy); -} -//---------------------------------------------------------------------------------------- -// -// CPdfRenderer -// -//---------------------------------------------------------------------------------------- -CPdfRenderer::CPdfRenderer(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA) : m_oCommandManager(this) -{ - m_pAppFonts = pAppFonts; - - // Создаем менеджер шрифтов с собственным кэшем - m_pFontManager = pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(pAppFonts->GetStreams()); - m_pFontManager->SetOwnerCache(pMeasurerCache); - - m_pDocument = new CDocument(); - - if (isPDFA) - m_pDocument->SetPDFAConformanceMode(true); - - if (!m_pDocument || !m_pDocument->CreateNew()) - { - SetError(); - return; - } - - m_pDocument->SetCompressionMode(COMP_ALL); - - m_bValid = true; - m_bEdit = false; - m_bEditPage = false; - m_dPageHeight = 297; - m_dPageWidth = 210; - m_pPage = NULL; - m_pFont = NULL; - - m_bNeedUpdateTextFont = true; - m_bNeedUpdateTextColor = true; - m_bNeedUpdateTextAlpha = true; - m_bNeedUpdateTextCharSpace = true; - m_bNeedUpdateTextSize = true; - - m_wsTempFolder = L""; - SetTempFolder(NSFile::CFileBinary::GetTempPath()); -} -CPdfRenderer::~CPdfRenderer() -{ - RELEASEOBJECT(m_pDocument); - RELEASEINTERFACE(m_pFontManager); - - if (L"" != m_wsTempFolder) - NSDirectory::DeleteDirectory(m_wsTempFolder); -} -void CPdfRenderer::SetPassword(const std::wstring& wsPassword) -{ - if (!IsValid()) - return; - - m_pDocument->SetPasswords(wsPassword, wsPassword); -} - -void CPdfRenderer::SetDocumentID(const std::wstring& wsDocumentID) -{ - if (!IsValid()) - return; - - m_pDocument->SetDocumentID(wsDocumentID); -} -int CPdfRenderer::SaveToFile(const std::wstring& wsPath) -{ - // TODO: Переделать на код ошибки - if (!IsValid()) - return 1; - - m_oCommandManager.Flush(); - - if (!m_pDocument->SaveToFile(wsPath)) - return 1; - - return 0; -} -void CPdfRenderer::SetTempFolder(const std::wstring& wsPath) -{ - if (L"" != m_wsTempFolder) - NSDirectory::DeleteDirectory(m_wsTempFolder); - - int nCounter = 0; - m_wsTempFolder = wsPath; - int nPathLen = (int)m_wsTempFolder.length(); - if (nPathLen > 0) - { - const wchar_t* pData = m_wsTempFolder.c_str(); - if ((pData[nPathLen - 1] != '/') && (pData[nPathLen - 1] != '\\')) - m_wsTempFolder += L"/"; - - m_wsTempFolder += L"PDF"; - } - - std::wstring sTest = m_wsTempFolder; - while (NSDirectory::Exists(m_wsTempFolder)) - { - m_wsTempFolder = sTest + L"/PDF_" + std::to_wstring(nCounter); - nCounter++; - } - NSDirectory::CreateDirectory(m_wsTempFolder); -} -std::wstring CPdfRenderer::GetTempFile() -{ - return NSFile::CFileBinary::CreateTempFileWithUniqueName(m_wsTempFolder, L"PDF"); -} -std::wstring CPdfRenderer::GetTempDirectory() -{ - return m_wsTempFolder; -} -//---------------------------------------------------------------------------------------- -// Тип рендерера -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::get_Type(LONG* lType) -{ - *lType = c_nPDFWriter; - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для работы со страницей -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::NewPage() -{ - m_oCommandManager.Flush(); - - if (!IsValid() || m_bEdit) - return S_FALSE; - - m_pPage = m_pDocument->AddPage(); - - if (!m_pPage) - { - SetError(); - return S_FALSE; - } - - m_pPage->SetWidth(MM_2_PT(m_dPageWidth)); - m_pPage->SetHeight(MM_2_PT(m_dPageHeight)); - - Reset(); - - return S_OK; -} -HRESULT CPdfRenderer::get_Height(double* dHeight) -{ - *dHeight = m_dPageHeight; - return S_OK; -} -HRESULT CPdfRenderer::put_Height(const double& dHeight) -{ - if (!IsValid() || !m_pPage) - return S_FALSE; - - if (m_bEdit && m_bEditPage) - { - return S_OK; - } - - m_dPageHeight = dHeight; - m_pPage->SetHeight(MM_2_PT(dHeight)); - return S_OK; -} -HRESULT CPdfRenderer::get_Width(double* dWidth) -{ - *dWidth = m_dPageWidth; - return S_OK; -} -HRESULT CPdfRenderer::put_Width(const double& dWidth) -{ - if (!IsValid() || !m_pPage) - return S_FALSE; - - if (m_bEdit && m_bEditPage) - { - return S_OK; - } - - m_dPageWidth = dWidth; - m_pPage->SetWidth(MM_2_PT(dWidth)); - return S_OK; -} -HRESULT CPdfRenderer::get_DpiX(double* dDpiX) -{ - *dDpiX = 72; - return S_OK; -} -HRESULT CPdfRenderer::get_DpiY(double* dDpiY) -{ - *dDpiY = 72; - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для работы с Pen -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::get_PenColor(LONG* lColor) -{ - *lColor = m_oPen.GetColor(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenColor(const LONG& lColor) -{ - m_oPen.SetColor(lColor); - return S_OK; -} -HRESULT CPdfRenderer::get_PenAlpha(LONG* lAlpha) -{ - *lAlpha = m_oPen.GetAlpha(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenAlpha(const LONG& lAlpha) -{ - m_oPen.SetAlpha(lAlpha); - return S_OK; -} -HRESULT CPdfRenderer::get_PenSize(double* dSize) -{ - *dSize = m_oPen.GetSize(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenSize(const double& dSize) -{ - m_oPen.SetSize(dSize); - return S_OK; -} -HRESULT CPdfRenderer::get_PenDashStyle(BYTE* nDashStyle) -{ - *nDashStyle = m_oPen.GetDashStyle(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenDashStyle(const BYTE& nDashStyle) -{ - m_oPen.SetDashStyle(nDashStyle); - return S_OK; -} -HRESULT CPdfRenderer::get_PenLineStartCap(BYTE* nCapStyle) -{ - *nCapStyle = m_oPen.GetStartCapStyle(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenLineStartCap(const BYTE& nCapStyle) -{ - m_oPen.SetStartCapStyle(nCapStyle); - return S_OK; -} -HRESULT CPdfRenderer::get_PenLineEndCap(BYTE* nCapStyle) -{ - *nCapStyle = m_oPen.GetEndCapStyle(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenLineEndCap(const BYTE& nCapStyle) -{ - m_oPen.SetEndCapStyle(nCapStyle); - return S_OK; -} -HRESULT CPdfRenderer::get_PenLineJoin(BYTE* nJoinStyle) -{ - *nJoinStyle = m_oPen.GetJoinStyle(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenLineJoin(const BYTE& nJoinStyle) -{ - m_oPen.SetJoinStyle(nJoinStyle); - return S_OK; -} -HRESULT CPdfRenderer::get_PenDashOffset(double* dOffset) -{ - *dOffset = m_oPen.GetDashOffset(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenDashOffset(const double& dOffset) -{ - m_oPen.SetDashOffset(dOffset); - return S_OK; -} -HRESULT CPdfRenderer::get_PenAlign(LONG* lAlign) -{ - *lAlign = m_oPen.GetAlign(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenAlign(const LONG& lAlign) -{ - m_oPen.SetAlign(lAlign); - return S_OK; -} -HRESULT CPdfRenderer::get_PenMiterLimit(double* dMiter) -{ - *dMiter = m_oPen.GetMiter(); - return S_OK; -} -HRESULT CPdfRenderer::put_PenMiterLimit(const double& dMiter) -{ - m_oPen.SetMiter(dMiter); - return S_OK; -} -HRESULT CPdfRenderer::PenDashPattern(double* pPattern, LONG lCount) -{ - m_oPen.SetDashPattern(pPattern, lCount); - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для работы с Brush -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::get_BrushType(LONG* lType) -{ - *lType = m_oBrush.GetType(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushType(const LONG& lType) -{ - m_oBrush.SetType(lType); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushColor1(LONG* lColor) -{ - *lColor = m_oBrush.GetColor1(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushColor1(const LONG& lColor) -{ - if (lColor != m_oBrush.GetColor1()) - { - m_oBrush.SetColor1(lColor); - m_bNeedUpdateTextColor = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_BrushAlpha1(LONG* lAlpha) -{ - *lAlpha = m_oBrush.GetAlpha1(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushAlpha1(const LONG& lAlpha) -{ - if (lAlpha != m_oBrush.GetAlpha1()) - { - m_oBrush.SetAlpha1(lAlpha); - m_bNeedUpdateTextAlpha = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_BrushColor2(LONG* lColor) -{ - *lColor = m_oBrush.GetColor2(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushColor2(const LONG& lColor) -{ - m_oBrush.SetColor2(lColor); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushAlpha2(LONG* lAlpha) -{ - *lAlpha = m_oBrush.GetAlpha2(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushAlpha2(const LONG& lAlpha) -{ - m_oBrush.SetAlpha2(lAlpha); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushTexturePath(std::wstring* wsPath) -{ - *wsPath = m_oBrush.GetTexturePath(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushTexturePath(const std::wstring& wsPath) -{ - m_oBrush.SetTexturePath(wsPath); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushTextureMode(LONG* lMode) -{ - *lMode = m_oBrush.GetTextureMode(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushTextureMode(const LONG& lMode) -{ - m_oBrush.SetTextureMode(lMode); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushTextureAlpha(LONG* lAlpha) -{ - *lAlpha = m_oBrush.GetTextureAlpha(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushTextureAlpha(const LONG& lAlpha) -{ - m_oBrush.SetTextureAlpha(lAlpha); - return S_OK; -} -HRESULT CPdfRenderer::get_BrushLinearAngle(double* dAngle) -{ - *dAngle = m_oBrush.GetLinearAngle(); - return S_OK; -} -HRESULT CPdfRenderer::put_BrushLinearAngle(const double& dAngle) -{ - m_oBrush.SetLinearAngle(dAngle); - return S_OK; -} -HRESULT CPdfRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) -{ - // Данными параметрами пользуемся, только если пришла команда EnableBrushRect, если команда не пришла, тогда - // ориентируемся на границы пата. - m_oBrush.SetBrushRect(nVal, dLeft, dTop, dWidth, dHeight); - m_oBrush.EnableBrushRect(1 == nVal ? true : false); - return S_OK; -} -HRESULT CPdfRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) -{ - // TODO: Пока определяется все по границам пата - return S_OK; -} -HRESULT CPdfRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG lCount) -{ - m_oBrush.SetGradientColors(lColors, pPositions, lCount); - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для работы со шрифтами -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::get_FontName(std::wstring* wsName) -{ - *wsName = m_oFont.GetName(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontName(const std::wstring& wsName) -{ - if (wsName != m_oFont.GetName()) - { - m_oFont.SetName(wsName); - m_bNeedUpdateTextFont = true; - } - - return S_OK; -} -HRESULT CPdfRenderer::get_FontPath(std::wstring* wsPath) -{ - *wsPath = m_oFont.GetPath(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontPath(const std::wstring& wsPath) -{ - if (wsPath != m_oFont.GetPath()) - { - m_oFont.SetPath(wsPath); - m_bNeedUpdateTextFont = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_FontSize(double* dSize) -{ - *dSize = m_oFont.GetSize(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontSize(const double& dSize) -{ - if (fabs(dSize - m_oFont.GetSize()) > 0.001) - { - m_oFont.SetSize(dSize); - m_bNeedUpdateTextSize = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_FontStyle(LONG* lStyle) -{ - *lStyle = m_oFont.GetStyle(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontStyle(const LONG& lStyle) -{ - if (lStyle != m_oFont.GetStyle()) - { - m_oFont.SetStyle(lStyle); - m_bNeedUpdateTextFont = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_FontStringGID(INT* bGid) -{ - *bGid = m_oFont.GetGid() ? 1 : 0; - return S_OK; -} -HRESULT CPdfRenderer::put_FontStringGID(const INT& bGid) -{ - m_oFont.SetGid(bGid ? true : false); - return S_OK; -} -HRESULT CPdfRenderer::get_FontCharSpace(double* dSpace) -{ - *dSpace = m_oFont.GetCharSpace(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontCharSpace(const double& dSpace) -{ - if (fabs(dSpace - m_oFont.GetCharSpace()) > 0.001) - { - m_oFont.SetCharSpace(dSpace); - m_bNeedUpdateTextCharSpace = true; - } - return S_OK; -} -HRESULT CPdfRenderer::get_FontFaceIndex(int* nFaceIndex) -{ - *nFaceIndex = (int)m_oFont.GetFaceIndex(); - return S_OK; -} -HRESULT CPdfRenderer::put_FontFaceIndex(const int& nFaceIndex) -{ - if (nFaceIndex != m_oFont.GetFaceIndex()) - { - m_oFont.SetFaceIndex(nFaceIndex); - m_bNeedUpdateTextFont = true; - } - - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для вывода текста -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid()) - return S_FALSE; - - unsigned int unUnicode = lUnicode; - unsigned char* pCodes = EncodeString(&unUnicode, 1); - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid() || !wsUnicodeText.size()) - return S_FALSE; - - unsigned int unLen; - unsigned int* pUnicodes = WStringToUtf32(wsUnicodeText, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned char* pCodes = EncodeString(pUnicodes, unLen); - delete[] pUnicodes; - - if (!pCodes) - return S_FALSE; - - // Специальный случай для текста из Djvu, нам не нужно, чтобы он рисовался - if (L"" == m_oFont.GetPath() && L"DjvuEmptyFont" == m_oFont.GetName()) - { - if (m_bNeedUpdateTextFont) - { - m_oFont.SetName(L"Arial"); - UpdateFont(); - m_oFont.SetName(L"DjvuEmptyFont"); - if (!m_pFont) - return S_FALSE; - } - - double dFontSize = MM_2_PT(dH); - double dStringWidth = 0; - for (unsigned int unIndex = 0; unIndex < unLen; unIndex++) - { - unsigned short ushCode = (pCodes[2 * unIndex] << 8) + pCodes[2 * unIndex + 1]; - dStringWidth += m_pFont->GetWidth(ushCode) * dFontSize / 1000.0; - } - - double dResultWidth = MM_2_PT(dW); - - CTransform& t = m_oTransform; - m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); - - CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen * 2, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH)); - pText->SetFont(m_pFont); - pText->SetSize(dFontSize); - pText->SetMode(textrenderingmode_Invisible); - if (fabs(dStringWidth) > 0.001) - pText->SetHorScaling(dResultWidth / dStringWidth * 100); - - return S_OK; - } - - return DrawText(pCodes, unLen * 2, dX, dY) ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid()) - return S_FALSE; - - unsigned int unUnicode = lUnicode; - unsigned int unGID = lGid; - unsigned char* pCodes = EncodeGID(unGID, &unUnicode, 1); - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::CommandDrawTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int unGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid() || (!wsUnicodeText.size() && (!pGids || !unGidsCount))) - return S_FALSE; - - unsigned int unLen = 0; - unsigned int* pUnicodes = NULL; - if (pGids && unGidsCount) - { - unLen = unGidsCount; - if (wsUnicodeText.size()) - { - unsigned int unUnicodeLen; - pUnicodes = WStringToUtf32(wsUnicodeText, unUnicodeLen); - if (!pUnicodes || unUnicodeLen != unLen) - RELEASEARRAYOBJECTS(pUnicodes); - } - - if (!pUnicodes) - { - pUnicodes = new unsigned int[unLen]; - if (!pUnicodes) - return S_FALSE; - - for (unsigned int unIndex = 0; unIndex < unLen; unIndex++) - pUnicodes[unIndex] = pGids[unIndex]; - } - } - else - { - pUnicodes = WStringToUtf32(wsUnicodeText, unLen); - if (!pUnicodes) - return S_FALSE; - } - - unsigned char* pCodes = EncodeString(pUnicodes, unLen, pGids); - RELEASEARRAYOBJECTS(pUnicodes); - return DrawText(pCodes, unLen * 2, dX, dY) ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid()) - return S_FALSE; - - unsigned char* pCodes = EncodeGID(unGid, pUnicodes, unUnicodeCount); - return DrawText(pCodes, 2, dX, dY) ? S_OK : S_FALSE; -} -//---------------------------------------------------------------------------------------- -// Маркеры команд -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::BeginCommand(const DWORD& dwType) -{ - // Здесь мы ничего не делаем - return S_OK; -} -HRESULT CPdfRenderer::EndCommand(const DWORD& dwType) -{ - if (!IsPageValid()) - return S_FALSE; - - // Здесь мы различаем лишь 2 команды: присоединить текущий пат к клипу и отменить клип - if (c_nClipType == dwType) - { - m_oCommandManager.Flush(); - m_pPage->GrSave(); - m_lClipDepth++; - UpdateTransform(); - - if (c_nClipRegionTypeEvenOdd & m_lClipMode) - m_oPath.Clip(m_pPage, true); - else - m_oPath.Clip(m_pPage, false); - } - else if (c_nResetClipType == dwType) - { - m_oCommandManager.Flush(); - while (m_lClipDepth) - { - m_pPage->GrRestore(); - m_lClipDepth--; - } - } - else if (c_nPageType == dwType) - { - for (int nIndex = 0, nCount = m_vDestinations.size(); nIndex < nCount; ++nIndex) - { - TDestinationInfo& oInfo = m_vDestinations.at(nIndex); - if (m_pDocument->GetPagesCount() > oInfo.unDestPage) - { - AddLink(oInfo.pPage, oInfo.dX, oInfo.dY, oInfo.dW, oInfo.dH, oInfo.dDestX, oInfo.dDestY, oInfo.unDestPage); - m_vDestinations.erase(m_vDestinations.begin() + nIndex); - nIndex--; - nCount--; - } - } - } - - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Функции для работы с патом -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::PathCommandStart() -{ - m_oPath.Clear(); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandEnd() -{ - m_oPath.Clear(); - return S_OK; -} -HRESULT CPdfRenderer::DrawPath(const LONG& lType) -{ - m_oCommandManager.Flush(); - - if (!IsPageValid()) - return S_FALSE; - - bool bStroke = LONG_2_BOOL(lType & c_nStroke); - bool bFill = LONG_2_BOOL(lType & c_nWindingFillMode); - bool bEoFill = LONG_2_BOOL(lType & c_nEvenOddFillMode); - - m_pPage->GrSave(); - UpdateTransform(); - - if (bStroke) - UpdatePen(); - - std::wstring sTextureOldPath = L""; - std::wstring sTextureTmpPath = L""; - - if (bFill || bEoFill) - { - if (c_BrushTypeTexture == m_oBrush.GetType()) - { - sTextureOldPath = m_oBrush.GetTexturePath(); - sTextureTmpPath = GetDownloadFile(sTextureOldPath); - - if (!sTextureTmpPath.empty()) - m_oBrush.SetTexturePath(sTextureTmpPath); - } - - UpdateBrush(); - } - - if (!m_pShading) - { - m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill); - } - else - { - if (bFill || bEoFill) - { - m_pPage->GrSave(); - m_oPath.Clip(m_pPage, bEoFill); - - if (NULL != m_pShadingExtGrState) - m_pPage->SetExtGrState(m_pShadingExtGrState); - - m_pPage->DrawShading(m_pShading); - m_pPage->GrRestore(); - } - - if (bStroke) - m_oPath.Draw(m_pPage, bStroke, false, false); - } - - m_pPage->GrRestore(); - - if (!sTextureTmpPath.empty()) - { - m_oBrush.SetTexturePath(sTextureOldPath); - - if (NSFile::CFileBinary::Exists(sTextureTmpPath)) - NSFile::CFileBinary::Remove(sTextureTmpPath); - } - - return S_OK; -} -HRESULT CPdfRenderer::PathCommandMoveTo(const double& dX, const double& dY) -{ - m_oPath.MoveTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandLineTo(const double& dX, const double& dY) -{ - m_oPath.LineTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandLinesTo(double* pPoints, const int& nCount) -{ - if (nCount < 4 || !pPoints) - return S_OK; - - if (!m_oPath.IsMoveTo()) - m_oPath.MoveTo(MM_2_PT(pPoints[0]), MM_2_PT(m_dPageHeight - pPoints[1])); - - int nPointsCount = (nCount / 2) - 1; - for (int nIndex = 1; nIndex <= nPointsCount; ++nIndex) - { - m_oPath.LineTo(MM_2_PT(pPoints[nIndex * 2]), MM_2_PT(m_dPageHeight - pPoints[nIndex * 2 + 1])); - } - - return S_OK; -} -HRESULT CPdfRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) -{ - m_oPath.CurveTo(MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dX2), MM_2_PT(m_dPageHeight - dY2), MM_2_PT(dXe), MM_2_PT(m_dPageHeight - dYe)); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount) -{ - if (nCount < 8 || !pPoints) - return S_OK; - - if (!m_oPath.IsMoveTo()) - m_oPath.MoveTo(MM_2_PT(pPoints[0]), MM_2_PT(m_dPageHeight - pPoints[1])); - - int nPointsCount = (nCount - 2) / 6; - double* pCur = pPoints + 2; - for (int nIndex = 0; nIndex <= nPointsCount; ++nIndex, pCur += 6) - { - m_oPath.CurveTo(MM_2_PT(pCur[0]), MM_2_PT(m_dPageHeight - pCur[1]), MM_2_PT(pCur[2]), MM_2_PT(m_dPageHeight - pCur[3]), MM_2_PT(pCur[4]), MM_2_PT(m_dPageHeight - pCur[5])); - } - - return S_OK; -} -HRESULT CPdfRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) -{ - m_oPath.ArcTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH), dStartAngle, dSweepAngle); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandClose() -{ - m_oPath.Close(); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandGetCurrentPoint(double* dX, double* dY) -{ - m_oPath.GetLastPoint(*dX, *dY); - *dX = PT_2_MM(*dX); - *dY = PT_2_MM(*dY); - return S_OK; -} -HRESULT CPdfRenderer::PathCommandTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH) -{ - unsigned int unUnicode = lUnicode; - bool bRes = PathCommandDrawText(&unUnicode, 1, dX, dY, NULL); - return bRes ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::PathCommandText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - unsigned int unLen; - unsigned int* pUnicodes = WStringToUtf32(wsUnicodeText, unLen); - if (!pUnicodes) - return S_FALSE; - - PathCommandDrawText(pUnicodes, unLen, dX, dY, NULL); - delete[] pUnicodes; - - return S_OK; -} -HRESULT CPdfRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH) -{ - unsigned int unUnicode = lUnicode; - unsigned int unGid = lGid; - bool bRes = PathCommandDrawText(&unUnicode, 1, dX, dY, &unGid); - return bRes ? S_OK : S_FALSE; -} -HRESULT CPdfRenderer::PathCommandTextEx(const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int unGidsCount, const double& dX, const double& dY, const double& dW, const double& dH) -{ - if (!IsPageValid() || (!wsUnicodeText.size() && (!pGids || !unGidsCount))) - return S_FALSE; - - unsigned int unLen = 0; - unsigned int* pUnicodes = NULL; - if (pGids && unGidsCount) - { - unLen = unGidsCount; - if (wsUnicodeText.size()) - { - unsigned int unUnicodeLen; - pUnicodes = WStringToUtf32(wsUnicodeText, unUnicodeLen); - if (!pUnicodes || unUnicodeLen != unLen) - RELEASEARRAYOBJECTS(pUnicodes); - } - - if (!pUnicodes) - { - pUnicodes = new unsigned int[unLen]; - if (!pUnicodes) - return S_FALSE; - - for (unsigned int unIndex = 0; unIndex < unLen; unIndex++) - pUnicodes[unIndex] = pGids[unIndex]; - } - } - else - { - pUnicodes = WStringToUtf32(wsUnicodeText, unLen); - if (!pUnicodes) - return S_FALSE; - } - - bool bRes = PathCommandDrawText(pUnicodes, unLen, dX, dY, pGids); - RELEASEARRAYOBJECTS(pUnicodes); - - return bRes ? S_OK : S_FALSE; -} -//---------------------------------------------------------------------------------------- -// Функции для вывода изображений -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH) -{ - m_oCommandManager.Flush(); - - if (!IsPageValid() || !pImage) - return S_OK; - - if (!DrawImage((Aggplus::CImage*)pImage, dX, dY, dW, dH, 255)) - return S_FALSE; - - return S_OK; -} -HRESULT CPdfRenderer::DrawImageFromFile(const std::wstring& wsImagePathSrc, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) -{ - m_oCommandManager.Flush(); - - if (!IsPageValid()) - return S_OK; - - std::wstring sTempImagePath = GetDownloadFile(wsImagePathSrc); - std::wstring wsImagePath = sTempImagePath.empty() ? wsImagePathSrc : sTempImagePath; - - Aggplus::CImage* pAggImage = NULL; - - CImageFileFormatChecker oImageFormat(wsImagePath); - if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_EMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVM == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVG == oImageFormat.eFileType) - { - // TODO: Реализовать отрисовку метафайлов по-нормальному - MetaFile::IMetaFile* pMeta = MetaFile::Create(m_pAppFonts); - pMeta->LoadFromFile(wsImagePath.c_str()); - - double dNewW = std::max(10.0, dW) / 25.4 * 300; - std::wstring wsTempFile = GetTempFile(); - pMeta->ConvertToRaster(wsTempFile.c_str(), _CXIMAGE_FORMAT_PNG, dNewW); - - RELEASEOBJECT(pMeta); - - pAggImage = new Aggplus::CImage(wsTempFile); - } - else - { - pAggImage = new Aggplus::CImage(wsImagePath); - } - - HRESULT hRes = S_OK; - if (!pAggImage || !DrawImage(pAggImage, dX, dY, dW, dH, nAlpha)) - hRes = S_FALSE; - - if (NSFile::CFileBinary::Exists(sTempImagePath)) - NSFile::CFileBinary::Remove(sTempImagePath); - - if (pAggImage) - delete pAggImage; - - return hRes; -} -//---------------------------------------------------------------------------------------- -// Функции для выставления преобразования -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) -{ - m_oCommandManager.Flush(); - m_oTransform.Set(dM11, dM12, dM21, dM22, dX, dY); - return S_OK; -} -HRESULT CPdfRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY) -{ - *dM11 = m_oTransform.m11; - *dM12 = m_oTransform.m12; - *dM21 = m_oTransform.m21; - *dM22 = m_oTransform.m22; - *dX = m_oTransform.dx; - *dY = m_oTransform.dy; - return S_OK; -} -HRESULT CPdfRenderer::ResetTransform() -{ - m_oCommandManager.Flush(); - m_oTransform.Reset(); - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Тип клипа -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::get_ClipMode(LONG* lMode) -{ - *lMode = m_lClipMode; - return S_OK; -} -HRESULT CPdfRenderer::put_ClipMode(const LONG& lMode) -{ - m_lClipMode = lMode; - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Дополнительные функции -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::CommandLong(const LONG& lType, const LONG& lCommand) -{ - return S_OK; -} -HRESULT CPdfRenderer::CommandDouble(const LONG& lType, const double& dCommand) -{ - return S_OK; -} -HRESULT CPdfRenderer::CommandString(const LONG& lType, const std::wstring& sCommand) -{ - return S_OK; -} -HRESULT CPdfRenderer::AddHyperlink(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsUrl, const std::wstring& wsTooltip) -{ - NSUnicodeConverter::CUnicodeConverter conv; - CAnnotation* pAnnot = m_pDocument->CreateUriLinkAnnot(m_pPage, TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)), conv.SASLprepToUtf8(wsUrl).c_str()); - pAnnot->SetBorderStyle(EBorderSubtype::border_subtype_Solid, 0); - return S_OK; -} -HRESULT CPdfRenderer::AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage) -{ - unsigned int unPagesCount = m_pDocument->GetPagesCount(); - if (unPagesCount == 0) - return S_OK; - - CPage* pPage = m_pDocument->GetPage(nPage); - if (!pPage) - { - m_vDestinations.push_back(TDestinationInfo(m_pPage, dX, dY, dW, dH, dDestX, dDestY, nPage)); - } - else - { - AddLink(m_pPage, dX, dY, dW, dH, dDestX, dDestY, nPage); - } - - return S_OK; -} -HRESULT CPdfRenderer::AddFormField(const CFormFieldInfo &oInfo) -{ - unsigned int unPagesCount = m_pDocument->GetPagesCount(); - if (!m_pDocument || 0 == unPagesCount) - return S_OK; - - if (m_bNeedUpdateTextFont) - UpdateFont(); - - if (!m_pFont) - return S_OK; - - PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); - if (!pFontTT) - return S_OK; - - double dX, dY, dW, dH; - oInfo.GetBounds(dX, dY, dW, dH); - - CFieldBase* pFieldBase = NULL; - - bool bRadioButton = false; - - if (oInfo.IsTextField()) - { - CTextField* pField = m_pDocument->CreateTextField(); - pFieldBase = static_cast(pField); - } - else if (oInfo.IsDropDownList()) - { - CChoiceField* pField = m_pDocument->CreateChoiceField(); - pFieldBase = static_cast(pField); - } - else if (oInfo.IsCheckBox()) - { - const CFormFieldInfo::CCheckBoxFormPr* pPr = oInfo.GetCheckBoxPr(); - - CCheckBoxField* pField = NULL; - std::wstring wsGroupName = pPr->GetGroupKey(); - if (L"" != wsGroupName) - { - bRadioButton = true; - CRadioGroupField* pRadioGroup = m_pDocument->GetRadioGroupField(wsGroupName); - if (pRadioGroup) - pField = pRadioGroup->CreateKid(); - } - else - { - pField = m_pDocument->CreateCheckBoxField(); - } - - pFieldBase = static_cast(pField); - } - else if (oInfo.IsPicture()) - { - CPictureField* pField = m_pDocument->CreatePictureField(); - pFieldBase = static_cast(pField); - } - else if (oInfo.IsSignature()) - { - CSignatureField* pField = m_pDocument->CreateSignatureField(); - pFieldBase = static_cast(pField); - } - - if (!pFieldBase) - return S_FALSE; - - // 0 - Right - // 1 - Left - // 2 - Center - // 3 - Justify - // 4 - Distributed - unsigned int unAlign = oInfo.GetJc(); - if (0 == unAlign) - pFieldBase->SetAlign(CFieldBase::EFieldAlignType::Right); - else if (2 == unAlign) - pFieldBase->SetAlign(CFieldBase::EFieldAlignType::Center); - - if (oInfo.HaveBorder()) - { - unsigned char unR, unG, unB, unA; - oInfo.GetBorderColor(unR, unG, unB, unA); - - pFieldBase->SetFieldBorder(EBorderSubtype::border_subtype_Solid, TRgb(unR, unG, unB), MM_2_PT(oInfo.GetBorderSize()), 0, 0, 0); - } - - if (oInfo.HaveShd()) - { - unsigned char unR, unG, unB, unA; - oInfo.GetShdColor(unR, unG, unB, unA); - pFieldBase->SetShd(TRgb(unR, unG, unB)); - } - - pFieldBase->SetRequiredFlag(oInfo.IsRequired()); - pFieldBase->SetFieldHint(oInfo.GetHelpText()); - - bool isBold = m_oFont.IsBold(); - bool isItalic = m_oFont.IsItalic(); - - - if (oInfo.IsTextField()) - { - const CFormFieldInfo::CTextFormPr* pPr = oInfo.GetTextPr(); - std::wstring wsValue = pPr->GetTextValue(); - - unsigned int unLen; - unsigned int* pUnicodes = WStringToUtf32(wsValue, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned short* pCodes = new unsigned short[unLen]; - if (!pCodes) - { - RELEASEARRAYOBJECTS(pUnicodes); - return S_FALSE; - } - - CFontCidTrueType** ppFonts = new CFontCidTrueType*[unLen]; - if (!ppFonts) - { - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - return S_FALSE; - } - - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned int unUnicode = pUnicodes[unIndex]; - - if (!m_pFont->HaveChar(unUnicode)) - { - std::wstring wsFontFamily = m_pAppFonts->GetFontBySymbol(unUnicode); - CFontCidTrueType* pTempFont = GetFont(wsFontFamily, isBold, isItalic); - if (pTempFont) - { - pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = pTempFont; - continue; - } - } - - pCodes[unIndex] = m_pFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = m_pFont; - } - - CTextField* pField = dynamic_cast(pFieldBase); - if (!pField) - { - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); - return S_FALSE; - } - - double _dY = m_pPage->GetHeight() - MM_2_PT(dY); - double _dB = m_pPage->GetHeight() - MM_2_PT(dY + dH); - - double dMargin = 2; // такой отступ используется в AdobeReader - double dBaseLine = MM_2_PT(dH - oInfo.GetBaseLineOffset()); - double dShiftX = dMargin; - - pFieldBase->AddPageRect(m_pPage, TRect(MM_2_PT(dX) - dMargin, _dY, MM_2_PT(dX + dW) + dMargin, _dB)); - - pField->SetMaxLen(pPr->GetMaxCharacters()); - pField->SetCombFlag(pPr->IsComb()); - pField->SetAutoFit(pPr->IsAutoFit()); - pField->SetMultilineFlag(pPr->IsMultiLine()); - - bool isComb = pPr->IsComb(); - unsigned int unAlign = oInfo.GetJc(); - double dFontSize = m_oFont.GetSize(); - - TColor oColor = m_oBrush.GetTColor1(); - bool isPlaceHolder = oInfo.IsPlaceHolder(); - - TRgb oNormalColor(oColor.r, oColor.g, oColor.b); - TRgb oPlaceHolderColor; - oPlaceHolderColor.r = oNormalColor.r + (1.0 - oNormalColor.r) / 2.0; - oPlaceHolderColor.g = oNormalColor.g + (1.0 - oNormalColor.g) / 2.0; - oPlaceHolderColor.b = oNormalColor.b + (1.0 - oNormalColor.b) / 2.0; - - if (!isPlaceHolder) - pField->SetTextValue(wsValue); - - if (!isComb && pPr->IsMultiLine()) - { - unsigned short* pCodes2 = new unsigned short[unLen]; - unsigned int* pWidths = new unsigned int[unLen]; - - unsigned short ushSpaceCode = 0xFFFF; - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - pCodes2[unIndex] = (0x0020 == pUnicodes[unIndex] ? ushSpaceCode : 0); - pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); - } - - m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); - - // TODO: Разобраться более детально по какой именно высоте идет в Adobe расчет - // пока временно оставим (H - 3 * margin) - if (pPr->IsAutoFit()) - dFontSize = m_oLinesManager.ProcessAutoFit(MM_2_PT(dW), (MM_2_PT(dH) - 3 * dMargin)); - - double dLineHeight = pFontTT->GetLineHeight() * dFontSize / 1000.0; - - m_oLinesManager.CalculateLines(dFontSize, MM_2_PT(dW)); - - pField->StartTextAppearance(m_pFont, dFontSize, isPlaceHolder ? oPlaceHolderColor : oNormalColor, 1.0); - - unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); - double dLineShiftY = MM_2_PT(dH) - pFontTT->GetLineHeight() * dFontSize / 1000.0 - dMargin; - for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) - { - unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); - double dLineShiftX = dShiftX; - double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); - if (0 == unAlign) - dLineShiftX += MM_2_PT(dW) - dLineWidth; - else if (2 == unAlign) - dLineShiftX += (MM_2_PT(dW) - dLineWidth) / 2; - - int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); - if (nInLineCount > 0) - pField->AddLineToTextAppearance(dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, ppFonts + unLineStart, NULL); - - dLineShiftY -= dLineHeight; - } - - pField->EndTextAppearance(); - - m_oLinesManager.Clear(); - - delete[] pCodes2; - delete[] pWidths; - } - else - { - double* pShifts = NULL; - unsigned int unShiftsCount = 0; - - if (isComb) - { - pField->SetDoNotScrollFlag(true); - pField->SetDoNotSpellCheckFlag(true); - pField->SetMultilineFlag(false); - - unShiftsCount = unLen; - pShifts = new double[unShiftsCount]; - if (pShifts && unShiftsCount) - { - // Сдвиг нулевой для comb форм и не забываем, что мы к ширине добавили 2 * dMargin - dShiftX = 0; - unsigned int unCellsCount = std::max(unShiftsCount, pPr->GetMaxCharacters()); - double dPrevW = 0; - double dCellW = (MM_2_PT(dW) + 2 * dMargin) / unCellsCount; - - if (0 == unAlign && unShiftsCount) - dPrevW = (unCellsCount - unShiftsCount) * dCellW; - - for (unsigned int unIndex = 0; unIndex < unShiftsCount; ++unIndex) - { - unsigned short ushCode = pCodes[unIndex]; - double dGlyphWidth = ppFonts[unIndex]->GetGlyphWidth(ushCode) / 1000.0 * dFontSize; - double dTempShift = (dCellW - dGlyphWidth) / 2; - pShifts[unIndex] = dPrevW + dTempShift; - dPrevW = dCellW - dTempShift; - - } - } - else - { - unShiftsCount = 0; - } - } - else if (0 == unAlign || 2 == unAlign) - { - double dSumWidth = 0; - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned short ushCode = pCodes[unIndex]; - double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; - dSumWidth += dLetterWidth; - } - - if (0 == unAlign && MM_2_PT(dW) - dSumWidth > 0) - dShiftX += MM_2_PT(dW) - dSumWidth; - else if (2 == unAlign && (MM_2_PT(dW) - dSumWidth) / 2 > 0) - dShiftX += (MM_2_PT(dW) - dSumWidth) / 2; - } - - pField->SetTextAppearance(wsValue, pCodes, unLen, m_pFont, isPlaceHolder ? oPlaceHolderColor : oNormalColor, 1.0, m_oFont.GetSize(), dShiftX, dBaseLine, ppFonts, pShifts); - RELEASEARRAYOBJECTS(pShifts); - } - - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); - - pField->SetDefaultAppearance(pFontTT, m_oFont.GetSize(), TRgb(oColor.r, oColor.g, oColor.b)); - - std::wstring wsPlaceHolder = pPr->GetPlaceHolder(); - if (!wsPlaceHolder.empty()) - { - unsigned int unMaxLen = pPr->GetMaxCharacters(); - if (unMaxLen && wsPlaceHolder.length() > unMaxLen) - wsPlaceHolder = wsPlaceHolder.substr(0, unMaxLen); - - pField->SetPlaceHolderText(wsPlaceHolder, oNormalColor, oPlaceHolderColor); - } - - pField->SetFormat(pPr->GetFormatPr()); - } - else if (oInfo.IsDropDownList()) - { - const CFormFieldInfo::CDropDownFormPr* pPr = oInfo.GetDropDownPr(); - std::wstring wsValue = pPr->GetTextValue(); - - unsigned int unLen; - unsigned int* pUnicodes = WStringToUtf32(wsValue, unLen); - if (!pUnicodes) - return S_FALSE; - - unsigned short* pCodes = new unsigned short[unLen]; - if (!pCodes) - { - RELEASEARRAYOBJECTS(pUnicodes); - return S_FALSE; - } - - CFontCidTrueType** ppFonts = new CFontCidTrueType*[unLen]; - if (!ppFonts) - { - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - return S_FALSE; - } - - for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) - { - unsigned int unUnicode = pUnicodes[unIndex]; - - if (!m_pFont->HaveChar(unUnicode)) - { - std::wstring wsFontFamily = m_pAppFonts->GetFontBySymbol(unUnicode); - CFontCidTrueType* pTempFont = GetFont(wsFontFamily, isBold, isItalic); - if (pTempFont) - { - pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = pTempFont; - continue; - } - } - pCodes[unIndex] = m_pFont->EncodeUnicode(unUnicode); - ppFonts[unIndex] = m_pFont; - } - - CChoiceField* pField = dynamic_cast(pFieldBase); - if (!pField) - { - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); - return S_FALSE; - } - - pFieldBase->AddPageRect(m_pPage, TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - - TColor oColor = m_oBrush.GetTColor1(); - - TRgb oNormalColor(oColor.r, oColor.g, oColor.b); - TRgb oPlaceHolderColor; - oPlaceHolderColor.r = oNormalColor.r + (1.0 - oNormalColor.r) / 2.0; - oPlaceHolderColor.g = oNormalColor.g + (1.0 - oNormalColor.g) / 2.0; - oPlaceHolderColor.b = oNormalColor.b + (1.0 - oNormalColor.b) / 2.0; - - pField->SetTextValue(wsValue); - pField->SetTextAppearance(wsValue, pCodes, unLen, m_pFont, oInfo.IsPlaceHolder() ? oPlaceHolderColor : oNormalColor, 1, m_oFont.GetSize(), 0, MM_2_PT(dH - oInfo.GetBaseLineOffset()), ppFonts); - - RELEASEARRAYOBJECTS(pUnicodes); - RELEASEARRAYOBJECTS(pCodes); - RELEASEARRAYOBJECTS(ppFonts); - - unsigned int unSelectedIndex = 0xFFFF; - for (unsigned int unIndex = 0, unItemsCount = pPr->GetComboBoxItemsCount(); unIndex < unItemsCount; ++unIndex) - { - std::wstring wsItem = pPr->GetComboBoxItem(unIndex); - pField->AddOption(wsItem); - if (wsItem == wsValue) - unSelectedIndex = unIndex; - } - - pField->SetComboFlag(true); - pField->SetEditFlag(pPr->IsEditComboBox()); - - pField->SetDefaultAppearance(pFontTT, m_oFont.GetSize(), oInfo.IsPlaceHolder() ? oPlaceHolderColor : oNormalColor); - - if (!pPr->GetPlaceHolder().empty()) - { - pField->SetPlaceHolderText(pPr->GetPlaceHolder(), oNormalColor, oPlaceHolderColor); - - if (!pPr->IsEditComboBox()) - { - // Для drop-down list в 0 позиции мы добавили плейсхолдер - if (oInfo.IsPlaceHolder()) - unSelectedIndex = 0; - else if (0xFFFF != unSelectedIndex) - unSelectedIndex++; - } - } - - if (!pPr->IsEditComboBox() && 0xFFFF != unSelectedIndex) - pField->SetSelectedIndex(unSelectedIndex); - } - else if (oInfo.IsCheckBox()) - { - const CFormFieldInfo::CCheckBoxFormPr* pPr = oInfo.GetCheckBoxPr(); - - CCheckBoxField* pField = dynamic_cast(pFieldBase); - if (!pField) - return S_FALSE; - - pFieldBase->AddPageRect(m_pPage, TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - pField->SetValue(pPr->IsChecked()); - - CFontCidTrueType* pCheckedFont = GetFont(pPr->GetCheckedFontName(), false, false); - CFontCidTrueType* pUncheckedFont = GetFont(pPr->GetUncheckedFontName(), false, false); - if (!pCheckedFont) - pCheckedFont = m_pFont; - - if (!pUncheckedFont) - pUncheckedFont = m_pFont; - - unsigned int unCheckedSymbol = pPr->GetCheckedSymbol(); - unsigned int unUncheckedSymbol = pPr->GetUncheckedSymbol(); - - unsigned short ushCheckedCode = pCheckedFont->EncodeUnicode(unCheckedSymbol); - unsigned short ushUncheckedCode = pUncheckedFont->EncodeUnicode(unUncheckedSymbol); - - TColor oColor = m_oBrush.GetTColor1(); - pField->SetAppearance(L"", &ushCheckedCode, 1, pCheckedFont, L"", &ushUncheckedCode, 1, pUncheckedFont, TRgb(oColor.r, oColor.g, oColor.b), 1, m_oFont.GetSize(), 0, MM_2_PT(dH - oInfo.GetBaseLineOffset())); - } - else if (oInfo.IsPicture()) - { - const CFormFieldInfo::CPictureFormPr* pPr = oInfo.GetPicturePr(); - - CPictureField* pField = dynamic_cast(pFieldBase); - pFieldBase->AddPageRect(m_pPage, TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - pField->SetConstantProportions(pPr->IsConstantProportions()); - pField->SetRespectBorders(pPr->IsRespectBorders()); - pField->SetScaleType(static_cast(pPr->GetScaleType())); - pField->SetShift(pPr->GetShiftX() / 1000.0, (1000 - pPr->GetShiftY()) / 1000.0); - - std::wstring wsPath = pPr->GetPicturePath(); - CImageDict* pImage = NULL; - if (wsPath.length()) - { - Aggplus::CImage oImage(wsPath); - pImage = LoadImage(&oImage, 255); - } - - pField->SetAppearance(pImage); - } - else if (oInfo.IsSignature()) - { - const CFormFieldInfo::CSignatureFormPr* pPr = oInfo.GetSignaturePr(); - - CSignatureField* pField = dynamic_cast(pFieldBase); - if (!pField) - return S_FALSE; - - pFieldBase->AddPageRect(m_pPage, TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH))); - pField->SetName(pPr->GetName()); - pField->SetReason(pPr->GetReason()); - pField->SetContact(pPr->GetContact()); - pField->SetDate(pPr->GetDate()); - - std::wstring wsPath = pPr->GetPicturePath(); - CImageDict* pImage = NULL; - if (!wsPath.empty()) - { - Aggplus::CImage oImage(wsPath); - pImage = LoadImage(&oImage, 255); - } - - pField->SetAppearance(pImage); - - // TODO Реализовать, когда появится поддержка CSignatureField - pField->SetCert(); - } - - - // Выставляем имя в конце, потому что там возможно копирование настроек поля в новое родительское поле, поэтому к текущему моменту - // все настройки должны быть выставлены - if (!bRadioButton) - { - std::wstring wsKey = oInfo.GetKey(); - if (L"" != wsKey) - pFieldBase->SetFieldName(wsKey); - else - pFieldBase->SetFieldName(m_oFieldsManager.GetNewFieldName()); - } - - return S_OK; -} -//---------------------------------------------------------------------------------------- -// Дополнительные функции Pdf рендерера -//---------------------------------------------------------------------------------------- -HRESULT CPdfRenderer::CommandDrawTextPdf(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int unGidsCount, const std::wstring& bsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CPdfRenderer::PathCommandTextPdf(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int unGidsCount, const std::wstring& bsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH) -{ - return S_OK; -} -HRESULT CPdfRenderer::DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH) -{ - m_oCommandManager.Flush(); - - if (!IsPageValid() || !pImageBuffer) - return S_OK; - - m_pPage->GrSave(); - UpdateTransform(); - - CImageDict* pPdfImage = m_pDocument->CreateImage(); - pPdfImage->LoadBW(pImageBuffer, unWidth, unHeight); - m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); - - m_pPage->GrRestore(); - return S_OK; -} -HRESULT CPdfRenderer::EnableBrushRect(const LONG& lEnable) -{ - m_oBrush.EnableBrushRect(LONG_2_BOOL(lEnable)); - return S_OK; -} -HRESULT CPdfRenderer::SetLinearGradient(const double& dX0, const double& dY0, const double& dX1, const double& dY1) -{ - m_oBrush.SetType(c_BrushTypeLinearGradient); - m_oBrush.SetLinearGradientPattern(dX0, dY0, dX1, dY1); - return S_OK; -} -HRESULT CPdfRenderer::SetRadialGradient(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1) -{ - m_oBrush.SetType(c_BrushTypeRadialGradient); - m_oBrush.SetRadialGradientPattern(dX0, dY0, dR0, dX1, dY1, dR1); - return S_OK; -} -HRESULT CPdfRenderer::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH) -{ - m_oCommandManager.Flush(); - - if (!IsPageValid() || !pMaskBuffer || !pImage) - return S_OK; - - m_pPage->GrSave(); - UpdateTransform(); - CImageDict* pPdfImage = LoadImage((Aggplus::CImage*)pImage, 255); - pPdfImage->LoadMask(pMaskBuffer, unMaskWidth, unMaskHeight); - m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); - m_pPage->GrRestore(); - return S_OK; -} -void CPdfRenderer::EditPdf() -{ - m_bEdit = true; -} -std::pair CPdfRenderer::GetPageRef(int nPageIndex) -{ - return m_pDocument->GetPageRef(nPageIndex); -} -bool CPdfRenderer::EditPage(PdfWriter::CPage* pNewPage) -{ - if (!IsValid() || !m_bEdit) - return false; - m_oCommandManager.Flush(); - - m_pPage = pNewPage; - if (m_pPage) - { - m_dPageWidth = PT_2_MM(m_pPage->GetWidth()); - m_dPageHeight = PT_2_MM(m_pPage->GetHeight()); - Reset(); - m_bEditPage = true; - return true; - } - return false; -} -bool CPdfRenderer::AddPage(int nPageIndex) -{ - if (!IsValid() || !m_bEdit) - return false; - m_oCommandManager.Flush(); - - m_pPage = m_pDocument->AddPage(nPageIndex); - if (m_pPage) - { - m_pPage->SetWidth(MM_2_PT(m_dPageWidth)); - m_pPage->SetHeight(MM_2_PT(m_dPageHeight)); - Reset(); - m_bEditPage = false; - return true; - } - return false; -} -bool CPdfRenderer::DeletePage(int nPageIndex) -{ - if (!m_bEdit) - { - return false; - } - return m_pDocument->DeletePage(nPageIndex); -} -bool CPdfRenderer::EditClose() -{ - if (!IsValid() || !m_bEdit) - return false; - m_oCommandManager.Flush(); - - unsigned int nPagesCount = m_pDocument->GetPagesCount(); - for (int nIndex = 0, nCount = m_vDestinations.size(); nIndex < nCount; ++nIndex) - { - TDestinationInfo& oInfo = m_vDestinations.at(nIndex); - if (nPagesCount > oInfo.unDestPage) - { - AddLink(oInfo.pPage, oInfo.dX, oInfo.dY, oInfo.dW, oInfo.dH, oInfo.dDestX, oInfo.dDestY, oInfo.unDestPage); - m_vDestinations.erase(m_vDestinations.begin() + nIndex); - nIndex--; - nCount--; - } - } - - m_bEdit = false; - m_bEditPage = false; - - return true; -} -void CPdfRenderer::PageRotate(int nRotate) -{ - if (m_pPage && m_bEdit) - m_pPage->SetRotate(nRotate); -} -void CPdfRenderer::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate) -{ - if (!m_bEdit) - { - return; - } - CImageDict* pImage = NULL; - if (!wsPicturePath.empty()) - { - Aggplus::CImage oImage(wsPicturePath); - pImage = LoadImage(&oImage, 255); - } - - m_pDocument->Sign(TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)), - pImage, pCertificate); -} -std::wstring CPdfRenderer::GetEditPdfPath() -{ - if (!m_bEdit) - { - return L""; - } - return m_pDocument->GetEditPdfPath(); -} - -NSFonts::IApplicationFonts* CPdfRenderer::GetApplicationFonts() -{ - return m_pAppFonts; -} -//---------------------------------------------------------------------------------------- -// Внутренние функции -//---------------------------------------------------------------------------------------- -PdfWriter::CImageDict* CPdfRenderer::LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha) -{ - int nImageW = abs((int)pImage->GetWidth()); - int nImageH = abs((int)pImage->GetHeight()); - BYTE* pData = pImage->GetData(); - int nStride = 4 * nImageW; - - // Картинки совсем маленьких размеров нельзя делать Jpeg2000 - bool bJpeg = false; - if (nImageH < 100 || nImageW < 100 || m_pDocument->IsPDFA()) - bJpeg = true; - - if (nImageH <= 0 || nImageW <= 0) - return NULL; - - // TODO: Пока не разберемся как в CxImage управлять параметрами кодирования нельзя писать в Jpeg2000, - // т.к. файлы получаются гораздо больше и конвертация идет намного дольше. - bJpeg = true; - - // Пробегаемся по картинке и определяем есть ли у нас альфа-канал - bool bAlpha = false; - - CBgraFrame oFrame; - if (m_pDocument->IsPDFA()) - { - BYTE* pCopyImage = new BYTE[4 * nImageW * nImageH]; - if (!pCopyImage) - return NULL; - - ::memcpy(pCopyImage, pData, 4 * nImageW * nImageH); - - BYTE* pDataMem = pCopyImage; - for (int nIndex = 0, nSize = nImageW * nImageH; nIndex < nSize; nIndex++) - { - if (pDataMem[3] < 32) - { - pDataMem[0] = 255; - pDataMem[1] = 255; - pDataMem[2] = 255; - } - pDataMem += 4; - } - - oFrame.put_Width(nImageW); - oFrame.put_Height(nImageH); - oFrame.put_Data(pCopyImage);// +4 * (nImageH - 1) * nImageW); - oFrame.put_Stride(-4* nImageW); - } - else - { - BYTE* pDataMem = pData; - for (int nIndex = 0, nSize = nImageW * nImageH; nIndex < nSize; nIndex++) - { - // making full-transparent pixels white - if (pDataMem[3] == 0) - { - pDataMem[0] = 255; - pDataMem[1] = 255; - pDataMem[2] = 255; - } - - if (!bAlpha && (pDataMem[3] < 255)) - { - bAlpha = true; - } - - pDataMem += 4; - } - oFrame.FromImage(pImage); - } - - oFrame.SetJpegQuality(85.0); - - BYTE* pBuffer = NULL; - int nBufferSize = 0; - if (!oFrame.Encode(pBuffer, nBufferSize, bJpeg ? _CXIMAGE_FORMAT_JPG : _CXIMAGE_FORMAT_JP2)) - return NULL; - - if (!pBuffer || !nBufferSize) - return NULL; - - CImageDict* pPdfImage = m_pDocument->CreateImage(); - if (bAlpha || nAlpha < 255) - pPdfImage->LoadSMask(pData, nImageW, nImageH, nAlpha, (pImage->GetStride() >= 0) ? false : true); - - if (bJpeg) - pPdfImage->LoadJpeg(pBuffer, nBufferSize, nImageW, nImageH); - else - pPdfImage->LoadJpx(pBuffer, nBufferSize, nImageW, nImageH); - - free(pBuffer); - - return pPdfImage; -} -bool CPdfRenderer::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha) -{ - CImageDict* pPdfImage = LoadImage(pImage, nAlpha); - if (!pPdfImage) - return false; - - m_pPage->GrSave(); - UpdateTransform(); - m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH)); - m_pPage->GrRestore(); - - return true; -} -bool CPdfRenderer::DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY) -{ - if (!pCodes || !unLen) - return false; - - CTransform& t = m_oTransform; - m_oCommandManager.SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); - - CRendererTextCommand* pText = m_oCommandManager.AddText(pCodes, unLen, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY)); - pText->SetFont(m_pFont); - pText->SetSize(m_oFont.GetSize()); - pText->SetColor(m_oBrush.GetColor1()); - pText->SetAlpha((BYTE)m_oBrush.GetAlpha1()); - pText->SetCharSpace(MM_2_PT(m_oFont.GetCharSpace())); - pText->SetNeedDoBold(m_oFont.IsNeedDoBold()); - pText->SetNeedDoItalic(m_oFont.IsNeedDoItalic()); - - return true; -} -bool CPdfRenderer::PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids) -{ - unsigned char* pCodes = EncodeString(pUnicodes, unLen, pGids); - if (!pCodes) - return false; - - m_oPath.AddText(m_pFont, pCodes, unLen * 2, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), m_oFont.GetSize(), MM_2_PT(m_oFont.GetCharSpace())); - return true; -} -void CPdfRenderer::UpdateFont() -{ - m_bNeedUpdateTextFont = false; - std::wstring wsFontPath = m_oFont.GetPath(); - LONG lFaceIndex = m_oFont.GetFaceIndex(); - if (L"" == wsFontPath) - GetFontPath(m_oFont.GetName(), m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex); - - m_oFont.SetNeedDoBold(false); - m_oFont.SetNeedDoItalic(false); - - m_pFont = NULL; - if (L"" != wsFontPath) - { - m_pFont = GetFont(wsFontPath, lFaceIndex); - if (m_pFont) - { - if (m_oFont.IsItalic() && !m_pFont->IsItalic()) - m_oFont.SetNeedDoItalic(true); - - if (m_oFont.IsBold() && !m_pFont->IsBold()) - m_oFont.SetNeedDoBold(true); - } - } -} -void CPdfRenderer::GetFontPath(const std::wstring &wsFontName, const bool &bBold, const bool &bItalic, std::wstring& wsFontPath, LONG& lFaceIndex) -{ - bool bFind = false; - for (int nIndex = 0, nCount = m_vFonts.size(); nIndex < nCount; nIndex++) - { - TFontInfo& oInfo = m_vFonts.at(nIndex); - if (oInfo.wsFontName == wsFontName && oInfo.bBold == bBold && oInfo.bItalic == bItalic) - { - wsFontPath = oInfo.wsFontPath; - lFaceIndex = oInfo.lFaceIndex; - bFind = true; - break; - } - } - - if (!bFind) - { - NSFonts::CFontSelectFormat oFontSelect; - oFontSelect.wsName = new std::wstring(wsFontName); - oFontSelect.bItalic = new INT(bItalic ? 1 : 0); - oFontSelect.bBold = new INT(bBold ? 1 : 0); - NSFonts::CFontInfo* pFontInfo = m_pFontManager->GetFontInfoByParams(oFontSelect, false); - if (!NSFonts::CFontInfo::CanEmbedForPreviewAndPrint(pFontInfo->m_usType)) - { - oFontSelect.Fill(pFontInfo); - if (NULL != oFontSelect.usType) - *oFontSelect.usType = NSFONTS_EMBEDDING_RIGHTS_PRINT_AND_PREVIEW; - else - oFontSelect.usType = new USHORT(NSFONTS_EMBEDDING_RIGHTS_PRINT_AND_PREVIEW); - - pFontInfo = m_pFontManager->GetFontInfoByParams(oFontSelect, false); - } - - wsFontPath = pFontInfo->m_wsFontPath; - lFaceIndex = pFontInfo->m_lIndex; - - m_vFonts.push_back(TFontInfo(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex)); - } -} -PdfWriter::CFontCidTrueType* CPdfRenderer::GetFont(const std::wstring& wsFontPath, const LONG& lFaceIndex) -{ - PdfWriter::CFontCidTrueType* pFont = NULL; - if (L"" != wsFontPath) - { - pFont = m_pDocument->FindCidTrueTypeFont(wsFontPath, lFaceIndex); - if (pFont) - return pFont; - - // TODO: Пока мы здесь предполагаем, что шрифты только либо TrueType, либо OpenType - if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, 10, 72, 72)) - { - std::wcout << L"PDF Writer: Can't load fontfile " << wsFontPath.c_str() << "\n"; - return NULL; - } - - std::wstring wsFontType = m_pFontManager->GetFontType(); - if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType) - pFont = m_pDocument->CreateCidTrueTypeFont(wsFontPath, lFaceIndex); - } - - return pFont; -} -PdfWriter::CFontCidTrueType* CPdfRenderer::GetFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic) -{ - std::wstring wsFontPath; - LONG lFaceIndex; - - GetFontPath(wsFontName, bBold, bItalic, wsFontPath, lFaceIndex); - return GetFont(wsFontPath, lFaceIndex); -} -void CPdfRenderer::UpdateTransform() -{ - CTransform& t = m_oTransform; - m_pPage->SetTransform(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy)); -} -void CPdfRenderer::UpdatePen() -{ - TColor oColor = m_oPen.GetTColor(); - m_pPage->SetStrokeColor(oColor.r, oColor.g, oColor.b); - m_pPage->SetStrokeAlpha((unsigned char)m_oPen.GetAlpha()); - m_pPage->SetLineWidth(MM_2_PT(m_oPen.GetSize())); - - LONG lDashCount = 0; - double* pDashPattern = NULL; - - LONG lDashStyle = m_oPen.GetDashStyle(); - if (Aggplus::DashStyleSolid == lDashStyle) - { - // Ничего не делаем - } - else if (Aggplus::DashStyleCustom == lDashStyle) - { - double *pDashPatternMM = m_oPen.GetDashPattern(lDashCount); - if (pDashPatternMM && lDashCount) - { - pDashPattern = new double[lDashCount]; - if (pDashPattern) - { - for (LONG lIndex = 0; lIndex < lDashCount; lIndex++) - { - pDashPattern[lIndex] = MM_2_PT(pDashPatternMM[lIndex]); - } - } - } - } - else - { - // TODO: Реализовать другие типы пунктирных линий - } - - if (pDashPattern && lDashCount) - { - m_pPage->SetDash(pDashPattern, lDashCount, MM_2_PT(m_oPen.GetDashOffset())); - delete[] pDashPattern; - } - - LONG lCapStyle = m_oPen.GetStartCapStyle(); - if (Aggplus::LineCapRound == lCapStyle) - m_pPage->SetLineCap(linecap_Round); - else if (Aggplus::LineCapSquare == lCapStyle) - m_pPage->SetLineCap(linecap_ProjectingSquare); - else - m_pPage->SetLineCap(linecap_Butt); - - LONG lJoinStyle = m_oPen.GetJoinStyle(); - if (Aggplus::LineJoinBevel == lJoinStyle) - m_pPage->SetLineJoin(linejoin_Bevel); - else if (Aggplus::LineJoinMiter == lJoinStyle) - { - m_pPage->SetLineJoin(linejoin_Miter); - m_pPage->SetMiterLimit(MM_2_PT(m_oPen.GetMiter())); - } - else - m_pPage->SetLineJoin(linejoin_Round); -} -void CPdfRenderer::UpdateBrush() -{ - m_pShading = NULL; - m_pShadingExtGrState = NULL; - - LONG lBrushType = m_oBrush.GetType(); - if (c_BrushTypeTexture == lBrushType) - { - std::wstring wsTexturePath = m_oBrush.GetTexturePath(); - CImageFileFormatChecker oImageFormat(wsTexturePath); - - CImageDict* pImage = NULL; - int nImageW = 0; - int nImageH = 0; - if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) - { - pImage = m_pDocument->CreateImage(); - CBgraFrame oFrame; - oFrame.OpenFile(wsTexturePath); - nImageH = oFrame.get_Height(); - nImageW = oFrame.get_Width(); - - if (pImage) - { - if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType) - pImage->LoadJpeg(wsTexturePath.c_str(), nImageW, nImageH, oFrame.IsGrayScale()); - else - pImage->LoadJpx(wsTexturePath.c_str(), nImageW, nImageH); - } - } - else if (_CXIMAGE_FORMAT_WMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_EMF == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVM == oImageFormat.eFileType || - _CXIMAGE_FORMAT_SVG == oImageFormat.eFileType) - { - // TODO: Реализовать отрисовку метафайлов по-нормальному - MetaFile::IMetaFile* pMeta = MetaFile::Create(m_pAppFonts); - pMeta->LoadFromFile(wsTexturePath.c_str()); - - double dL, dR, dT, dB; - m_oPath.GetBounds(dL, dT, dR, dB); - - double dNewW = std::max(10.0, dR - dL) / 72 * 300; - - std::wstring wsTempFile = GetTempFile(); - pMeta->ConvertToRaster(wsTempFile.c_str(), _CXIMAGE_FORMAT_PNG, dNewW); - - RELEASEOBJECT(pMeta); - - Aggplus::CImage oImage(wsTempFile); - nImageW = abs((int)oImage.GetWidth()); - nImageH = abs((int)oImage.GetHeight()); - pImage = LoadImage(&oImage, 255); - } - else - { - Aggplus::CImage oImage(wsTexturePath); - nImageW = abs((int)oImage.GetWidth()); - nImageH = abs((int)oImage.GetHeight()); - pImage = LoadImage(&oImage, 255); - } - - if (pImage) - { - BYTE nAlpha = m_oBrush.GetTextureAlpha(); - if (0xFF != nAlpha) - pImage->AddTransparency(nAlpha); - - LONG lTextureMode = m_oBrush.GetTextureMode(); - - double dW = 10; - double dH = 10; - - double dL, dR, dT, dB; - CBrushState::TBrushRect& oRect = m_oBrush.GetBrushRect(); - if (!oRect.bUse) - { - m_oPath.GetBounds(dL, dT, dR, dB); - } - else - { - dL = MM_2_PT(oRect.dLeft); - dB = MM_2_PT(m_dPageHeight - oRect.dTop); - dR = MM_2_PT(oRect.dLeft + oRect.dWidth); - dT = MM_2_PT(m_dPageHeight - oRect.dTop - oRect.dHeight); - } - - double dXStepSpacing = 0, dYStepSpacing = 0; - if (c_BrushTextureModeStretch == lTextureMode) - { - // Растягиваем картинку по размерам пата - dW = std::max(10.0, dR - dL); - dH = std::max(10.0, dB - dT); - - // Чтобы избавиться от погрешностей из-за которых могут возникать полоски или обрезание картинки, - // удвоим расстрояние между соседними тайлами. Плохого тут нет, т.к. нам нужен всего 1 тайл - dXStepSpacing = dW; - dYStepSpacing = dH; - } - else - { - // Размеры картинки заданы в пикселях. Размеры тайла - это размеры картинки в пунктах. - dW = nImageW * 72 / 96; - dH = nImageH * 72 / 96; - } - - // Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования. - CMatrix* pMatrix = m_pPage->GetTransform(); - pMatrix->Apply(dL, dT); - CMatrix oPatternMatrix = *pMatrix; - oPatternMatrix.x = dL; - oPatternMatrix.y = dT; - m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage, &oPatternMatrix, imagetilepatterntype_Default, dXStepSpacing, dYStepSpacing)); - } - } - else if (c_BrushTypeHatch1 == lBrushType) - { - std::wstring wsHatchType = m_oBrush.GetTexturePath(); - - double dW = 8 * 72 / 96; - double dH = 8 * 72 / 96; - - TColor oColor1 = m_oBrush.GetTColor1(); - TColor oColor2 = m_oBrush.GetTColor2(); - BYTE nAlpha1 = (BYTE)m_oBrush.GetAlpha1(); - BYTE nAlpha2 = (BYTE)m_oBrush.GetAlpha2(); - - m_pPage->SetPatternColorSpace(m_pDocument->CreateHatchPattern(dW, dH, oColor1.r, oColor1.g, oColor1.b, nAlpha1, oColor2.r, oColor2.g, oColor2.b, nAlpha2, wsHatchType)); - } - else if (c_BrushTypeRadialGradient == lBrushType || c_BrushTypeLinearGradient == lBrushType) - { - TColor* pGradientColors; - double* pPoints; - LONG lCount; - - m_oBrush.GetGradientColors(pGradientColors, pPoints, lCount); - - if (lCount > 0) - { - unsigned char* pColors = new unsigned char[3 * lCount]; - unsigned char* pAlphas = new unsigned char[lCount]; - if (pColors) - { - for (LONG lIndex = 0; lIndex < lCount; lIndex++) - { - pColors[3 * lIndex + 0] = pGradientColors[lIndex].r; - pColors[3 * lIndex + 1] = pGradientColors[lIndex].g; - pColors[3 * lIndex + 2] = pGradientColors[lIndex].b; - pAlphas[lIndex] = pGradientColors[lIndex].a; - } - - if (c_BrushTypeLinearGradient == lBrushType) - { - double dX0, dY0, dX1, dY1; - m_oBrush.GetLinearGradientPattern(dX0, dY0, dX1, dY1); - m_pShading = m_pDocument->CreateAxialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState); - } - else //if (c_BrushTypeRadialGradient == lBrushType) - { - double dX0, dY0, dR0, dX1, dY1, dR1; - m_oBrush.GetRadialGradientPattern(dX0, dY0, dR0, dX1, dY1, dR1); - m_pShading = m_pDocument->CreateRadialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dR0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dR1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState); - } - delete[] pColors; - delete[] pAlphas; - } - } - } - else// if (c_BrushTypeSolid == lBrushType) - { - TColor oColor1 = m_oBrush.GetTColor1(); - m_pPage->SetFillColor(oColor1.r, oColor1.g, oColor1.b); - m_pPage->SetFillAlpha((unsigned char)m_oBrush.GetAlpha1()); - } -} -void CPdfRenderer::Reset() -{ - m_oPen.Reset(); - m_oBrush.Reset(); - m_oFont.Reset(); - m_oPath.Clear(); - - // clear font!!! - m_oFont.SetName(L""); - m_oFont.SetSize(-1); - m_oFont.SetStyle(1 << 5); - - m_lClipDepth = 0; -} -/* -HRESULT CPdfRenderer::OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams) -{ - if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, false, pParams)) - return S_FALSE; - - return S_OK; -} -HRESULT CPdfRenderer::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams) -{ - if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, true, pParams)) - return S_FALSE; - - return S_OK; -} -*/ - -static inline void UpdateMaxMinPoints(double& dMinX, double& dMinY, double& dMaxX, double& dMaxY, const double& dX, const double& dY) -{ - if (dX < dMinX) - dMinX = dX; - - if (dX > dMaxX) - dMaxX = dX; - - if (dY < dMinY) - dMinY = dY; - - if (dY > dMaxY) - dMaxY = dY; -} -void CPdfRenderer::CPath::Draw(PdfWriter::CPage* pPage, bool bStroke, bool bFill, bool bEoFill) -{ - for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++) - { - CPathCommandBase* pCommand = m_vCommands.at(nIndex); - pCommand->Draw(pPage); - } - - if (bStroke && !bFill && !bEoFill) - pPage->Stroke(); - else if (bStroke && bFill) - pPage->FillStroke(); - else if (bStroke && bEoFill) - pPage->EoFillStroke(); - else if (bFill) - pPage->Fill(); - else if (bEoFill) - pPage->EoFill(); - else - pPage->EndPath(); -} -void CPdfRenderer::CPath::Clip(PdfWriter::CPage* pPage, bool bEvenOdd) -{ - for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++) - { - CPathCommandBase* pCommand = m_vCommands.at(nIndex); - pCommand->Draw(pPage); - } - - if (bEvenOdd) - pPage->Eoclip(); - else - pPage->Clip(); - - pPage->EndPath(); -} -void CPdfRenderer::CPath::GetLastPoint(double& dX, double& dY) -{ - dX = 0; - dY = 0; - - bool bFindMoveTo = false; - for (int nIndex = m_vCommands.size() - 1; nIndex >= 0; nIndex--) - { - CPathCommandBase* pCommand = m_vCommands.at(nIndex); - if (rendererpathcommand_Close == pCommand->GetType()) - { - bFindMoveTo = true; - continue; - } - else - { - pCommand->GetLastPoint(dX, dY); - if (!bFindMoveTo || rendererpathcommand_MoveTo == pCommand->GetType()) - break; - } - } -} -void CPdfRenderer::CPath::GetBounds(double& dL, double& dT, double& dR, double& dB) -{ - GetLastPoint(dL, dT); - dR = dL; - dB = dT; - - for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++) - { - CPathCommandBase* pCommand = m_vCommands.at(nIndex); - pCommand->UpdateBounds(dL, dT, dR, dB); - } -} -void CPdfRenderer::CPath::CPathMoveTo::Draw(PdfWriter::CPage* pPage) -{ - pPage->MoveTo(x, y); -} -void CPdfRenderer::CPath::CPathMoveTo::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ - UpdateMaxMinPoints(dL, dT, dR, dB, x, y); -} -void CPdfRenderer::CPath::CPathLineTo::Draw(PdfWriter::CPage* pPage) -{ - pPage->LineTo(x, y); -} -void CPdfRenderer::CPath::CPathLineTo::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ - UpdateMaxMinPoints(dL, dT, dR, dB, x, y); -} -void CPdfRenderer::CPath::CPathCurveTo::Draw(PdfWriter::CPage* pPage) -{ - pPage->CurveTo(x1, y1, x2, y2, xe, ye); -} -void CPdfRenderer::CPath::CPathCurveTo::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ - UpdateMaxMinPoints(dL, dT, dR, dB, x1, y1); - UpdateMaxMinPoints(dL, dT, dR, dB, x2, y2); - UpdateMaxMinPoints(dL, dT, dR, dB, xe, ye); -} -void CPdfRenderer::CPath::CPathArcTo::Draw(PdfWriter::CPage* pPage) -{ - if (sweepAngle >= 360 - 0.001) - pPage->Ellipse(x + w / 2, y + h / 2, w / 2, h / 2); - else - pPage->EllipseArcTo(x + w / 2, y + h / 2, w / 2, h / 2, 360 - startAngle, 360 - (startAngle + sweepAngle), sweepAngle > 0 ? true : false); -} -void CPdfRenderer::CPath::CPathArcTo::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ - UpdateMaxMinPoints(dL, dT, dR, dB, x, y); - UpdateMaxMinPoints(dL, dT, dR, dB, x + w, y + h); -} -void CPdfRenderer::CPath::CPathClose::Draw(PdfWriter::CPage* pPage) -{ - pPage->ClosePath(); -} -void CPdfRenderer::CPath::CPathClose::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ -} -void CPdfRenderer::CPath::CPathText::Draw(PdfWriter::CPage* pPage) -{ - // TODO: Если данная команда будет часто вызываться, тогда ее нужно будет оптимизировать, точно также как это делается в обычном тексте - pPage->BeginText(); - pPage->SetFontAndSize(font, fontSize); - pPage->SetCharSpace(charSpace); - pPage->SetTextRenderingMode(textrenderingmode_Stroke); - pPage->DrawText(x, y, codes, codesCount); - pPage->EndText(); -} -void CPdfRenderer::CPath::CPathText::UpdateBounds(double& dL, double& dT, double& dR, double& dB) -{ - UpdateMaxMinPoints(dL, dT, dR, dB, x, y); -} -void CPdfRenderer::CBrushState::Reset() -{ - m_lType = c_BrushTypeSolid; - m_oColor1.Set(0); - m_oColor2.Set(0); - m_nAlpha1 = 255; - m_nAlpha2 = 255; - m_wsTexturePath = L""; - m_lTextureMode = c_BrushTextureModeStretch; - m_nTextureAlpha = 255; - m_dLinearAngle = 0; - m_oRect.Reset(); - - if (m_pShadingColors) - delete[] m_pShadingColors; - - if (m_pShadingPoints) - delete[] m_pShadingPoints; - - m_pShadingColors = NULL; - m_pShadingPoints = NULL; - m_lShadingPointsCount = 0; -} -void CPdfRenderer::AddLink(PdfWriter::CPage* pPage, const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const unsigned int& unDestPage) -{ - CPage* pCurPage = pPage; - CPage* pDestPage = m_pDocument->GetPage(unDestPage); - if (!pCurPage || !pDestPage) - return; - - CDestination* pDestination = m_pDocument->CreateDestination(unDestPage); - if (!pDestination) - return; - - pDestination->SetXYZ(MM_2_PT(dDestX), pDestPage->GetHeight() - MM_2_PT(dDestY), 0); - CAnnotation* pAnnot = m_pDocument->CreateLinkAnnot(pCurPage, TRect(MM_2_PT(dX), pCurPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)), pDestination); - pAnnot->SetBorderStyle(EBorderSubtype::border_subtype_Solid, 0); -} -bool CPdfRenderer::IsValid() -{ - return m_bValid; -} -bool CPdfRenderer::IsPageValid() -{ - if (!IsValid() || !m_pPage) - return false; - - return true; -} -void CPdfRenderer::SetError() -{ - m_bValid = false; -} -unsigned char* CPdfRenderer::EncodeString(const unsigned int *pUnicodes, const unsigned int& unCount, const unsigned int *pGIDs) -{ - if (m_bNeedUpdateTextFont) - UpdateFont(); - - if (!m_pFont) - return NULL; - - unsigned char* pCodes = new unsigned char[unCount * 2]; - if (!pCodes) - return NULL; - - for (unsigned int unIndex = 0; unIndex < unCount; unIndex++) - { - unsigned short ushCode; - if (pGIDs) - ushCode = m_pFont->EncodeGID(pGIDs[unIndex], &pUnicodes[unIndex], 1); - else - ushCode = m_pFont->EncodeUnicode(pUnicodes[unIndex]); - - pCodes[2 * unIndex + 0] = (ushCode >> 8) & 0xFF; - pCodes[2 * unIndex + 1] = ushCode & 0xFF; - } - - return pCodes; -} -unsigned char* CPdfRenderer::EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount) -{ - if (m_bNeedUpdateTextFont) - UpdateFont(); - - if (!m_pFont) - return NULL; - - unsigned char* pCodes = new unsigned char[2]; - if (!pCodes) - return NULL; - - unsigned short ushCode = m_pFont->EncodeGID(unGID, pUnicodes, unUnicodesCount); - pCodes[0] = (ushCode >> 8) & 0xFF; - pCodes[1] = ushCode & 0xFF; - return pCodes; -} -std::wstring CPdfRenderer::GetDownloadFile(const std::wstring& sUrl) -{ - std::wstring::size_type n1 = sUrl.find(L"www."); - std::wstring::size_type n2 = sUrl.find(L"http://"); - std::wstring::size_type n3 = sUrl.find(L"ftp://"); - std::wstring::size_type n4 = sUrl.find(L"https://"); - std::wstring::size_type nMax = 3; - - bool bIsNeedDownload = false; - if (n1 != std::wstring::npos && n1 < nMax) - bIsNeedDownload = true; - else if (n2 != std::wstring::npos && n2 < nMax) - bIsNeedDownload = true; - else if (n3 != std::wstring::npos && n3 < nMax) - bIsNeedDownload = true; - else if (n4 != std::wstring::npos && n4 < nMax) - bIsNeedDownload = true; - - if (!bIsNeedDownload) - return L""; - - std::wstring sTempFile = GetTempFile(); - NSNetwork::NSFileTransport::CFileDownloader oDownloader(sUrl, false); - oDownloader.SetFilePath(sTempFile); - - if (oDownloader.DownloadSync()) - return sTempFile; - - if (NSFile::CFileBinary::Exists(sTempFile)) - NSFile::CFileBinary::Remove(sTempFile); - - return L""; -} diff --git a/PdfWriter/PdfRenderer.h b/PdfWriter/PdfRenderer.h deleted file mode 100644 index 46fc241f42..0000000000 --- a/PdfWriter/PdfRenderer.h +++ /dev/null @@ -1,1890 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#ifndef _PDF_WRITER_PDFRENDERER_H -#define _PDF_WRITER_PDFRENDERER_H - -#include "../DesktopEditor/graphics/IRenderer.h" -#include "../DesktopEditor/graphics/pro/Fonts.h" -#include "../DesktopEditor/graphics/pro/Image.h" -#include -#include -#include -#include - -#ifndef PDFWRITER_USE_DYNAMIC_LIBRARY -#define PDFWRITER_DECL_EXPORT -#else -#include "../DesktopEditor/common/base_export.h" -#define PDFWRITER_DECL_EXPORT Q_DECL_EXPORT -#endif - -#include "../DesktopEditor/xmlsec/src/include/Certificate.h" - -namespace PdfWriter -{ - class CDocument; - class CPage; - class CFontCidTrueType; - class CFontTrueType; - class CImageDict; - class CShading; - class CExtGrState; - class CFontDict; -} - -namespace Aggplus -{ - class CImage; -} - -class CRendererCommandBase; -class CRendererTextCommand; - -class CConvertFromBinParams -{ -public: - std::wstring m_sMediaDirectory; - std::wstring m_sInternalMediaDirectory; - std::wstring m_sThemesDirectory; - bool m_bIsUsePicker; - -public: - CConvertFromBinParams() - { - m_bIsUsePicker = false; - } -}; - -class PDFWRITER_DECL_EXPORT CPdfRenderer : public IRenderer -{ -public: - CPdfRenderer(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false); - ~CPdfRenderer(); - int SaveToFile(const std::wstring& wsPath); - void SetPassword(const std::wstring& wsPassword); - void SetDocumentID(const std::wstring& wsDocumentID); - void SetTempFolder(const std::wstring& wsPath); - std::wstring GetTempDirectory(); - std::wstring GetTempFile(); - //---------------------------------------------------------------------------------------- - // Тип рендерера - //---------------------------------------------------------------------------------------- - virtual HRESULT get_Type(LONG* lType); - //---------------------------------------------------------------------------------------- - // Функции для работы со страницей - //---------------------------------------------------------------------------------------- - virtual HRESULT NewPage(); - virtual HRESULT get_Height(double* dHeight); - virtual HRESULT put_Height(const double& dHeight); - virtual HRESULT get_Width(double* dWidth); - virtual HRESULT put_Width(const double& dWidth); - virtual HRESULT get_DpiX(double* dDpiX); - virtual HRESULT get_DpiY(double* dDpiY); - //---------------------------------------------------------------------------------------- - // Функции для работы с Pen - //---------------------------------------------------------------------------------------- - virtual HRESULT get_PenColor(LONG* lColor); - virtual HRESULT put_PenColor(const LONG& lColor); - virtual HRESULT get_PenAlpha(LONG* lAlpha); - virtual HRESULT put_PenAlpha(const LONG& lAlpha); - virtual HRESULT get_PenSize(double* dSize); - virtual HRESULT put_PenSize(const double& dSize); - virtual HRESULT get_PenDashStyle(BYTE* nDashStyle); - virtual HRESULT put_PenDashStyle(const BYTE& nDashStyle); - virtual HRESULT get_PenLineStartCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineStartCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineEndCap(BYTE* nCapStyle); - virtual HRESULT put_PenLineEndCap(const BYTE& nCapStyle); - virtual HRESULT get_PenLineJoin(BYTE* nJoinStyle); - virtual HRESULT put_PenLineJoin(const BYTE& nJoinStyle); - virtual HRESULT get_PenDashOffset(double* dOffset); - virtual HRESULT put_PenDashOffset(const double& dOffset); - virtual HRESULT get_PenAlign(LONG* lAlign); - virtual HRESULT put_PenAlign(const LONG& lAlign); - virtual HRESULT get_PenMiterLimit(double* dMiter); - virtual HRESULT put_PenMiterLimit(const double& dMiter); - virtual HRESULT PenDashPattern(double* pPattern, LONG lCount); - //---------------------------------------------------------------------------------------- - // Функции для работы с Brush - //---------------------------------------------------------------------------------------- - virtual HRESULT get_BrushType(LONG* lType); - virtual HRESULT put_BrushType(const LONG& lType); - virtual HRESULT get_BrushColor1(LONG* lColor); - virtual HRESULT put_BrushColor1(const LONG& lColor); - virtual HRESULT get_BrushAlpha1(LONG* lAlpha); - virtual HRESULT put_BrushAlpha1(const LONG& lAlpha); - virtual HRESULT get_BrushColor2(LONG* lColor); - virtual HRESULT put_BrushColor2(const LONG& lColor); - virtual HRESULT get_BrushAlpha2(LONG* lAlpha); - virtual HRESULT put_BrushAlpha2(const LONG& lAlpha); - virtual HRESULT get_BrushTexturePath(std::wstring* wsPath); - virtual HRESULT put_BrushTexturePath(const std::wstring& wsPath); - virtual HRESULT get_BrushTextureMode(LONG* lMode); - virtual HRESULT put_BrushTextureMode(const LONG& lMode); - virtual HRESULT get_BrushTextureAlpha(LONG* lAlpha); - virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha); - virtual HRESULT get_BrushLinearAngle(double* dAngle); - virtual HRESULT put_BrushLinearAngle(const double& dAngle); - virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight); - virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount); - //---------------------------------------------------------------------------------------- - // Функции для работы со шрифтами - //---------------------------------------------------------------------------------------- - virtual HRESULT get_FontName(std::wstring* wsName); - virtual HRESULT put_FontName(const std::wstring& wsName); - virtual HRESULT get_FontPath(std::wstring* wsPath); - virtual HRESULT put_FontPath(const std::wstring& wsPath); - virtual HRESULT get_FontSize(double* dSize); - virtual HRESULT put_FontSize(const double& dSize); - virtual HRESULT get_FontStyle(LONG* lStyle); - virtual HRESULT put_FontStyle(const LONG& lStyle); - virtual HRESULT get_FontStringGID(INT* bGid); - virtual HRESULT put_FontStringGID(const INT& bGid); - virtual HRESULT get_FontCharSpace(double* dSpace); - virtual HRESULT put_FontCharSpace(const double& dSpace); - virtual HRESULT get_FontFaceIndex(int* lFaceIndex); - virtual HRESULT put_FontFaceIndex(const int& lFaceIndex); - //---------------------------------------------------------------------------------------- - // Функции для вывода текста - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandDrawTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT CommandDrawTextCHAR2 (unsigned int* unUnicode, const unsigned int& unUnicodeCount, const unsigned int& unGid, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Маркеры команд - //---------------------------------------------------------------------------------------- - virtual HRESULT BeginCommand(const DWORD& lType); - virtual HRESULT EndCommand(const DWORD& lType); - //---------------------------------------------------------------------------------------- - // Функции для работы с патом - //---------------------------------------------------------------------------------------- - virtual HRESULT PathCommandMoveTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLineTo(const double& dX, const double& dY); - virtual HRESULT PathCommandLinesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe); - virtual HRESULT PathCommandCurvesTo(double* pPoints, const int& nCount); - virtual HRESULT PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle); - virtual HRESULT PathCommandClose(); - virtual HRESULT PathCommandEnd(); - virtual HRESULT DrawPath(const LONG& lType); - virtual HRESULT PathCommandStart(); - virtual HRESULT PathCommandGetCurrentPoint(double* dX, double* dY); - virtual HRESULT PathCommandTextCHAR (const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandText (const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT PathCommandTextEx (const std::wstring& wsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& dX, const double& dY, const double& dW, const double& dH); - //---------------------------------------------------------------------------------------- - // Функции для вывода изображений - //---------------------------------------------------------------------------------------- - virtual HRESULT DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH); - virtual HRESULT DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha = 255); - //---------------------------------------------------------------------------------------- - // Функции для выставления преобразования - //---------------------------------------------------------------------------------------- - virtual HRESULT SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY); - virtual HRESULT GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY); - virtual HRESULT ResetTransform(); - //---------------------------------------------------------------------------------------- - // Тип клипа - //---------------------------------------------------------------------------------------- - virtual HRESULT get_ClipMode(LONG* lMode); - virtual HRESULT put_ClipMode(const LONG& lMode); - //---------------------------------------------------------------------------------------- - // Дополнительные функции - //---------------------------------------------------------------------------------------- - virtual HRESULT CommandLong(const LONG& lType, const LONG& lCommand); - virtual HRESULT CommandDouble(const LONG& lType, const double& dCommand); - virtual HRESULT CommandString(const LONG& lType, const std::wstring& sCommand); - virtual HRESULT AddHyperlink(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsUrl, const std::wstring& wsTooltip); - virtual HRESULT AddLink(const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const int& nPage); - virtual HRESULT AddFormField(IFormField* pInfo); - //---------------------------------------------------------------------------------------- - // Дополнительные функции Pdf рендерера - //---------------------------------------------------------------------------------------- - HRESULT CommandDrawTextPdf(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const std::wstring& wsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT PathCommandTextPdf(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const std::wstring& bsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH); - HRESULT EnableBrushRect(const LONG& lEnable); - HRESULT SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2); - HRESULT SetRadialGradient(const double& dX1, const double& dY1, const double& dR1, const double& dX2, const double& dY2, const double& dR2); - //HRESULT OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL); - //HRESULT OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL); - HRESULT DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH); - - //---------------------------------------------------------------------------------------- - // Дополнительные функции для дозаписи Pdf - //---------------------------------------------------------------------------------------- - void EditPdf(); - std::pair GetPageRef(int nPageIndex); - bool EditPage(PdfWriter::CPage* pNewPage); - bool AddPage(int nPageIndex); - bool DeletePage(int nPageIndex); - bool EditClose(); - void PageRotate(int nRotate); - void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); - std::wstring GetEditPdfPath(); - PdfWriter::CDocument* GetPDFDocument() { return m_pDocument; } - - NSFonts::IApplicationFonts* GetApplicationFonts(); - -private: - PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha); - bool DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); - bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY); - bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); - void UpdateFont(); - void GetFontPath(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, std::wstring& wsFontPath, LONG& lFaceIndex); - PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontPath, const LONG& lFontIndex); - PdfWriter::CFontCidTrueType* GetFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic); - void UpdateTransform(); - void UpdatePen(); - void UpdateBrush(); - void Reset(); - bool IsValid(); - bool IsPageValid(); - void SetError(); - void AddLink(PdfWriter::CPage* pPage, const double& dX, const double& dY, const double& dW, const double& dH, const double& dDestX, const double& dDestY, const unsigned int& unDestPage); - unsigned char* EncodeString(const unsigned int* pUnicodes, const unsigned int& unUnicodesCount, const unsigned int* pGIDs = NULL); - unsigned char* EncodeGID(const unsigned int& unGID, const unsigned int* pUnicodes, const unsigned int& unUnicodesCount); - std::wstring GetDownloadFile(const std::wstring& sUrl); - -private: - - struct TFontInfo - { - TFontInfo(const std::wstring& fontName, const bool& bold, const bool& italic, const std::wstring& fontPath, const LONG& faceIndex) - { - wsFontName = fontName; - bBold = bold; - bItalic = italic; - wsFontPath = fontPath; - lFaceIndex = faceIndex; - } - - std::wstring wsFontName; - bool bBold; - bool bItalic; - std::wstring wsFontPath; - LONG lFaceIndex; - }; - struct TColor - { - TColor() - { - lColor = 0; - r = 0; - g = 0; - b = 0; - a = 255; - } - TColor(const LONG& _lColor) - { - Set(_lColor); - } - - void Set(const LONG& _lColor) - { - lColor = _lColor; - - r = (unsigned char)(lColor & 0xFF); - g = (unsigned char)((lColor >> 8) & 0xFF); - b = (unsigned char)((lColor >> 16) & 0xFF); - a = (unsigned char)((lColor >> 24) & 0xFF); - } - void operator=(const LONG& _lColor) - { - Set(_lColor); - } - void Set(BYTE _r, BYTE _g, BYTE _b, BYTE _a = 255) - { - r = _r; - g = _g; - b = _b; - a = _a; - - lColor = (LONG)(((LONG)r) | ((LONG)g << 8) | ((LONG)b << 16) | ((LONG)a << 24)); - } - - LONG lColor; - BYTE r; - BYTE g; - BYTE b; - BYTE a; - }; - class CPenState - { - public: - - CPenState() - { - m_pDashPattern = NULL; - Reset(); - } - ~CPenState() - { - if (m_pDashPattern) - delete[] m_pDashPattern; - } - inline LONG GetColor() - { - return m_oColor.lColor; - } - inline void SetColor(const LONG& lColor) - { - m_oColor.Set(lColor); - } - inline TColor GetTColor() - { - return m_oColor; - } - inline LONG GetAlpha() - { - return m_nAlpha; - } - inline void SetAlpha(const LONG& lAlpha) - { - m_nAlpha = (BYTE)(std::max)(0, (std::min)(255, (int)lAlpha)); - } - inline double GetSize() - { - return m_dSize; - } - inline void SetSize(const double& dSize) - { - m_dSize = dSize; - } - inline BYTE GetDashStyle() - { - return m_nDashStyle; - } - inline void SetDashStyle(const BYTE& nDashStyle) - { - m_nDashStyle = nDashStyle; - } - inline BYTE GetStartCapStyle() - { - return m_nStartCapStyle; - } - inline void SetStartCapStyle(const BYTE& nCapStyle) - { - m_nStartCapStyle = nCapStyle; - } - inline BYTE GetEndCapStyle() - { - return m_nEndCapStyle; - } - inline void SetEndCapStyle(const BYTE& nCapStyle) - { - m_nEndCapStyle = nCapStyle; - } - inline BYTE GetJoinStyle() - { - return m_nJoinStyle; - } - inline void SetJoinStyle(const BYTE& nJoinStyle) - { - m_nJoinStyle = nJoinStyle; - } - inline double GetDashOffset() - { - return m_dDashOffset; - } - inline void SetDashOffset(const double& dOffset) - { - m_dDashOffset = dOffset; - } - inline LONG GetAlign() - { - return m_lAlign; - } - inline void SetAlign(const LONG& lAlign) - { - m_lAlign = lAlign; - } - inline double GetMiter() - { - return m_dMiter; - } - inline void SetMiter(const double& dMiter) - { - m_dMiter = dMiter; - } - inline void SetDashPattern(const double* pPattern, const LONG& lSize) - { - if (m_pDashPattern) - { - delete[] m_pDashPattern; - m_pDashPattern = NULL; - } - - m_lDashPatternSize = 0; - - if (!pPattern || !lSize) - { - m_lDashPatternSize = 0; - m_pDashPattern = NULL; - } - else - { - // Избавляемся от нулей, потому что все pdf-ридеры плохо их воспринимают - std::vector vPattern; - for (LONG lIndex = 0; lIndex < lSize; lIndex++) - { - if (lIndex > 1 && fabs(pPattern[lIndex]) < 0.001) - { - if (0 == lIndex % 2) - { - if (fabs(pPattern[lIndex + 1]) < 0.001) - { - lIndex++; - } - else if (lIndex + 1 < lSize) - { - size_t nPatternSize = vPattern.size(); - vPattern.at(nPatternSize - 1) = vPattern.at(nPatternSize - 1) + pPattern[lIndex + 1]; - lIndex++; - } - } - else - { - size_t nPatternSize = vPattern.size(); - vPattern.at(nPatternSize - 2) = vPattern.at(nPatternSize - 2) + vPattern.at(nPatternSize - 1); - vPattern.pop_back(); - } - } - else - { - vPattern.push_back(pPattern[lIndex]); - } - } - - size_t nPatternSize = vPattern.size(); - if (nPatternSize > 0) - { - m_pDashPattern = new double[nPatternSize]; - if (m_pDashPattern) - { - for (int nIndex = 0; nIndex < nPatternSize; nIndex++) - { - m_pDashPattern[nIndex] = vPattern.at(nIndex); - } - m_lDashPatternSize = nPatternSize; - } - } - } - } - inline double*GetDashPattern(LONG& lSize) - { - lSize = m_lDashPatternSize; - return m_pDashPattern; - } - - void Reset() - { - if (m_pDashPattern) - delete[] m_pDashPattern; - - m_oColor.Set(0); - m_dSize = 0; - m_nAlpha = 255; - m_nStartCapStyle = Aggplus::LineCapRound; - m_nEndCapStyle = Aggplus::LineCapRound; - m_nJoinStyle = Aggplus::LineJoinRound; - - m_lAlign = 0; - m_dMiter = 0; - - m_nDashStyle = Aggplus::DashStyleSolid; - m_lDashPatternSize = 0; - m_pDashPattern = NULL; - - m_dDashOffset = 0; - } - - private: - - double m_dSize; - TColor m_oColor; - BYTE m_nAlpha; - BYTE m_nStartCapStyle; - BYTE m_nEndCapStyle; - BYTE m_nJoinStyle; - - LONG m_lAlign; - double m_dMiter; - - BYTE m_nDashStyle; - double m_dDashOffset; - double*m_pDashPattern; - LONG m_lDashPatternSize; - - }; - class CBrushState - { - public: - struct TColorAndPoint - { - TColorAndPoint() - { - lColor = 0; - dPoint = 0; - bUse = false; - } - TColorAndPoint(const LONG& color, const double& point) - { - lColor = color; - dPoint = point; - bUse = true; - } - - static bool Compare(const TColorAndPoint& oFirst, const TColorAndPoint& oSecond) - { - return (oFirst.dPoint < oSecond.dPoint); - } - static LONG GetLinearApprox(const TColorAndPoint& oPoint1, const TColorAndPoint& oPoint2, const double& dDstPoint) - { - double dPoint1 = oPoint1.dPoint; - double dPoint2 = oPoint2.dPoint; - LONG lColor1 = oPoint1.lColor; - LONG lColor2 = oPoint2.lColor; - - double dDiff = dPoint2 - dPoint1; - if (fabs(dDiff) < 0) - return lColor1; - - TColor oColor1 = lColor1; - TColor oColor2 = lColor2; - - BYTE r = (BYTE)(std::max)(0, (std::min)(255, (int)(oColor1.r + (oColor2.r - oColor1.r) / dDiff * (dDstPoint - dPoint1)))); - BYTE g = (BYTE)(std::max)(0, (std::min)(255, (int)(oColor1.g + (oColor2.g - oColor1.g) / dDiff * (dDstPoint - dPoint1)))); - BYTE b = (BYTE)(std::max)(0, (std::min)(255, (int)(oColor1.b + (oColor2.b - oColor1.b) / dDiff * (dDstPoint - dPoint1)))); - BYTE a = (BYTE)(std::max)(0, (std::min)(255, (int)(oColor1.a + (oColor2.a - oColor1.a) / dDiff * (dDstPoint - dPoint1)))); - - TColor oResColor; - oResColor.Set(r, g, b, a); - return oResColor.lColor; - } - - LONG lColor; - double dPoint; - bool bUse; - }; - struct TBrushRect - { - TBrushRect() - { - Reset(); - } - - void Reset() - { - bUse = false; - nVal = 0; - dLeft = 0; - dTop = 0; - dWidth = 0; - dHeight = 0; - } - - bool bUse; - int nVal; - double dLeft; - double dTop; - double dWidth; - double dHeight; - }; - - public: - CBrushState() - { - m_pShadingColors = NULL; - m_pShadingPoints = NULL; - m_lShadingPointsCount = 0; - Reset(); - } - ~CBrushState() - { - if (m_pShadingColors) - delete[] m_pShadingColors; - if (m_pShadingPoints) - delete[] m_pShadingPoints; - } - void Reset(); - inline LONG GetType() - { - return m_lType; - } - inline void SetType(const LONG& lType) - { - m_lType = lType; - } - inline LONG GetColor1() - { - return m_oColor1.lColor; - } - inline TColor GetTColor1() - { - return m_oColor1; - } - inline void SetColor1(const LONG& lColor) - { - m_oColor1.Set(lColor); - } - inline LONG GetColor2() - { - return m_oColor2.lColor; - } - inline TColor GetTColor2() - { - return m_oColor2; - } - inline void SetColor2(const LONG& lColor) - { - m_oColor2.Set(lColor); - } - inline LONG GetAlpha1() - { - return m_nAlpha1; - } - inline void SetAlpha1(const LONG& lAlpha) - { - m_nAlpha1 = (BYTE)(std::max)(0, (std::min)(255, (int)lAlpha)); - } - inline LONG GetAlpha2() - { - return m_nAlpha2; - } - inline void SetAlpha2(const LONG& lAlpha) - { - m_nAlpha2 = (BYTE)(std::max)(0, (std::min)(255, (int)lAlpha)); - } - inline std::wstring GetTexturePath() - { - return m_wsTexturePath; - } - inline void SetTexturePath(const std::wstring& wsPath) - { - m_wsTexturePath = wsPath; - } - inline LONG GetTextureMode() - { - return m_lTextureMode; - } - inline void SetTextureMode(const LONG& lMode) - { - m_lTextureMode = lMode; - } - inline BYTE GetTextureAlpha() - { - return m_nTextureAlpha; - } - inline void SetTextureAlpha(const LONG& lAlpha) - { - m_nTextureAlpha = (BYTE)(std::max)(0, (std::min)(255, (int)lAlpha)); - } - inline double GetLinearAngle() - { - return m_dLinearAngle; - } - inline void SetLinearAngle(const double& dAngle) - { - m_dLinearAngle = dAngle; - } - inline void SetGradientColors(LONG* pColors, double* pPoints, const LONG& lCount) - { - // Мы создаем упорядоченный по возрастанию массив, причем первая и последняя точки должны быть 0 и 1 соответственно. - if (m_pShadingColors) - { - delete[] m_pShadingColors; - m_pShadingColors = NULL; - } - - if (m_pShadingPoints) - { - delete[] m_pShadingPoints; - m_pShadingPoints = NULL; - } - - if (!pColors || !pPoints || !lCount) - return; - - // Проверим вырожденный случай, когда задана либо 1 точка, либо несколько точек с одинковым значением - bool bIrregular = false; - if (1 == lCount) - { - bIrregular = true; - } - else - { - bIrregular = true; - for (LONG lIndex = 0; lIndex < lCount; lIndex++) - { - double dPoint1 = pPoints[lIndex]; - for (LONG lIndex2 = lIndex + 1; lIndex2 < lCount; lIndex2++) - { - double dPoint2 = pPoints[lIndex2]; - if (fabs(dPoint2 - dPoint1) > 0.00001) - { - bIrregular = false; - break; - } - } - - if (!bIrregular) - break; - } - } - - if (bIrregular) - { - if (1 == lCount) - { - m_pShadingPoints = new double[2]; - m_pShadingColors = new TColor[2]; - - if (!m_pShadingColors || !m_pShadingColors) - return; - - m_pShadingPoints[0] = 0.0; - m_pShadingColors[0] = pColors[0]; - m_pShadingPoints[1] = 1.0; - m_pShadingColors[1] = pColors[0]; - m_lShadingPointsCount = 2; - } - else - { - if (pPoints[0] < 0) - { - m_pShadingPoints = new double[2]; - m_pShadingColors = new TColor[2]; - - if (!m_pShadingColors || !m_pShadingColors) - return; - - m_pShadingPoints[0] = 0.0; - m_pShadingColors[0] = pColors[lCount - 1]; - m_pShadingPoints[1] = 1.0; - m_pShadingColors[1] = pColors[lCount - 1]; - m_lShadingPointsCount = 2; - } - else if (pPoints[0] > 1) - { - m_pShadingPoints = new double[2]; - m_pShadingColors = new TColor[2]; - - if (!m_pShadingColors || !m_pShadingColors) - return; - - m_pShadingPoints[0] = 0.0; - m_pShadingColors[0] = pColors[0]; - m_pShadingPoints[1] = 1.0; - m_pShadingColors[1] = pColors[0]; - m_lShadingPointsCount = 2; - } - else - { - m_pShadingPoints = new double[4]; - m_pShadingColors = new TColor[4]; - - if (!m_pShadingColors || !m_pShadingColors) - return; - - m_pShadingPoints[0] = 0.0; - m_pShadingColors[0] = pColors[0]; - m_pShadingPoints[1] = pPoints[0]; - m_pShadingColors[1] = pColors[0]; - m_pShadingPoints[2] = pPoints[lCount - 1]; - m_pShadingColors[2] = pColors[lCount - 1]; - m_pShadingPoints[3] = 1.0; - m_pShadingColors[3] = pColors[lCount - 1]; - m_lShadingPointsCount = 4; - } - } - } - else - { - std::vector vPoints; - for (LONG lIndex = 0; lIndex < lCount; lIndex++) - { - vPoints.push_back(TColorAndPoint(pColors[lIndex], pPoints[lIndex])); - } - std::sort(vPoints.begin(), vPoints.end(), TColorAndPoint::Compare); - - LONG lMinIn = -1, lMaxIn = -1, lMinOut = -1, lMaxOut = -1; - for (LONG lIndex = 0; lIndex < lCount; lIndex++) - { - double dPoint = vPoints.at(lIndex).dPoint; - if (0 <= dPoint && dPoint <= 1) - { - if (-1 == lMinIn || dPoint < vPoints.at(lMinIn).dPoint) - lMinIn = lIndex; - - if (-1 == lMaxIn || dPoint > vPoints.at(lMaxIn).dPoint) - lMaxIn = lIndex; - } - else if (dPoint < 0) - { - if (-1 == lMinOut || dPoint > vPoints.at(lMinOut).dPoint) - lMinOut = lIndex; - } - else// if (dPoint > 1) - { - if (-1 == lMaxOut || dPoint < vPoints.at(lMaxOut).dPoint) - lMaxOut = lIndex; - } - } - - LONG lBeginIndex = lMinIn; - LONG lEndIndex = lMaxIn; - - bool bNeed0 = true, bNeed1 = true; - if (-1 != lMinIn && vPoints.at(lMinIn).dPoint < 0.001) - { - bNeed0 = false; - lBeginIndex = lMinIn; - vPoints.at(lMinIn).dPoint = 0; - } - else if (-1 != lMinOut && vPoints.at(lMinOut).dPoint > -0.001) - { - bNeed0 = false; - lBeginIndex = lMinOut; - vPoints.at(lMinOut).dPoint = 0; - } - - if (-1 != lMaxIn && vPoints.at(lMaxIn).dPoint > 0.999) - { - bNeed1 = false; - lEndIndex = lMaxIn; - vPoints.at(lEndIndex).dPoint = 1; - } - else if (-1 != lMaxOut && vPoints.at(lMaxOut).dPoint < 1.001) - { - bNeed1 = false; - lEndIndex = lMaxOut; - vPoints.at(lEndIndex).dPoint = 1; - } - - std::vector vResPoints; - if (bNeed0) - { - LONG lIndex0, lIndex1; - if (-1 != lMinOut) - { - if (-1 != lMinIn) - { - lIndex0 = lMinOut; - lIndex1 = lMinIn; - } - else if (-1 != lMaxOut) - { - lIndex0 = lMinOut; - lIndex1 = lMaxOut; - } - else - { - lIndex0 = lMinIn - 1; - lIndex1 = lMinIn; - } - } - else - { - if (-1 != lMinIn) - { - lIndex0 = lMinIn; - lIndex1 = lMinIn + 1; - } - else - { - lIndex0 = lMaxOut; - lIndex1 = lMaxOut + 1; - } - } - - LONG lColor0 = TColorAndPoint::GetLinearApprox(vPoints.at(lIndex0), vPoints.at(lIndex1), 0); - vResPoints.push_back(TColorAndPoint(lColor0, 0)); - } - - if (-1 != lBeginIndex && -1 != lEndIndex) - { - for (LONG lIndex = lBeginIndex; lIndex <= lEndIndex; lIndex++) - { - vResPoints.push_back(vPoints.at(lIndex)); - } - } - - if (bNeed1) - { - LONG lIndex0, lIndex1; - if (-1 != lMaxOut) - { - if (-1 != lMaxIn) - { - lIndex0 = lMaxIn; - lIndex1 = lMaxOut; - } - else if (-1 != lMinOut) - { - lIndex0 = lMinOut; - lIndex1 = lMaxOut; - } - else - { - lIndex0 = lMaxOut; - lIndex1 = lMaxOut + 1; - } - } - else - { - if (-1 != lMaxIn) - { - lIndex0 = lMaxIn - 1; - lIndex1 = lMaxIn; - } - else - { - lIndex0 = lMinOut - 1; - lIndex1 = lMinOut; - } - } - - LONG lColor1 = TColorAndPoint::GetLinearApprox(vPoints.at(lIndex0), vPoints.at(lIndex1), 1); - vResPoints.push_back(TColorAndPoint(lColor1, 1)); - } - - size_t lResCount = vResPoints.size(); - if (lResCount == 0) - return; - - m_pShadingColors = new TColor[lResCount]; - m_pShadingPoints = new double[lResCount]; - m_lShadingPointsCount = lResCount; - - if (!m_pShadingColors || !m_pShadingPoints) - return; - - for (LONG lIndex = 0; lIndex < lResCount; lIndex++) - { - m_pShadingColors[lIndex] = vResPoints.at(lIndex).lColor; - m_pShadingPoints[lIndex] = vResPoints.at(lIndex).dPoint; - } - } - } - inline void SetBrushRect(const int& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight) - { - m_oRect.nVal = nVal; - m_oRect.dLeft = dLeft; - m_oRect.dTop = dTop; - m_oRect.dWidth = dWidth; - m_oRect.dHeight = dHeight; - } - inline void EnableBrushRect(bool bEnable) - { - m_oRect.bUse = bEnable; - } - TBrushRect& GetBrushRect() - { - return m_oRect; - } - - inline void SetLinearGradientPattern(const double& dX0, const double& dY0, const double& dX1, const double& dY1) - { - m_pShadingPattern[0] = dX0; - m_pShadingPattern[1] = dY0; - m_pShadingPattern[2] = dX1; - m_pShadingPattern[3] = dY1; - } - inline void SetRadialGradientPattern(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1) - { - m_pShadingPattern[0] = dX0; - m_pShadingPattern[1] = dY0; - m_pShadingPattern[2] = dR0; - m_pShadingPattern[3] = dX1; - m_pShadingPattern[4] = dY1; - m_pShadingPattern[5] = dR1; - } - inline void GetLinearGradientPattern(double& dX0, double& dY0, double& dX1, double& dY1) - { - dX0 = m_pShadingPattern[0]; - dY0 = m_pShadingPattern[1]; - dX1 = m_pShadingPattern[2]; - dY1 = m_pShadingPattern[3]; - } - inline void GetRadialGradientPattern(double& dX0, double& dY0, double& dR0, double& dX1, double& dY1, double& dR1) - { - dX0 = m_pShadingPattern[0]; - dY0 = m_pShadingPattern[1]; - dR0 = m_pShadingPattern[2]; - dX1 = m_pShadingPattern[3]; - dY1 = m_pShadingPattern[4]; - dR1 = m_pShadingPattern[5]; - } - inline void GetGradientColors(TColor*& pColors, double*& pPoints, LONG& lCount) - { - pColors = m_pShadingColors; - pPoints = m_pShadingPoints; - lCount = m_lShadingPointsCount; - } - - private: - - LONG m_lType; - TColor m_oColor1; - TColor m_oColor2; - BYTE m_nAlpha1; - BYTE m_nAlpha2; - std::wstring m_wsTexturePath; - LONG m_lTextureMode; - BYTE m_nTextureAlpha; - double m_dLinearAngle; - TBrushRect m_oRect; - - TColor* m_pShadingColors; - double* m_pShadingPoints; - LONG m_lShadingPointsCount; - double m_pShadingPattern[6]; // У линейного градиента x0, y0, x1, y1 (2 не используются), у радиального x0, y0, r0, x1, y1, r1 - }; - class CFontState - { - public: - - CFontState() : m_wsPath(L""), m_wsName(L"Arial"), m_lStyle(0), m_bBold(false), m_bItalic(false), m_dCharSpace(0), - m_lFaceIndex(0), m_dSize(10), m_bGid(false), m_bNeedDoBold(false), m_bNeedDoItalic(false) - { - } - - void Reset() - { - m_wsPath = L""; - m_wsName = L"Arial"; - m_lStyle = 0; - m_bBold = false; - m_bItalic = false; - m_dCharSpace = 0; - m_lFaceIndex = 0; - m_dSize = 10; - m_bGid = false; - - m_bNeedDoBold = false; - m_bNeedDoItalic = false; - } - - inline std::wstring GetName() - { - return m_wsName; - } - inline void SetName(const std::wstring& wsName) - { - m_wsName = wsName; - } - inline std::wstring GetPath() - { - return m_wsPath; - } - inline void SetPath(const std::wstring& wsPath) - { - m_wsPath = wsPath; - } - inline double GetSize() - { - return m_dSize; - } - inline void SetSize(const double& dSize) - { - m_dSize = dSize; - } - inline LONG GetFaceIndex() - { - return m_lFaceIndex; - } - inline void SetFaceIndex(const LONG& lFaceIndex) - { - m_lFaceIndex = lFaceIndex; - } - inline LONG GetStyle() - { - return m_lStyle; - } - inline void SetStyle(const LONG& lStyle) - { - m_lStyle = lStyle; - m_bBold = (lStyle & 1 ? true : false); - m_bItalic = (lStyle & 2 ? true : false); - } - inline bool GetGid() - { - return m_bGid; - } - inline void SetGid(const bool& bGid) - { - m_bGid = bGid; - } - inline double GetCharSpace() - { - return m_dCharSpace; - } - inline void SetCharSpace(const double& dCharSpace) - { - m_dCharSpace = dCharSpace; - } - inline bool IsBold() - { - return m_bBold; - } - inline bool IsItalic() - { - return m_bItalic; - } - inline void SetNeedDoItalic(const bool& bNeedDoItalic) - { - m_bNeedDoItalic = bNeedDoItalic; - } - inline void SetNeedDoBold(const bool& bNeedDoBold) - { - m_bNeedDoBold = bNeedDoBold; - } - inline bool IsNeedDoItalic() - { - return m_bNeedDoItalic; - } - inline bool IsNeedDoBold() - { - return m_bNeedDoBold; - } - - private: - - std::wstring m_wsName; - std::wstring m_wsPath; - double m_dSize; - bool m_bGid; - LONG m_lFaceIndex; - LONG m_lStyle; - bool m_bBold; - bool m_bItalic; - double m_dCharSpace; - bool m_bNeedDoItalic; - bool m_bNeedDoBold; - }; - class CPath - { - private: - - enum EPathCommandType - { - rendererpathcommand_Unknown = 0x00, - rendererpathcommand_MoveTo = 0x01, - rendererpathcommand_LineTo = 0x02, - rendererpathcommand_CurveTo = 0x03, - rendererpathcommand_ArcTo = 0x04, - rendererpathcommand_Close = 0x05, - rendererpathcommand_TextChar = 0x06, - rendererpathcommand_Text = 0x07, - rendererpathcommand_TextExChar = 0x08, - rendererpathcommand_TextEx = 0x09 - }; - class CPathCommandBase - { - public: - CPathCommandBase() - { - } - virtual ~CPathCommandBase() - { - } - virtual void Draw(PdfWriter::CPage* pPage) = 0; - virtual void UpdateBounds(double& dL, double& dT, double& dR, double& dB) = 0; - virtual void GetLastPoint(double& dX, double& dY) = 0; - virtual EPathCommandType GetType() = 0; - }; - class CPathMoveTo : public CPathCommandBase - { - public: - CPathMoveTo(const double& dX, const double& dY) - { - x = dX; - y = dY; - } - void GetLastPoint(double& dX, double& dY) - { - dX = x; - dY = y; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_MoveTo; - } - - public: - - double x; - double y; - }; - class CPathLineTo : public CPathCommandBase - { - public: - CPathLineTo(const double& dX, const double& dY) - { - x = dX; - y = dY; - } - void GetLastPoint(double& dX, double& dY) - { - dX = x; - dY = y; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_LineTo; - } - - public: - - double x; - double y; - }; - class CPathCurveTo : public CPathCommandBase - { - public: - CPathCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe) - { - x1 = dX1; - y1 = dY1; - x2 = dX2; - y2 = dY2; - xe = dXe; - ye = dYe; - } - void GetLastPoint(double& dX, double& dY) - { - dX = xe; - dY = ye; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_CurveTo; - } - - public: - - double x1; - double y1; - double x2; - double y2; - double xe; - double ye; - }; - class CPathArcTo : public CPathCommandBase - { - public: - CPathArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle) - { - x = dX; - y = dY; - w = dW; - h = dH; - startAngle = dStartAngle; - sweepAngle = dSweepAngle; - } - void GetLastPoint(double& dX, double& dY) - { - // TODO: Надо грамотно пересчитать - dX = x; - dY = y; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_ArcTo; - } - - public: - - double x; - double y; - double w; - double h; - double startAngle; - double sweepAngle; - }; - class CPathClose : public CPathCommandBase - { - public: - CPathClose() - { - } - void GetLastPoint(double& dX, double& dY) - { - // TODO: Надо грамотно пересчитать - dX = 0; - dY = 0; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_Close; - } - }; - class CPathText : public CPathCommandBase - { - public: - CPathText(PdfWriter::CFontDict* pFont, unsigned char* pCodes, const unsigned int& unCodesCount, const double& dX, const double& dY, const double& dSize, const double& dCharSpace) - { - font = pFont; - codes = pCodes; - codesCount = unCodesCount; - x = dX; - y = dY; - fontSize = dSize; - charSpace = dCharSpace; - } - ~CPathText() - { - RELEASEARRAYOBJECTS(codes); - } - void GetLastPoint(double& dX, double& dY) - { - dX = x; - dY = y; - } - void Draw(PdfWriter::CPage* pPage); - void UpdateBounds(double& dL, double& dT, double& dR, double& dB); - EPathCommandType GetType() - { - return rendererpathcommand_Text; - } - - public: - - PdfWriter::CFontDict* font; - unsigned char* codes; - unsigned int codesCount; - double x; - double y; - double fontSize; - double charSpace; - }; - - public: - - CPath() - { - m_bIsMoveTo = false; - } - ~CPath() - { - Clear(); - } - - bool MoveTo(const double& dX, const double& dY) - { - m_bIsMoveTo = true; - return Add(new CPathMoveTo(dX, dY)); - } - bool LineTo(const double& dX, const double& dY) - { - if (!m_bIsMoveTo) - MoveTo(dX, dY); - - return Add(new CPathLineTo(dX, dY)); - } - bool CurveTo(double dX1, double dY1, double dX2, double dY2, double dXE, double dYE) - { - if (!m_bIsMoveTo) - MoveTo(dX1, dY1); - - return Add(new CPathCurveTo(dX1, dY1, dX2, dY2, dXE, dYE)); - } - bool ArcTo(double dX, double dY, double dW, double dH, double dStart, double dSweep) - { - if (!m_bIsMoveTo) - MoveTo(dX, dY); - - return Add(new CPathArcTo(dX, dY, dW, dH, dStart, dSweep)); - } - bool AddText(PdfWriter::CFontDict* pFont, unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY, const double& dSize, const double& dCharSpace) - { - return Add(new CPathText(pFont, pCodes, unLen, dX, dY, dSize, dCharSpace)); - } - bool Close() - { - return Add(new CPathClose()); - } - void Clear() - { - for (size_t nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++) - { - CPathCommandBase* pCommand = m_vCommands.at(nIndex); - delete pCommand; - } - m_vCommands.clear(); - m_bIsMoveTo = false; - } - bool IsMoveTo() - { - return m_bIsMoveTo; - } - void GetLastPoint(double& dX, double& dY); - void Draw(PdfWriter::CPage* pPage, bool bStroke, bool bFill, bool bEoFill); - void Clip(PdfWriter::CPage* pPage, bool bEvenOdd = false); - void GetBounds(double& dL, double& dT, double& dR, double& dB); - - private: - - bool Add(CPathCommandBase* pCommand) - { - if (pCommand) - { - m_vCommands.push_back(pCommand); - return true; - } - - return false; - } - - - public: - - std::vector m_vCommands; - bool m_bIsMoveTo; - }; - class CTransform - { - public: - - CTransform() - { - Reset(); - } - void operator=(const CTransform& oT) - { - m11 = oT.m11; - m12 = oT.m12; - m21 = oT.m21; - m22 = oT.m22; - dx = oT.dx; - dy = oT.dy; - } - void Reset() - { - m11 = 1.0; - m12 = 0.0; - m21 = 0.0; - m22 = 1.0; - dx = 0; - dy = 0; - } - bool IsIdentity() const - { - if (fabs(m11 - 1) < 0.001 - && fabs(m12) < 0.001 - && fabs(m21) < 0.001 - && fabs(m22 - 1) < 0.001 - && fabs(dx) < 0.001 - && fabs(dy) < 0.001) - return true; - - return false; - } - void Set(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) - { - m11 = dM11; - m12 = dM12; - m21 = dM21; - m22 = dM22; - dx = dX; - dy = dY; - } - - public: - - double m11; - double m12; - double m21; - double m22; - double dx; - double dy; - }; - class PDFWRITER_DECL_EXPORT CCommandManager - { - public: - CCommandManager(CPdfRenderer* pRenderer); - ~CCommandManager(); - CRendererTextCommand* AddText(unsigned char* pCodes, unsigned int nLen, const double& dX, const double& dY); - void Flush(); - void SetTransform(const CTransform& oTransform); - void SetTransform(const double& m11, const double& m12, const double& m21, const double& m22, const double& dx, const double& dy); - private: - void Add(CRendererCommandBase* pCommand); - void Clear(); - private: - CPdfRenderer* m_pRenderer; - std::vector m_vCommands; - CTransform m_oTransform; - }; - struct TImageInfo - { - std::wstring wsPath; - BYTE nAlpha; - int nWidth; - int nHeight; - PdfWriter::CImageDict* pImage; - }; - struct TDestinationInfo - { - TDestinationInfo(PdfWriter::CPage* page, const double& x, const double& y, const double& w, const double& h, const double& dx, const double& dy, const unsigned int& undpage) - { - pPage = page; - dX = x; - dY = y; - dW = w; - dH = h; - dDestX = dx; - dDestY = dy; - unDestPage = undpage; - } - - PdfWriter::CPage* pPage; - double dX; - double dY; - double dW; - double dH; - double dDestX; - double dDestY; - unsigned int unDestPage; - }; - class CFieldsManager - { - public: - - CFieldsManager() - { - m_unCounter = 0; - } - - std::string GetNewFieldName() - { - std::string sName("F"); - sName.append(std::to_string(++m_unCounter)); - return sName; - } - - private: - - unsigned int m_unCounter; - }; - //---------------------------------------------------------------------------------------- - // - // CMultiLineTextManager - // - //---------------------------------------------------------------------------------------- - class CMultiLineTextManager - { - public: - CMultiLineTextManager() - { - m_pCodes = NULL; - m_pWidths = NULL; - m_unLen = 0; - m_ushSpaceCode = 0; - m_unLineHeight = 0; - m_nAscent = 0; - m_nDescent = 0; - } - void Init(unsigned short* pCodes, unsigned int* pWidths, const unsigned int& unLen, const unsigned short& ushSpaceCode, const unsigned int& unLineHeight, const int& nAscent) - { - m_pCodes = pCodes; - m_pWidths = pWidths; - m_unLen = unLen; - m_ushSpaceCode = ushSpaceCode; - m_unLineHeight = unLineHeight; - m_nAscent = nAscent; - m_nDescent = unLineHeight - nAscent; - } - void Clear() - { - m_pCodes = NULL; - m_pWidths = NULL; - m_unLen = 0; - m_ushSpaceCode = 0; - m_unLineHeight = 0; - m_nAscent = 0; - m_nDescent = 0; - } - void CalculateLines(const double& dFontSize, const double& dW) - { - m_vBreaks.clear(); - - bool bLineStart = true, bWord = false, bFirstItemOnLine = true; - - unsigned int unPos = 0, unWordStartPos = 0; - double dWordWidth = 0; - double dX = 0, dKoef = dFontSize / 1000.0; - - while (unPos < m_unLen) - { - if (IsSpace(unPos)) - { - dX += dWordWidth + m_pWidths[unPos] * dKoef; - bWord = false; - dWordWidth = 0; - bLineStart = false; - bFirstItemOnLine = false; - } - else - { - double dLetterWidth = m_pWidths[unPos] * dKoef; - if (dX + dWordWidth + dLetterWidth > dW) - { - if (bLineStart) - { - if (bFirstItemOnLine) - { - if (unPos != m_unLen - 1) - m_vBreaks.push_back(unPos + 1); - - unPos++; - } - else - { - m_vBreaks.push_back(unPos); - } - } - else - { - if (bWord) - { - m_vBreaks.push_back(unWordStartPos); - unPos = unWordStartPos; - } - else - { - m_vBreaks.push_back(unPos); - } - } - - dX = 0; - bWord = false; - dWordWidth = 0; - bLineStart = true; - bFirstItemOnLine = true; - continue; - } - - if (bWord) - { - dWordWidth += m_pWidths[unPos] * dKoef; - } - else - { - unWordStartPos = unPos; - bWord = true; - dWordWidth = m_pWidths[unPos] * dKoef; - } - - bFirstItemOnLine = false; - } - - unPos++; - } - } - double ProcessAutoFit(const double& dW, const double& dH) - { - double dGoodFontSize = 0; - - // Параметры подобраны для совместимости с AdobeReader - double dFontSize = 4; - double dFontSizeStep = 0.797 / 3.0; - - while (true) - { - CalculateLines(dFontSize, dW); - if (CheckHeight(dH, dFontSize)) - { - dGoodFontSize = dFontSize; - dFontSize += dFontSizeStep; - - if (dFontSize > 12) - { - dFontSize = 12; - break; - } - } - else - { - if (dGoodFontSize > 0.001) - { - dFontSize = dGoodFontSize; - break; - } - - dFontSize -= dFontSizeStep; - if (dFontSize < 4) - { - dFontSize = 4; - break; - } - } - } - - return (floor(dFontSize * 1000.0 + 0.5) / 1000.0); - } - unsigned int GetLinesCount() const - { - return m_vBreaks.size() + 1; - } - unsigned int GetLineStartPos(const int& nLineIndex) const - { - if (!nLineIndex || nLineIndex > m_vBreaks.size()) - return 0; - - return m_vBreaks[nLineIndex - 1]; - } - unsigned int GetLineEndPos(const int& nLineIndex) const - { - if (nLineIndex >= m_vBreaks.size()) - return m_unLen; - - return m_vBreaks[nLineIndex]; - } - double GetLineWidth(const int& nLineIndex, const double& dFontSize = 10.0) - { - if (nLineIndex < 0 || nLineIndex > m_vBreaks.size()) - return 0; - - unsigned int unStart = GetLineStartPos(nLineIndex); - unsigned int unEnd = GetLineEndPos(nLineIndex); - - double dWidth = 0; - double dKoef = dFontSize / 1000.0; - - while (unStart < unEnd) - { - if (IsSpace(unStart)) - unStart++; - else - break; - } - - while (unEnd > unStart && unEnd > 0) - { - if (IsSpace(unEnd - 1)) - unEnd--; - else - break; - } - - for (unsigned int unPos = unStart; unPos < unEnd; ++unPos) - { - dWidth += m_pWidths[unPos] * dKoef; - } - - return dWidth; - } - - - private: - - inline bool IsSpace(const unsigned int& unPos) const - { - return (m_pCodes[unPos] == m_ushSpaceCode); - } - inline bool CheckHeight(const double& dH, const double& dFontSize) const - { - double dKoef = dFontSize / 1000.0; - return (GetLinesCount() * (m_unLineHeight * dKoef) < (dH - (m_nDescent * dKoef))); - } - - - private: - - unsigned short* m_pCodes; - unsigned int* m_pWidths; - unsigned int m_unLen; - unsigned short m_ushSpaceCode; - unsigned int m_unLineHeight; - int m_nAscent; - int m_nDescent; - - std::vector m_vBreaks; - }; - -private: - - NSFonts::IApplicationFonts* m_pAppFonts; - NSFonts::IFontManager* m_pFontManager; - std::wstring m_wsTempFolder; - - PdfWriter::CDocument* m_pDocument; - PdfWriter::CPage* m_pPage; - PdfWriter::CFontCidTrueType* m_pFont; - PdfWriter::CShading* m_pShading; - PdfWriter::CExtGrState* m_pShadingExtGrState; - - bool m_bNeedUpdateTextFont; - bool m_bNeedUpdateTextColor; - bool m_bNeedUpdateTextAlpha; - bool m_bNeedUpdateTextCharSpace; - bool m_bNeedUpdateTextSize; - - CCommandManager m_oCommandManager; - - CPenState m_oPen; - CBrushState m_oBrush; - CFontState m_oFont; - CPath m_oPath; - CTransform m_oTransform; - LONG m_lClipMode; - double m_dPageHeight; - double m_dPageWidth; - LONG m_lClipDepth; - std::vector m_vFonts; - std::vectorm_vDestinations; - CFieldsManager m_oFieldsManager; - CMultiLineTextManager m_oLinesManager; - - bool m_bValid; - bool m_bEdit; - bool m_bEditPage; -}; - -#endif // _PDF_WRITER_PDFRENDERER_H diff --git a/PdfWriter/PdfWriter.pro b/PdfWriter/PdfWriter.pro deleted file mode 100644 index bd8a9c4f55..0000000000 --- a/PdfWriter/PdfWriter.pro +++ /dev/null @@ -1,115 +0,0 @@ -QT -= core gui - -VERSION = 1.0.0.4 -TARGET = PdfWriter -TEMPLATE = lib - -CONFIG += shared -CONFIG += plugin - -CONFIG += core_static_link_libstd - -CORE_ROOT_DIR = $$PWD/.. -PWD_ROOT_DIR = $$PWD -include(../Common/base.pri) - -DEFINES += PDFWRITER_USE_DYNAMIC_LIBRARY - -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network) - -DEFINES += CRYPTOPP_DISABLE_ASM -LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib - -DEFINES += NOMINMAX - -core_linux { - DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H - QMAKE_CXXFLAGS += -Wno-narrowing -} -core_mac { - DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H -} -core_android { - QMAKE_CXXFLAGS += -Wno-narrowing -} - -core_windows { - DEFINES -= UNICODE - DEFINES -= _UNICODE - - LIBS += -lAdvapi32 - LIBS += -lShell32 - LIBS += -lUser32 -} - -include(../DesktopEditor/graphics/pro/freetype.pri) - -core_windows { - -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -HEADERS += \ - Src/AcroForm.h \ - Src/Annotation.h \ - Src/Catalog.h \ - Src/Consts.h \ - Src/Destination.h \ - Src/Document.h \ - Src/Encodings.h \ - Src/Encrypt.h \ - Src/EncryptDictionary.h \ - Src/Field.h \ - Src/Font.h \ - Src/Font14.h \ - Src/FontCidTT.h \ - Src/FontTT.h \ - Src/FontTTWriter.h \ - Src/GState.h \ - Src/Image.h \ - Src/Info.h \ - Src/Objects.h \ - Src/Outline.h \ - Src/Pages.h \ - Src/Pattern.h \ - Src/ResourcesDictionary.h \ - Src/Shading.h \ - Src/Streams.h \ - Src/Types.h \ - Src/Utils.h \ - OnlineOfficeBinToPdf.h \ - PdfRenderer.h \ - Src/Metadata.h \ - Src/ICCProfile.h - -SOURCES += \ - Src/AcroForm.cpp \ - Src/Annotation.cpp \ - Src/Catalog.cpp \ - Src/Destination.cpp \ - Src/Document.cpp \ - Src/Encrypt.cpp \ - Src/EncryptDictionary.cpp \ - Src/Field.cpp \ - Src/Font.cpp \ - Src/Font14.cpp \ - Src/FontCidTT.cpp \ - Src/FontTT.cpp \ - Src/FontTTWriter.cpp \ - Src/GState.cpp \ - Src/Image.cpp \ - Src/Info.cpp \ - Src/Objects.cpp \ - Src/Outline.cpp \ - Src/Pages.cpp \ - Src/Pattern.cpp \ - Src/ResourcesDictionary.cpp \ - Src/Shading.cpp \ - Src/Streams.cpp \ - Src/Utils.cpp \ - Src/Metadata.cpp \ - OnlineOfficeBinToPdf.cpp \ - PdfRenderer.cpp diff --git a/PdfWriter/PdfWriter.sln b/PdfWriter/PdfWriter.sln deleted file mode 100644 index 0846c99f4e..0000000000 --- a/PdfWriter/PdfWriter.sln +++ /dev/null @@ -1,51 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfWriter", "PdfWriter.vcxproj", "{D4A77282-62EC-465D-ACB4-9CEE6BC704E5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfWriterTest", "PdfWriterTest\PdfWriterTest.vcxproj", "{B819B482-8822-4809-B633-09F8946D761E}" - ProjectSection(ProjectDependencies) = postProject - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5} = {D4A77282-62EC-465D-ACB4-9CEE6BC704E5} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|Win32.ActiveCfg = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|Win32.Build.0 = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|x64.ActiveCfg = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Debug|x64.Build.0 = Debug|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|Mixed Platforms.Build.0 = Release|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|Win32.ActiveCfg = Release|Win32 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|Win32.Build.0 = Release|Win32 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|x64.ActiveCfg = Release|x64 - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5}.Release|x64.Build.0 = Release|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|Win32.ActiveCfg = Debug|Win32 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|Win32.Build.0 = Debug|Win32 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|x64.ActiveCfg = Debug|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Debug|x64.Build.0 = Debug|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Release|Mixed Platforms.Build.0 = Release|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Release|Win32.ActiveCfg = Release|Win32 - {B819B482-8822-4809-B633-09F8946D761E}.Release|Win32.Build.0 = Release|Win32 - {B819B482-8822-4809-B633-09F8946D761E}.Release|x64.ActiveCfg = Release|x64 - {B819B482-8822-4809-B633-09F8946D761E}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PdfWriter/PdfWriter.vcxproj b/PdfWriter/PdfWriter.vcxproj deleted file mode 100644 index db20ad1392..0000000000 --- a/PdfWriter/PdfWriter.vcxproj +++ /dev/null @@ -1,254 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {D4A77282-62EC-465D-ACB4-9CEE6BC704E5} - Win32Proj - PdfWriter - - - - StaticLibrary - true - v140 - Unicode - - - StaticLibrary - true - v140 - Unicode - - - StaticLibrary - false - v140 - true - Unicode - - - StaticLibrary - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\DesktopEditor\freetype-2.10.4\include;..\..\DesktopEditor\freetype-2.10.4\include\freetype;..\..\DesktopEditor\freetype-2.10.4\;%(AdditionalIncludeDirectories) - - - Windows - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;NOMINMAX;FT_CONFIG_OPTION_SYSTEM_ZLIB;FT2_BUILD_LIBRARY;%(PreprocessorDefinitions) - true - 4018;4005;4267 - ..\DesktopEditor\freetype-2.10.4\include;..\DesktopEditor\agg-2.4\include;..\DesktopEditor\cximage\zlib;..\DesktopEditor\freetype-2.10.4\include\freetype;%(AdditionalIncludeDirectories) - true - - - Windows - true - - - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) - true - ..\DesktopEditor\freetype-2.5.2\include;..\DesktopEditor\agg-2.4\include;..\DesktopEditor\cximage\zlib;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriter.vcxproj.filters b/PdfWriter/PdfWriter.vcxproj.filters deleted file mode 100644 index ffa3e81ca4..0000000000 --- a/PdfWriter/PdfWriter.vcxproj.filters +++ /dev/null @@ -1,345 +0,0 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {1fccc0b6-4331-4120-a261-6d13ed199aab} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {207e9ca3-771d-48cd-b185-e8557f5a59c9} - - - {e955fc8f-90e5-44a8-89b6-4f281e87c89a} - - - {033cacd7-e0b9-4894-8566-3197e61f07a8} - - - {6336853a-6b37-4a99-943f-d1852309adaa} - - - - - - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Source Files - - - Src\Font - - - Src\Encrypt - - - Src\Encrypt - - - Src\Font - - - Src\Font - - - Src\Font - - - Src\Source Files - - - Src\Source Files - - - Src - - - Src - - - Src\Source Files - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\ZLib - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\FreeType - - - Src\Source Files - - - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Font - - - Src\Encrypt - - - Src\Encrypt - - - Src\Font - - - Src\Font - - - Src\Font - - - Src\Header Files - - - Src\Header Files - - - Src - - - Src - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - Src\Header Files - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.cpp b/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.cpp deleted file mode 100644 index beb8a4ae4a..0000000000 --- a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -// PdfWriterLibTest.cpp : Defines the entry point for the console application. -// - -#include "stdafx.h" - -#include -#include -#include -#include -#include - -#include "../OnlineOfficeBinToPdf.h" -#include "../PdfRenderer.h" -#include "../../DesktopEditor/fontengine/ApplicationFonts.h" - -#include "../../DesktopEditor/raster/Metafile/MetaFile.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/common/Directory.h" - -#include "../../UnicodeConverter/UnicodeConverter.h" - -#include "../Src/Streams.h" -#include "../Src/Utils.h" -#include "../Src/Objects.h" -#include "../Src/Encrypt.h" -#include "../Src/Info.h" -#include "../Src/Document.h" -#include "../Src/Outline.h" -#include "../Src/Destination.h" -#include "../Src/Pages.h" -#include "../Src/Annotation.h" -#include "../Src/Image.h" -#include "../Src/Font.h" -#include "../Src/Font14.h" -#include "../Src/FontCidTT.h" -#include "../Src/Pattern.h" -#include "../Src/Field.h" - -using namespace PdfWriter; - -std::wstring g_wsOutFolder = L"D:\\Work\\Test\\TextOnline\\"; - -void TestDocument1() -{ - // PageLabels and Encryption - CDocument oPdf; - oPdf.CreateNew(); - oPdf.AddPage(); - oPdf.AddPageLabel(pagenumstyle_Decimal, 1, "Dec-"); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPageLabel(2, pagenumstyle_UpperRoman, 21, "UppRom-"); - - oPdf.SetPasswords(L"123", L"qwe"); - - oPdf.SaveToFile(g_wsOutFolder + L"Test1.pdf"); - oPdf.Close(); -} -void TestField() -{ - CDocument oPdf; - oPdf.CreateNew(); - oPdf.SetPDFAConformanceMode(true); - CPage* pPage = oPdf.AddPage(); - - CFontDict* pFont2 = oPdf.CreateFont14(standard14fonts_Courier); - - CFontTrueType* pFont = oPdf.CreateTrueTypeFont(L"C:/Windows/Fonts/centaur.ttf", 0); - - - //CTextField* pField1 = oPdf.CreateTextField(); - //pField1->SetRequiredFlag(false); - //pField1->AddPageRect(pPage, TRect(200, 400, 600, 200)); - //pField1->SetFieldName(L"Test"); - //pField1->SetFieldHint(L"Илья"); - //pField1->SetPlaceHolderText(L"123", TRgb(255, 0, 0), TRgb(254, 0, 0)); - //pField1->SetAlign(CFieldBase::EFieldAlignType::Center); - //CTextField* pField2 = oPdf.CreateTextField(); - //pField2->SetRequiredFlag(false); - //pField2->SetCombFlag(true); - //pField2->AddPageRect(pPage, TRect(200, 300, 300, 250)); - //pField2->SetFieldName(L"Test"); - //pField2->SetFieldHint(L"Hint"); - //pField2->SetDefaultAppearance((CFontDict*)pFont, 40, TRgb(0, 255, 0)); - //pField2->SetTextAppearance(L"Enter text", NULL, 0, (CFontDict*)pFont2, TRgb(255, 0, 0), 0.5, 40, 1, 14.3); - - //CTextField* pField3 = oPdf.CreateTextField(); - //pField3->SetRequiredFlag(false); - //pField3->SetCombFlag(true); - //pField3->AddPageRect(pPage, TRect(000, 500, 300, 450)); - //pField3->SetFieldName(L"Test123"); - //pField3->SetFieldHint(L"Hint123"); - ////pField3->SetMaxLen(100); - //pField3->SetTextValue(L"Enter text"); - //pField3->SetTextAppearance(L"Enter text", NULL, 0, pFont, TRgb(0, 255, 0), 0.5, 40, 1, 14.3); - - - //CTextField* pField33 = oPdf.CreateTextField(); - //pField33->SetRequiredFlag(false); - //pField33->SetCombFlag(true); - //pField33->AddPageRect(pPage, TRect(000, 400, 300, 350)); - //pField33->SetFieldName(L"Test123"); - //pField33->SetFieldHint(L"Hint123"); - ////pField33->SetMaxLen(100); - //pField33->SetAutoFit(true); - //pField33->SetTextValue(L"Enter text"); - //pField33->SetTextAppearance(L"Enter text", NULL, 0, pFont, TRgb(0, 255, 0), 0.5, 40, 1, 14.3); - - - //CTextField* pField4 = oPdf.CreateTextField(); - //pField4->SetRequiredFlag(false); - //pField4->AddPageRect(pPage, TRect(400, 500, 500, 450)); - //pField4->SetFieldName(L"Test1234"); - //pField4->SetFieldHint(L"Hint1234"); - //pField4->SetMaxLen(10); - //pField4->SetCombFlag(true); - //pField4->SetTextValue(L"Ilya"); - //pField4->SetFieldBorder(border_subtype_Solid, TRgb(255, 0, 0), 1, 0, 0, 0); - //pField4->SetTextAppearance(L"Ilya", NULL, 0, pFont, TRgb(255, 0, 0), 1, 40, 1, 14.3); - - CChoiceField* pComboBox = oPdf.CreateChoiceField(); - pComboBox->SetRequiredFlag(false); - pComboBox->AddPageRect(pPage, TRect(200, 600, 500, 550)); - pComboBox->SetFieldName(L"ComboBox1"); - pComboBox->SetFieldHint(L"Какой-то текст"); - pComboBox->SetTextValue(L"Введите цвет"); - pComboBox->AddOption(L"Зеленый"); - pComboBox->AddOption(L"Green"); - pComboBox->AddOption(L"Зеленый"); - pComboBox->SetComboFlag(true); - pComboBox->SetEditFlag(true); - pComboBox->SetFieldBorder(border_subtype_Solid, TRgb(0, 255, 0), 1, 0, 0, 0); - pComboBox->SetMultiSelectFlag(false); - pComboBox->SetPlaceHolderText(L"Введите цвет", TRgb(0, 0, 0), TRgb(122, 122, 122)); - pComboBox->SetTextAppearance(L"Введите цвет", NULL, 0, (CFontDict*)pFont, TRgb(122, 122, 122), 0.5, 40, 1, 14.3); - pComboBox->SetDefaultAppearance((CFontDict*)pFont, 40, TRgb(122, 122, 122)); - - //CCheckBoxField* pCheckBox = oPdf.CreateCheckBoxField(); - //pCheckBox->SetFieldName(L"CheckBox"); - //pCheckBox->SetRequiredFlag(false); - //pCheckBox->AddPageRect(pPage, TRect(50, 600, 100, 550)); - //pCheckBox->SetValue(true); - ////pCheckBox->SetAppearance(L"1", NULL, 0, pFont2, L"2", NULL, 0, pFont2, TRgb(0, 0, 0), 1, 40, 0, 0); - //pCheckBox->SetAppearance(1, TRgb(0, 0, 0), 1, 40, 0, 0); - - //CRadioGroupField* pRadioGroup = oPdf.GetRadioGroupField(L"RadioGroup"); - //CCheckBoxField* pRadio1 = pRadioGroup->CreateKid(); - //pRadio1->AddPageRect(pPage, TRect(50, 700, 100, 650)); - //pRadio1->SetValue(true); - ////pRadio1->SetAppearance(L"3", NULL, 0, pFont2, L"4", NULL, 0, pFont2, TRgb(0, 0, 0), 1, 40, 0, 0); - //pRadio1->SetAppearance(2, TRgb(0, 0, 0), 1, 40, 0, 0); - - //CCheckBoxField* pRadio2 = pRadioGroup->CreateKid(L"TestName"); - //pRadio2->AddPageRect(pPage, TRect(150, 700, 200, 650)); - //pRadio2->SetValue(true); - ////pRadio2->SetAppearance(L"3", NULL, 0, pFont2, L"4", NULL, 0, pFont2, TRgb(0, 0, 0), 1, 40, 0, 0); - //pRadio2->SetAppearance(2, TRgb(0, 0, 0), 1, 40, 0, 0); - - //CCheckBoxField* pRadio3 = pRadioGroup->CreateKid(); - //pRadio3->AddPageRect(pPage, TRect(250, 700, 300, 650)); - //pRadio3->SetValue(false); - ////pRadio3->SetAppearance(L"3", NULL, 0, pFont2, L"4", NULL, 0, pFont2, TRgb(0, 0, 0), 1, 40, 0, 0); - //pRadio3->SetAppearance(2, TRgb(0, 0, 0), 1, 40, 0, 0); - - CImageDict* pImage = oPdf.CreateImage(); - pImage->LoadJpeg(L"D:/1429799187_5060172-vinni-puh-idet-v-gosti.jpg", 3872, 2592); - //pImage->LoadJpeg(L"D:/Fry.jpg", 240, 240); - - pPage->DrawImage(pImage, 0, 0, 10, 10); - - //CPictureField* pPictureField = oPdf.CreatePictureField(); - //pPictureField->SetRequiredFlag(false); - //pPictureField->AddPageRect(pPage, TRect(100, 100, 500, 650)); - //pPictureField->SetFieldName(L"Pic"); - //pPictureField->SetFieldHint(L"Картинка"); - //pPictureField->SetShift(0.25, 0.75); - //pPictureField->SetScaleType(CPictureField::EScaleType::Bigger); - //pPictureField->SetFieldBorder(border_subtype_Solid, TRgb(255, 0, 0), 3, 0, 0, 0); - //pPictureField->SetShd(TRgb(0, 0, 255)); - //pPictureField->SetRespectBorders(true); - //pPictureField->SetAppearance(pImage); - - - oPdf.SaveToFile(g_wsOutFolder + L"TestField1.pdf"); - oPdf.Close(); -} -void TestDocument2() -{ - // Outline - CDocument oPdf; - oPdf.CreateNew(); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPage(); - - COutline* pOutline1 = oPdf.CreateOutline(NULL, "Test1"); - COutline* pOutline11 = oPdf.CreateOutline(pOutline1, "Test1.1"); - COutline* pOutline111 = oPdf.CreateOutline(pOutline11, "Test1.1.1"); - COutline* pOutline12 = oPdf.CreateOutline(pOutline1, "Test1.2"); - COutline* pOutline2 = oPdf.CreateOutline(NULL, "Test2"); - COutline* pOutline21 = oPdf.CreateOutline(pOutline2, "Test21"); - COutline* pOutline22 = oPdf.CreateOutline(pOutline2, "Test22"); - COutline* pOutline23 = oPdf.CreateOutline(pOutline2, "Test23"); - COutline* pOutline221 = oPdf.CreateOutline(pOutline22, "Test223"); - - CDestination* pDest = oPdf.CreateDestination(2); - pDest->SetXYZ(0, 792, 0); - pOutline21->SetDestination(pDest); - - pDest = oPdf.CreateDestination(3); - pDest->SetFit(); - pOutline11->SetDestination(pDest); - - - oPdf.SaveToFile(g_wsOutFolder + L"Test2.pdf"); - oPdf.Close(); -} -void TestDocument3() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(100); - pPage->SetWidth(100); - - pPage->MoveTo(10, 10); - pPage->LineTo(20, 20); - pPage->CurveTo(70, 30, 30, 20, 50, 50); - pPage->ClosePath(); - pPage->Fill(); - - pPage = oPdf.AddPage(); - pPage->SetHeight(400); - pPage->SetWidth(600); - - pPage->Ellipse(200, 200, 50, 100); - pPage->Fill(); - - pPage->GrSave(); - double dAngle = 30 * 3.141592f / 180; - pPage->Concat(cos(dAngle), -sin(dAngle), sin(dAngle), cos(dAngle), -50, 50); - pPage->MoveTo(400, 200); - pPage->EllipseArcTo(400, 200, 50, 100, 0, 145); - pPage->Stroke(); - pPage->GrRestore(); - - - - double pPattern[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern, 4, 5); - pPage->MoveTo(10, 10); - pPage->LineTo(20, 20); - pPage->CurveTo(70, 30, 30, 20, 50, 50); - pPage->ClosePath(); - pPage->Stroke(); - - pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(400); - - pPage->MoveTo(10, 10); - pPage->LineTo(350, 10); - pPage->LineTo(350, 350); - pPage->LineTo(10, 350); - pPage->ClosePath(); - pPage->Stroke(); - - pPage->SetLineWidth(4); - - pPage->GrSave(); - pPage->SetLineCap(linecap_Butt); - pPage->MoveTo(20, 20); - pPage->LineTo(330, 20); - pPage->Stroke(); - - pPage->SetLineCap(linecap_Round); - pPage->MoveTo(20, 40); - pPage->LineTo(330, 40); - pPage->Stroke(); - - pPage->SetLineCap(linecap_ProjectingSquare); - pPage->MoveTo(20, 60); - pPage->LineTo(330, 60); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - double pPattern1[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern1, 4, 0); - pPage->MoveTo(20, 80); - pPage->LineTo(330, 80); - pPage->Stroke(); - double pPattern2[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern2, 4, 5); - pPage->MoveTo(20, 100); - pPage->LineTo(330, 100); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->SetStrokeColor(255, 0, 0); - pPage->SetLineJoin(linejoin_Bevel); - pPage->MoveTo(20, 120); - pPage->LineTo(100, 120); - pPage->LineTo(100, 180); - pPage->Stroke(); - - pPage->SetStrokeColor(0, 255, 0); - pPage->SetLineJoin(linejoin_Miter); - pPage->SetMiterLimit(30); - pPage->MoveTo(120, 120); - pPage->LineTo(210, 120); - pPage->LineTo(210, 180); - pPage->Stroke(); - - pPage->SetStrokeColor(0, 0, 255); - pPage->SetLineJoin(linejoin_Round); - pPage->MoveTo(220, 120); - pPage->LineTo(330, 120); - pPage->LineTo(330, 180); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->SetFillColor(120, 15, 15); - pPage->MoveTo(30, 210); - pPage->LineTo(140, 210); - pPage->LineTo(140, 240); - pPage->LineTo(30, 240); - pPage->ClosePath(); - pPage->MoveTo(20, 200); - pPage->LineTo(150, 200); - pPage->LineTo(150, 250); - pPage->LineTo(20, 250); - pPage->ClosePath(); - pPage->EoFillStroke(); - - //pPage->SetExtGrState(oPdf.GetExtGState(0.8, 0.8)); - pPage->SetStrokeAlpha(20); - pPage->SetFillAlpha(20); - pPage->SetFillColor(15, 15, 120); - pPage->MoveTo(230, 210); - pPage->LineTo(320, 210); - pPage->LineTo(320, 240); - pPage->LineTo(230, 240); - pPage->ClosePath(); - pPage->MoveTo(220, 200); - pPage->LineTo(330, 200); - pPage->LineTo(330, 250); - pPage->LineTo(220, 250); - pPage->ClosePath(); - pPage->FillStroke(); - pPage->GrRestore(); - - - pPage->MoveTo(230, 310); - pPage->LineTo(320, 310); - pPage->LineTo(280, 340); - pPage->ClosePath(); - pPage->Clip(); - pPage->EndPath(); - - pPage->SetStrokeAlpha(122); - pPage->SetFillAlpha(122); - //pPage->SetExtGrState(oPdf.GetExtGState(0.5, 0.5)); - pPage->MoveTo(230, 310); - pPage->LineTo(320, 310); - pPage->LineTo(320, 340); - pPage->LineTo(230, 340); - pPage->ClosePath(); - pPage->MoveTo(220, 300); - pPage->LineTo(330, 300); - pPage->LineTo(330, 350); - pPage->LineTo(220, 350); - pPage->ClosePath(); - pPage->FillStroke(); - - - - oPdf.SaveToFile(g_wsOutFolder + L"Test3.pdf"); - oPdf.Close(); -} -void TestDocument4() -{ - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - CDestination* pDest = oPdf.CreateDestination(1); - pDest->SetXYZ(0, 792, 0); - //CAnnotation* pAnnot = oPdf.CreateLinkAnnot(0, TRect(0, 100, 100, 0), pDest); - //pAnnot = oPdf.CreateUriLinkAnnot(0, TRect(0, 200, 100, 100), "www.rbc.ru"); - - oPdf.SaveToFile(g_wsOutFolder + L"Test4.pdf"); - oPdf.Close(); -} -void TestDocument5() -{ - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - //CBgraFrame oFrame; - //oFrame.OpenFile(L"D:/test/_pdf/Test.jb2"); - - //TIFF* pTiff = TIFFOpenW(L"D:/test/_pdf/Test.tiff", "w+"); - //TIFFSetField(pTiff, TIFFTAG_IMAGEWIDTH, 800); - //TIFFSetField(pTiff, TIFFTAG_IMAGELENGTH, 1000); - //TIFFSetField(pTiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - //TIFFSetField(pTiff, TIFFTAG_XRESOLUTION, 200.0); - //TIFFSetField(pTiff, TIFFTAG_YRESOLUTION, 200.0); - //TIFFSetField(pTiff, TIFFTAG_COMPRESSION, COMPRESSION_CCITT_T6); - - //for (int nY = 0; nY < 1000; ++nY) - //{ - // BYTE pBuffer[800]; - // for (int nX = 0; nX < 100; ++nX) - // { - // pBuffer[nX] = (nX > nY ? 0 : 255); - // } - - // TIFFWriteScanline(pTiff, pBuffer, nY); - //} - //TIFFClose(pTiff); - - //CImageDict* pImage = oPdf.CreateImage(); - //pImage->LoadCCITT4(L"D:/test/_pdf/Test.tiff", 800, 1000); - //pPage->DrawImage(pImage, 100, 100, 200, 200); - - BYTE* pBuffer = new BYTE[100 * 800]; - for (int nY = 0; nY < 800; ++nY) - { - for (int nX = 0; nX < 100; ++nX) - { - pBuffer[nX + nY * 100] = rand() % 255;// (nX * 8 > nY ? 0 : 255); - } - } - - CImageDict* pImage = oPdf.CreateImage(); - pImage->LoadBW(pBuffer, 800, 800, 100); - delete pBuffer; - pPage->DrawImage(pImage, 100, 100, 200, 200); - - pBuffer = new BYTE[100 * 800]; - for (int nY = 0; nY < 800; ++nY) - { - for (int nX = 0; nX < 100; ++nX) - { - pBuffer[nX + nY * 100] = rand() % 255;// (nX * 8 > nY ? 0 : 255); - } - } - - pImage = oPdf.CreateImage(); - pImage->LoadBW(pBuffer, 800, 800, 100); - delete pBuffer; - pPage->DrawImage(pImage, 300, 300, 200, 200); - - - //CxImage oImage; - //oImage.Load(L"D:/test/_pdf/Test.jb2"); - - //CImageDict* pJb2Image = oPdf.CreateImage(); - //pJb2Image->LoadJb2(L"D:/test/_pdf/Test.jb2", 1728, 2376); - //pPage->DrawImage(pJb2Image, 100, 100, 200, 200); - - //CImageDict* pJpegImage = oPdf.CreateImage(); - //pJpegImage->LoadJpeg(L"D:/test/_pdf/Test.jpg", 670, 473); - //pPage->DrawImage(pJpegImage, 100, 100, 200, 200); - - //BYTE* pAlpha = new BYTE[4 * 400 * 300]; - //for (int nY = 0; nY < 300; nY++) - //{ - // for (int nX = 0; nX < 400; nX++) - // { - // int nIndex = 4 * (nY * 400 + nX); - - // if (nY > 300 / 2) - // { - // pAlpha[nIndex + 0] = 255; - // pAlpha[nIndex + 1] = 0; - // pAlpha[nIndex + 2] = 0; - // pAlpha[nIndex + 3] = 255; - // } - // else - // { - // pAlpha[nIndex + 0] = 0; - // pAlpha[nIndex + 1] = 0; - // pAlpha[nIndex + 2] = 255; - // pAlpha[nIndex + 3] = 128; - // } - // } - //} - - //CImageDict* pJpxImage = oPdf.CreateImage(); - //pJpxImage->LoadJpx(L"D:/test/_pdf/Test.jp2", 400, 300); - //pJpxImage->LoadSMask(pAlpha, 400, 300); - //pPage->DrawImage(pJpxImage, 300, 100, 200, 200); - - //delete[] pAlpha; - - ////CImageDict* pJb2Image = oPdf.CreateImage(); - ////pJb2Image->LoadJb2(L"D:/test/_pdf/Test.jbig2", 400, 300); - ////pPage->DrawImage(pJb2Image, 300, 300, 200, 200); - - //CImageDict* pRawImage = oPdf.CreateImage(); - - //BYTE* pBgra = new BYTE[4 * 100 * 100]; - //for (int nY = 0; nY < 100; nY++) - //{ - // for (int nX = 0; nX < 100; nX++) - // { - // int nIndex = 4 * (nY * 100 + nX); - - // if (nX > nY) - // { - // pBgra[nIndex + 0] = 255; - // pBgra[nIndex + 1] = 0; - // pBgra[nIndex + 2] = 0; - // pBgra[nIndex + 3] = 255; - // } - // else - // { - // pBgra[nIndex + 0] = 0; - // pBgra[nIndex + 1] = 0; - // pBgra[nIndex + 2] = 255; - // pBgra[nIndex + 3] = 20; - // } - // } - //} - - //pRawImage->LoadRaw(pBgra, 100, 100); - //pRawImage->LoadSMask(pBgra, 100, 100); - //pPage->DrawImage(pRawImage, 300, 300, 200, 200); - //delete[] pBgra; - - oPdf.SaveToFile(g_wsOutFolder + L"Test5.pdf"); - oPdf.Close(); -} -void TestDocument6() -{ - CDocument oPdf; - oPdf.SetPDFAConformanceMode(true); - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - CFontDict* pFont = oPdf.CreateFont14(standard14fonts_CourierOblique); - - pPage->BeginText(); - pPage->SetFontAndSize(pFont, 15); - pPage->DrawText(10, 100, (const BYTE*)"Ilya", 4); - - pPage->SetFontAndSize(pFont, 30); - pPage->DrawText(100, 100, (const BYTE*)"Ilya", 4); - - - pPage->SetCharSpace(6); - pPage->DrawText(100, 200, (const BYTE*)"Ilya", 4); - pPage->SetCharSpace(0); - - pPage->SetHorizontalScalling(200.0); - pPage->DrawText(100, 300, (const BYTE*)"Ilya", 4); - pPage->SetHorizontalScalling(100.0); - - double dAngle = 30 * 3.141592f / 180; - pPage->SetTextMatrix(cos(dAngle), -sin(dAngle), sin(dAngle), cos(dAngle), 0, 0); - pPage->DrawText(100, 400, (const BYTE*)"Ilya", 4); - - pPage->SetTextMatrix(1, 0, 0, 1, 0, 0); - pPage->DrawText(100, 500, (const BYTE*)"Ilya", 4); - - pPage->EndText(); - - pFont = oPdf.CreateFont14(standard14fonts_TimesBold); - - pPage->BeginText(); - - - pPage->SetFontAndSize(pFont, 30); - pPage->SetTextRenderingMode(textrenderingmode_Fill); - pPage->DrawText(300, 100, (const BYTE*)"Ilya", 4); - - - pPage->SetTextRenderingMode(textrenderingmode_Stroke); - pPage->DrawText(300, 200, (const BYTE*)"Ilya", 4); - pPage->SetCharSpace(0); - - pPage->SetFillColor(255, 0, 0); - pPage->SetStrokeColor(0, 0, 255); - pPage->SetTextRenderingMode(textrenderingmode_FillThenStroke); - pPage->DrawText(300, 300, (const BYTE*)"Ilya", 4); - pPage->SetHorizontalScalling(100.0); - - pPage->SetTextRenderingMode(textrenderingmode_Invisible); - pPage->DrawText(300, 400, (const BYTE*)"Ilya", 4); - - pPage->SetTextRenderingMode(textrenderingmode_StrokeClipping); - pPage->DrawText(300, 500, (const BYTE*)"Ilya", 4); - - pPage->EndText(); - - pPage->MoveTo(300, 505); - pPage->LineTo(400, 505); - pPage->LineTo(400, 515); - pPage->LineTo(300, 515); - pPage->ClosePath(); - pPage->Fill(); - - oPdf.SaveToFile(g_wsOutFolder + L"Test6.pdf"); - oPdf.Close(); -} -void TestDocument7() -{ - struct TRange - { - unsigned int rangeStart; - unsigned int rangeEnd; - }; - - int nRangesCount = 10; - const TRange arrRanges[] = - { - { 0x1D400, 0x1D4FF }, - { 0x1D500, 0x1D5FF }, - { 0x1D600, 0x1D6FF }, - { 0x1D700, 0x1D7FF }, - - { 0x10000, 0x1007F }, - { 0x10380, 0x1039F }, - { 0x0020, 0x007F }, - { 0x0400, 0x04FF }, - { 0x3040, 0x309F }, - { 0x30A0, 0x30FF } - }; - - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(1000); - - CFontCidTrueType* pFont = oPdf.CreateCidTrueTypeFont(g_wsOutFolder + L"/cambria.ttc", 1); - - pPage->BeginText(); - - int nX = 10; - int nY = 590; - - for (int nRangeIndex = 0; nRangeIndex < nRangesCount; nRangeIndex++) - { - unsigned int rangeStart = arrRanges[nRangeIndex].rangeStart; - unsigned int rangeEnd = arrRanges[nRangeIndex].rangeEnd; - unsigned int rangeLen = rangeEnd - rangeStart + 1; - unsigned int* pRange = new unsigned int[rangeLen]; - for (unsigned int unIndex = rangeStart; unIndex <= rangeEnd; unIndex++) - { - pRange[unIndex - rangeStart] = unIndex; - } - - pPage->SetFontAndSize(pFont, 10); - - unsigned char* pString = new unsigned char[rangeLen * 2]; - if (!pString) - return; - - for (unsigned int unIndex = 0; unIndex < rangeLen; unIndex++) - { - unsigned short ushCode = pFont->EncodeUnicode(pRange[unIndex]); - pString[2 * unIndex + 0] = (ushCode >> 8) & 0xFF; - pString[2 * unIndex + 1] = ushCode & 0xFF; - } - pPage->DrawText(nX, nY, (const BYTE*)pString, rangeLen * 2); - - delete[] pString; - delete[] pRange; - - nY -= 10; - } - - pPage->EndText(); - - oPdf.SaveToFile(g_wsOutFolder + L"Test7.pdf"); - oPdf.Close(); -} -void TestDocument8() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(600); - pPage->SetWidth(600); - - - pPage->GrSave(); - pPage->Ellipse(200, 200, 50, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount = 2; - unsigned char pColors[] = - { - 255, 0, 0, - 0, 0, 255 - }; - - unsigned char pAlphas[] ={ 255, 255 }; - CExtGrState* pExtGrState = NULL; - - double pPoints[] ={ 0, 1 }; - CShading* pShading = oPdf.CreateAxialShading(pPage, 200, 150, 200, 250, pColors, pAlphas, pPoints, 2, pExtGrState); - pPage->DrawShading(pShading); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->Ellipse(400, 200, 50, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount2 = 4; - unsigned char pColors2[] = - { - 255, 0, 0, - 0, 255, 0, - 255, 255, 255, - 0, 0, 255 - }; - unsigned char pAlphas2[] ={ 255, 255, 255, 255 }; - - double pPoints2[] ={ 0, 0.3, 0.7, 1 }; - - CShading* pShading2 = oPdf.CreateAxialShading(pPage, 400, 150, 400, 250, pColors2, pAlphas2, pPoints2, nCount2, pExtGrState); - pPage->DrawShading(pShading2); - pPage->GrRestore(); - - - pPage->GrSave(); - pPage->Ellipse(200, 400, 100, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount3 = 3; - unsigned char pColors3[] = - { - 255, 0, 0, - 255, 255, 0, - 0, 0, 255 - }; - unsigned char pAlphas3[] ={ 255, 255, 255 }; - - double pPoints3[] ={ 0, 0.5, 1 }; - - CShading* pShading3 = oPdf.CreateRadialShading(pPage, 200, 375, 20, 200, 425, 100, pColors3, pAlphas3, pPoints3, nCount3, pExtGrState); - pPage->DrawShading(pShading3); - pPage->GrRestore(); - - - oPdf.SaveToFile(g_wsOutFolder + L"Test8.pdf"); - oPdf.Close(); -} -void TestDocument9() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(600); - pPage->SetWidth(600); - - CImageDict* pJpegImage = oPdf.CreateImage(); - pJpegImage->LoadJpeg(L"D:/Test/PDF/Test.jpg", 600, 400); - - CImageTilePattern* pPattern = oPdf.CreateImageTilePattern(70, 70, pJpegImage, NULL, imagetilepatterntype_InverseX); - - pPage->GrSave(); - pPage->SetPatternColorSpace(pPattern); - pPage->Ellipse(300, 300, 200, 150); - pPage->Clip(); - pPage->Fill(); - pPage->GrRestore(); - - - oPdf.SaveToFile(g_wsOutFolder + L"Test9.pdf"); - oPdf.Close(); -} - - -void ConvertFolder(std::wstring wsFolderPath) -{ - NSFonts::IApplicationFonts *pAppFonts = NSFonts::NSApplication::Create(); - pAppFonts->Initialize(); - - MetaFile::IMetaFile *pMetaFile = MetaFile::Create(pAppFonts); - - CPdfRenderer oRenderer(pAppFonts); - - pMetaFile->Close(); - - std::wstring sExt; - - double dPx2Mm = 25.4 / 96; - - std::vector vFiles = NSDirectory::GetFiles(wsFolderPath); - - for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) - { - oRenderer.NewPage(); - - std::wstring wsFilePath = wsFolderPath; - wsFilePath.append(vFiles.at(nIndex)); - if (pMetaFile->LoadFromFile(wsFilePath.c_str())) - { - double dW, dH, dX, dY; - pMetaFile->GetBounds(&dX, &dY, &dW, &dH); - - dW *= dPx2Mm; - dH *= dPx2Mm; - dX *= dPx2Mm; - dY *= dPx2Mm; - - double dAspect = dH / dW; - dW = 595.27; - dH = dAspect * dW; - - oRenderer.put_Width(dW); - oRenderer.put_Height(dH); - //pMetaFile->DrawOnRenderer(&oRenderer, -dX, -dY, dW, dH); - pMetaFile->DrawOnRenderer(&oRenderer, 0, 0, dW, dH); - pMetaFile->Close(); - } - - printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); - } - - oRenderer.SaveToFile(wsFolderPath + L"Out.pdf"); - - delete pMetaFile; - delete pAppFonts; -} - -std::vector GetAllFilesInFolder(std::wstring wsFolder, std::wstring wsExt) -{ - std::vector vwsNames; - - std::wstring wsSearchPath = wsFolder; - wsSearchPath.append(L"*."); - wsSearchPath.append(wsExt); - - WIN32_FIND_DATA oFindData; - HANDLE hFind = ::FindFirstFile(wsSearchPath.c_str(), &oFindData); - if (hFind != INVALID_HANDLE_VALUE) - { - do - { - if (!(oFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - vwsNames.push_back(oFindData.cFileName); - } - } while (::FindNextFile(hFind, &oFindData)); - ::FindClose(hFind); - } - return vwsNames; -} - -//void ConvertFolder(std::wstring wsFolderPath, const int nType) -//{ -// NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); -// if (!pFonts) -// return; -// -// pFonts->Initialize(); -// -// MetaFile::CMetaFile oMetaFile(pFonts); -// CPdfRenderer oRenderer(pFonts); -// -// oMetaFile.Close(); -// -// std::wstring sExt; -// -// switch (nType) -// { -// case MetaFile::c_lMetaEmf: sExt = L"emf"; break; -// case MetaFile::c_lMetaWmf: sExt = L"wmf"; break; -// case MetaFile::c_lMetaSvm: sExt = L"svm"; break; -// } -// double dPx2Mm = 25.4 / 96; -// std::vector vFiles = GetAllFilesInFolder(wsFolderPath, sExt); -// for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) -// { -// oRenderer.NewPage(); -// -// std::wstring wsFilePath = wsFolderPath; -// wsFilePath.append(vFiles.at(nIndex)); -// if (oMetaFile.LoadFromFile(wsFilePath.c_str())) -// { -// double dW, dH, dX, dY; -// oMetaFile.GetBounds(&dX, &dY, &dW, &dH); -// -// dW *= dPx2Mm; -// dH *= dPx2Mm; -// dX *= dPx2Mm; -// dY *= dPx2Mm; -// -// double dAspect = dH / dW; -// dW = 595.27; -// dH = dAspect * dW; -// -// oRenderer.put_Width(dW); -// oRenderer.put_Height(dH); -// //oMetaFile.DrawOnRenderer(&oRenderer, -dX, -dY, dW, dH); -// oMetaFile.DrawOnRenderer(&oRenderer, 0, 0, dW, dH); -// oMetaFile.Close(); -// } -// -// printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); -// } -// -// oRenderer.SaveToFile(wsFolderPath + L"Out.pdf"); -// delete pFonts; -//} -//void TestMetafile() -//{ -// ConvertFolder(L"D://Test Files//Emf//", MetaFile::c_lMetaEmf); -// //ConvertFolder(L"D://Test Files//Wmf//", MetaFile::c_lMetaWmf); -//} -void TestOnlineBin() -{ - std::wstring wsFolderPath = L"D:/Test/PDF/TextOnline/"; - std::wstring wsTempFolder = L"D:/Test/PDF/TextOnline/Temp/"; - - NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); - if (!pFonts) - return; - - pFonts->Initialize(); - - clock_t oBeginTime = clock(); - double dPx2Mm = 25.4 / 96; - std::vector vFiles = GetAllFilesInFolder(wsFolderPath, L"txt"); - for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) - { - std::wstring wsFilePath = wsFolderPath; - wsFilePath.append(vFiles.at(nIndex)); - - std::wstring::size_type stFound = vFiles.at(nIndex).rfind(L"."); - std::wstring wsFileName = vFiles.at(nIndex); - if (stFound != std::wstring::npos) - wsFileName.erase(stFound); - - std::wstring wsOutPath = wsFolderPath + wsFileName + L".pdf"; - - CPdfRenderer oRenderer(pFonts, true); - oRenderer.SetTempFolder(wsTempFolder); - oRenderer.OnlineWordToPdf(wsFilePath, wsOutPath); - - printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); - } - - clock_t oEndTime = clock(); - double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; - printf("%f\n", dElapsedSecs); - - delete pFonts; -} -void TestOnlineBin2() -{ - std::wstring wsFileName = L"1234"; - std::wstring wsFolderPath = L"D:/Work/Test/TextOnline/"; - std::wstring wsTempFolder = L"D:/Work/Test/TextOnline/Temp/"; - - NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); - if (!pFonts) - return; - - pFonts->Initialize(); - - clock_t oBeginTime = clock(); - - std::wstring wsFilePath = wsFolderPath + wsFileName + L".txt"; - std::wstring wsOutPath = wsFolderPath + wsFileName + L".pdf"; - - CPdfRenderer oRenderer(pFonts, true); - oRenderer.SetTempFolder(wsTempFolder); - oRenderer.OnlineWordToPdf(wsFilePath, wsOutPath); - - clock_t oEndTime = clock(); - double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; - printf("%f\n", dElapsedSecs); - - delete pFonts; -} - -int main() -{ - TestField(); - TestDocument1(); - TestDocument2(); - TestDocument3(); - TestDocument4(); - TestDocument5(); - TestDocument6(); - TestDocument7(); - TestDocument8(); - TestDocument9(); - - //TestOnlineBin2(); - - return 0; -} - diff --git a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.pro b/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.pro deleted file mode 100644 index b01eff6c61..0000000000 --- a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.pro +++ /dev/null @@ -1,102 +0,0 @@ -QT -= core -QT -= gui - -TARGET = PdfWriterLibTest -TEMPLATE = app - -CONFIG += console -CONFIG -= app_bundle - -CORE_ROOT_DIR = $$PWD/../.. -PWD_ROOT_DIR = $$PWD -include($$CORE_ROOT_DIR/Common/base.pri) -include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -include($$CORE_ROOT_DIR/DesktopEditor/graphics/pro/freetype.pri) - -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfWriter) - -INCLUDEPATH += \ - $$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include/freetype - -DEFINES += NOMINMAX \ - CRYPTOPP_DISABLE_ASM - -LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib - -core_windows { -DEFINES -= UNICODE -DEFINES -= _UNICODE - -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -HEADERS += \ - ../Src/AcroForm.h \ - ../Src/Annotation.h \ - ../Src/Catalog.h \ - ../Src/Consts.h \ - ../Src/Destination.h \ - ../Src/Document.h \ - ../Src/Encodings.h \ - ../Src/Encrypt.h \ - ../Src/EncryptDictionary.h \ - ../Src/Field.h \ - ../Src/Font.h \ - ../Src/Font14.h \ - ../Src/FontCidTT.h \ - ../Src/FontTT.h \ - ../Src/FontTTWriter.h \ - ../Src/GState.h \ - ../Src/Image.h \ - ../Src/Info.h \ - ../Src/Objects.h \ - ../Src/Outline.h \ - ../Src/Pages.h \ - ../Src/Pattern.h \ - ../Src/ResourcesDictionary.h \ - ../Src/Shading.h \ - ../Src/Streams.h \ - ../Src/Types.h \ - ../Src/Utils.h \ - ../OnlineOfficeBinToPdf.h \ - ../PdfRenderer.h \ - ../Src/Metadata.h \ - ../Src/ICCProfile.h \ - stdafx.h \ - targetver.h - -SOURCES += \ - ../Src/AcroForm.cpp \ - ../Src/Annotation.cpp \ - ../Src/Catalog.cpp \ - ../Src/Destination.cpp \ - ../Src/Document.cpp \ - ../Src/Encrypt.cpp \ - ../Src/EncryptDictionary.cpp \ - ../Src/Field.cpp \ - ../Src/Font.cpp \ - ../Src/Font14.cpp \ - ../Src/FontCidTT.cpp \ - ../Src/FontTT.cpp \ - ../Src/FontTTWriter.cpp \ - ../Src/GState.cpp \ - ../Src/Image.cpp \ - ../Src/Info.cpp \ - ../Src/Objects.cpp \ - ../Src/Outline.cpp \ - ../Src/Pages.cpp \ - ../Src/Pattern.cpp \ - ../Src/ResourcesDictionary.cpp \ - ../Src/Shading.cpp \ - ../Src/Streams.cpp \ - ../Src/Utils.cpp \ - ../Src/Metadata.cpp \ - ../OnlineOfficeBinToPdf.cpp \ - ../PdfRenderer.cpp - -SOURCES += PdfWriterLibTest.cpp diff --git a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.sln b/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.sln deleted file mode 100644 index 1bd6be05ec..0000000000 --- a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfWriterLibTest", "PdfWriterLibTest.vcxproj", "{7DBC8195-1D94-4B34-863F-8F35CC59C231}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Debug|x64.ActiveCfg = Debug|x64 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Debug|x64.Build.0 = Debug|x64 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Debug|x86.ActiveCfg = Debug|Win32 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Debug|x86.Build.0 = Debug|Win32 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Release|x64.ActiveCfg = Release|x64 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Release|x64.Build.0 = Release|x64 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Release|x86.ActiveCfg = Release|Win32 - {7DBC8195-1D94-4B34-863F-8F35CC59C231}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj b/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj deleted file mode 100644 index 576a7f762f..0000000000 --- a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj +++ /dev/null @@ -1,272 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {7DBC8195-1D94-4B34-863F-8F35CC59C231} - Win32Proj - PdfWriterLibTest - 8.1 - - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - ..\..\build\lib\win_64\DEBUG;$(LibraryPath) - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - - - Level3 - Disabled - WIN64;_WIN64;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;NOMINMAX;FT2_BUILD_LIBRARY;CRYPTOPP_DISABLE_ASM;FT_CONFIG_OPTION_SYSTEM_ZLIB;%(PreprocessorDefinitions) - true - ..\..\DesktopEditor\agg-2.4\include;..\..\OfficeUtils\src\zlib-1.2.11;..\..\DesktopEditor\freetype-2.10.4\include;..\..\DesktopEditor\freetype-2.10.4\include\freetype;%(AdditionalIncludeDirectories) - 4018;4005;4267;4146;4703 - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj.filters b/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj.filters deleted file mode 100644 index 78eb59279b..0000000000 --- a/PdfWriter/PdfWriterLibTest/PdfWriterLibTest.vcxproj.filters +++ /dev/null @@ -1,366 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {21d59946-a4de-4629-bd36-fd186a3b2900} - - - {850ba345-bd3e-4b71-ae5b-f14f4f265a1b} - - - {bbbd9a0c-b31b-4512-b1dc-9fbd46c176c5} - - - - - - - - Header Files - - - Header Files - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - - - Source Files - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - ZLib - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - FreeType - - - PdfWriterLib - - - PdfWriterLib - - - PdfWriterLib - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriterLibTest/ReadMe.txt b/PdfWriter/PdfWriterLibTest/ReadMe.txt deleted file mode 100644 index 85b86bccd9..0000000000 --- a/PdfWriter/PdfWriterLibTest/ReadMe.txt +++ /dev/null @@ -1,40 +0,0 @@ -======================================================================== - CONSOLE APPLICATION : PdfWriterLibTest Project Overview -======================================================================== - -AppWizard has created this PdfWriterLibTest application for you. - -This file contains a summary of what you will find in each of the files that -make up your PdfWriterLibTest application. - - -PdfWriterLibTest.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -PdfWriterLibTest.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -PdfWriterLibTest.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named PdfWriterLibTest.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/PdfWriter/PdfWriterLibTest/stdafx.cpp b/PdfWriter/PdfWriterLibTest/stdafx.cpp deleted file mode 100644 index 6d94d969e7..0000000000 --- a/PdfWriter/PdfWriterLibTest/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// PdfWriterLibTest.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/PdfWriter/PdfWriterLibTest/stdafx.h b/PdfWriter/PdfWriterLibTest/stdafx.h deleted file mode 100644 index 13dd28a084..0000000000 --- a/PdfWriter/PdfWriterLibTest/stdafx.h +++ /dev/null @@ -1,29 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include -#include - -#pragma comment(lib, "../../Common/3dParty/icu/win_64/build/icuuc.lib") - -#ifdef _DEBUG -#pragma comment(lib, "CryptoPPLib.lib") -#pragma comment(lib, "UnicodeConverter.lib") -#pragma comment(lib, "graphics.lib") -#pragma comment(lib, "kernel.lib") -#pragma comment(lib, "Ws2_32.lib") -#else -#pragma comment(lib, "../../build/lib/win_64/CryptoPPLib.lib") -#pragma comment(lib, "../../build/lib/win_64/UnicodeConverter.lib") -#pragma comment(lib, "../../build/lib/win_64/graphics.lib") -#pragma comment(lib, "../../build/lib/win_64/kernel.lib") -#pragma comment(lib, "Ws2_32.lib") -#endif - -// TODO: reference additional headers your program requires here diff --git a/PdfWriter/PdfWriterLibTest/targetver.h b/PdfWriter/PdfWriterLibTest/targetver.h deleted file mode 100644 index 87c0086de7..0000000000 --- a/PdfWriter/PdfWriterLibTest/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/PdfWriter/PdfWriterTest/PdfWriterTest.cpp b/PdfWriter/PdfWriterTest/PdfWriterTest.cpp deleted file mode 100644 index b71c7c7a5a..0000000000 --- a/PdfWriter/PdfWriterTest/PdfWriterTest.cpp +++ /dev/null @@ -1,812 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -// PdfReaderTest.cpp : Defines the entry point for the console application. -// - -#include "stdafx.h" - -#include -#include -#include -#include - -#include "../OnlineOfficeBinToPdf.h" -#include "../PdfRenderer.h" -#include "../../DesktopEditor/fontengine/ApplicationFonts.h" - -#include "../../DesktopEditor/raster/Metafile/MetaFile.h" -#include "../../DesktopEditor/raster/BgraFrame.h" -#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" -#include "../../DesktopEditor/common/Directory.h" - -#include "../Src/Streams.h" -#include "../Src/Utils.h" -#include "../Src/Objects.h" -#include "../Src/Encrypt.h" -#include "../Src/Info.h" -#include "../Src/Document.h" -#include "../Src/Outline.h" -#include "../Src/Destination.h" -#include "../Src/Pages.h" -#include "../Src/Annotation.h" -#include "../Src/Image.h" -#include "../Src/Font.h" -#include "../Src/Font14.h" -#include "../Src/FontCidTT.h" -#include "../Src/Pattern.h" - -#define TEST_PDFWRITER_LIB - -#if defined(_WIN64) - #pragma comment(lib, "../../Common/3dParty/icu/win_64/build/icuuc.lib") -#elif defined (_WIN32) - - #if defined(_DEBUG) - #pragma comment(lib, "../../build/lib/win_32/DEBUG/graphics.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/kernel.lib") - //#pragma comment(lib, "../../build/lib/win_32/DEBUG/UnicodeConverter.lib") - #pragma comment(lib, "../../build/lib/win_32/DEBUG/CryptoPPLib.lib") - #else - #pragma comment(lib, "../../build/lib/win_32/graphics.lib") - #pragma comment(lib, "../../build/lib/win_32/kernel.lib") - //#pragma comment(lib, "../../build/lib/win_32/UnicodeConverter.lib") - #pragma comment(lib, "../../build/lib/win_32/CryptoPPLib.lib") - #endif - #pragma comment(lib, "../../build/bin/icu/win_32/icuuc.lib") -#endif - -using namespace PdfWriter; - -void TestDocument1() -{ - // PageLabels and Encryption - CDocument oPdf; - oPdf.CreateNew(); - oPdf.AddPage(); - oPdf.AddPageLabel(pagenumstyle_Decimal, 1, "Dec-"); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPageLabel(2, pagenumstyle_UpperRoman, 21, "UppRom-"); - - oPdf.SetPasswords(L"123", L"qwe"); - - oPdf.SaveToFile(L"D:/test/_pdf/Test1.pdf"); - oPdf.Close(); -} -void TestDocument2() -{ - // Outline - CDocument oPdf; - oPdf.CreateNew(); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPage(); - oPdf.AddPage(); - - COutline* pOutline1 = oPdf.CreateOutline(NULL, "Test1"); - COutline* pOutline11 = oPdf.CreateOutline(pOutline1, "Test1.1"); - COutline* pOutline111 = oPdf.CreateOutline(pOutline11, "Test1.1.1"); - COutline* pOutline12 = oPdf.CreateOutline(pOutline1, "Test1.2"); - COutline* pOutline2 = oPdf.CreateOutline(NULL, "Test2"); - COutline* pOutline21 = oPdf.CreateOutline(pOutline2, "Test21"); - COutline* pOutline22 = oPdf.CreateOutline(pOutline2, "Test22"); - COutline* pOutline23 = oPdf.CreateOutline(pOutline2, "Test23"); - COutline* pOutline221 = oPdf.CreateOutline(pOutline22, "Test223"); - - CDestination* pDest = oPdf.CreateDestination(2); - pDest->SetXYZ(0, 792, 0); - pOutline21->SetDestination(pDest); - - pDest = oPdf.CreateDestination(3); - pDest->SetFit(); - pOutline11->SetDestination(pDest); - - - oPdf.SaveToFile(L"D:/test/_pdf/Test2.pdf"); - oPdf.Close(); -} -void TestDocument3() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(100); - pPage->SetWidth(100); - - pPage->MoveTo(10, 10); - pPage->LineTo(20, 20); - pPage->CurveTo(70, 30, 30, 20, 50, 50); - pPage->ClosePath(); - pPage->Fill(); - - pPage = oPdf.AddPage(); - pPage->SetHeight(400); - pPage->SetWidth(600); - - pPage->Ellipse(200, 200, 50, 100); - pPage->Fill(); - - pPage->GrSave(); - double dAngle = 30 * 3.141592f / 180; - pPage->Concat(cos(dAngle), -sin(dAngle), sin(dAngle), cos(dAngle), -50, 50); - pPage->MoveTo(400, 200); - pPage->EllipseArcTo(400, 200, 50, 100, 0, 145); - pPage->Stroke(); - pPage->GrRestore(); - - - - double pPattern[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern, 4, 5); - pPage->MoveTo(10, 10); - pPage->LineTo(20, 20); - pPage->CurveTo(70, 30, 30, 20, 50, 50); - pPage->ClosePath(); - pPage->Stroke(); - - pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(400); - - pPage->MoveTo(10, 10); - pPage->LineTo(350, 10); - pPage->LineTo(350, 350); - pPage->LineTo(10, 350); - pPage->ClosePath(); - pPage->Stroke(); - - pPage->SetLineWidth(4); - - pPage->GrSave(); - pPage->SetLineCap(linecap_Butt); - pPage->MoveTo(20, 20); - pPage->LineTo(330, 20); - pPage->Stroke(); - - pPage->SetLineCap(linecap_Round); - pPage->MoveTo(20, 40); - pPage->LineTo(330, 40); - pPage->Stroke(); - - pPage->SetLineCap(linecap_ProjectingSquare); - pPage->MoveTo(20, 60); - pPage->LineTo(330, 60); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - double pPattern1[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern1, 4, 0); - pPage->MoveTo(20, 80); - pPage->LineTo(330, 80); - pPage->Stroke(); - double pPattern2[] ={ 1, 5, 5, 2 }; - pPage->SetDash((const double*)pPattern2, 4, 5); - pPage->MoveTo(20, 100); - pPage->LineTo(330, 100); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->SetStrokeColor(255, 0, 0); - pPage->SetLineJoin(linejoin_Bevel); - pPage->MoveTo(20, 120); - pPage->LineTo(100, 120); - pPage->LineTo(100, 180); - pPage->Stroke(); - - pPage->SetStrokeColor(0, 255, 0); - pPage->SetLineJoin(linejoin_Miter); - pPage->SetMiterLimit(30); - pPage->MoveTo(120, 120); - pPage->LineTo(210, 120); - pPage->LineTo(210, 180); - pPage->Stroke(); - - pPage->SetStrokeColor(0, 0, 255); - pPage->SetLineJoin(linejoin_Round); - pPage->MoveTo(220, 120); - pPage->LineTo(330, 120); - pPage->LineTo(330, 180); - pPage->Stroke(); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->SetFillColor(120, 15, 15); - pPage->MoveTo(30, 210); - pPage->LineTo(140, 210); - pPage->LineTo(140, 240); - pPage->LineTo(30, 240); - pPage->ClosePath(); - pPage->MoveTo(20, 200); - pPage->LineTo(150, 200); - pPage->LineTo(150, 250); - pPage->LineTo(20, 250); - pPage->ClosePath(); - pPage->EoFillStroke(); - - //pPage->SetExtGrState(oPdf.GetExtGState(0.8, 0.8)); - pPage->SetStrokeAlpha(20); - pPage->SetFillAlpha(20); - pPage->SetFillColor(15, 15, 120); - pPage->MoveTo(230, 210); - pPage->LineTo(320, 210); - pPage->LineTo(320, 240); - pPage->LineTo(230, 240); - pPage->ClosePath(); - pPage->MoveTo(220, 200); - pPage->LineTo(330, 200); - pPage->LineTo(330, 250); - pPage->LineTo(220, 250); - pPage->ClosePath(); - pPage->FillStroke(); - pPage->GrRestore(); - - - pPage->MoveTo(230, 310); - pPage->LineTo(320, 310); - pPage->LineTo(280, 340); - pPage->ClosePath(); - pPage->Clip(); - pPage->EndPath(); - - pPage->SetStrokeAlpha(122); - pPage->SetFillAlpha(122); - //pPage->SetExtGrState(oPdf.GetExtGState(0.5, 0.5)); - pPage->MoveTo(230, 310); - pPage->LineTo(320, 310); - pPage->LineTo(320, 340); - pPage->LineTo(230, 340); - pPage->ClosePath(); - pPage->MoveTo(220, 300); - pPage->LineTo(330, 300); - pPage->LineTo(330, 350); - pPage->LineTo(220, 350); - pPage->ClosePath(); - pPage->FillStroke(); - - oPdf.SetDocumentID(L"23193r09jscladjalj"); - oPdf.SetPasswords(L"123", L"qwe"); - oPdf.SetPDFAConformanceMode(true); - - oPdf.SaveToFile(L"D:/test/_pdf/Test3-pdfa-my.pdf"); - oPdf.Close(); -} -void TestDocument4() -{ - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - CDestination* pDest = oPdf.CreateDestination(1); - pDest->SetXYZ(0, 792, 0); - //CAnnotation* pAnnot = oPdf.CreateLinkAnnot(0, TRect(0, 100, 100, 0), pDest); - //pAnnot = oPdf.CreateUriLinkAnnot(0, TRect(0, 200, 100, 100), "www.rbc.ru"); - - oPdf.SaveToFile(L"D:/test/_pdf/Test4.pdf"); - oPdf.Close(); -} -void TestDocument5() -{ - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - //CBgraFrame oFrame; - //oFrame.OpenFile(L"D:/test/_pdf/Test.jb2"); - - //TIFF* pTiff = TIFFOpenW(L"D:/test/_pdf/Test.tiff", "w+"); - //TIFFSetField(pTiff, TIFFTAG_IMAGEWIDTH, 800); - //TIFFSetField(pTiff, TIFFTAG_IMAGELENGTH, 1000); - //TIFFSetField(pTiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - //TIFFSetField(pTiff, TIFFTAG_XRESOLUTION, 200.0); - //TIFFSetField(pTiff, TIFFTAG_YRESOLUTION, 200.0); - //TIFFSetField(pTiff, TIFFTAG_COMPRESSION, COMPRESSION_CCITT_T6); - - //for (int nY = 0; nY < 1000; ++nY) - //{ - // BYTE pBuffer[800]; - // for (int nX = 0; nX < 100; ++nX) - // { - // pBuffer[nX] = (nX > nY ? 0 : 255); - // } - - // TIFFWriteScanline(pTiff, pBuffer, nY); - //} - //TIFFClose(pTiff); - - //CImageDict* pImage = oPdf.CreateImage(); - //pImage->LoadCCITT4(L"D:/test/_pdf/Test.tiff", 800, 1000); - //pPage->DrawImage(pImage, 100, 100, 200, 200); - - BYTE* pBuffer = new BYTE[100 * 800]; - for (int nY = 0; nY < 800; ++nY) - { - for (int nX = 0; nX < 100; ++nX) - { - pBuffer[nX + nY * 100] = rand() % 255;// (nX * 8 > nY ? 0 : 255); - } - } - - CImageDict* pImage = oPdf.CreateImage(); - pImage->LoadBW(pBuffer, 800, 800, 100); - delete pBuffer; - pPage->DrawImage(pImage, 100, 100, 200, 200); - - pBuffer = new BYTE[100 * 800]; - for (int nY = 0; nY < 800; ++nY) - { - for (int nX = 0; nX < 100; ++nX) - { - pBuffer[nX + nY * 100] = rand() % 255;// (nX * 8 > nY ? 0 : 255); - } - } - - pImage = oPdf.CreateImage(); - pImage->LoadBW(pBuffer, 800, 800, 100); - delete pBuffer; - pPage->DrawImage(pImage, 300, 300, 200, 200); - - - //CxImage oImage; - //oImage.Load(L"D:/test/_pdf/Test.jb2"); - - //CImageDict* pJb2Image = oPdf.CreateImage(); - //pJb2Image->LoadJb2(L"D:/test/_pdf/Test.jb2", 1728, 2376); - //pPage->DrawImage(pJb2Image, 100, 100, 200, 200); - - //CImageDict* pJpegImage = oPdf.CreateImage(); - //pJpegImage->LoadJpeg(L"D:/test/_pdf/Test.jpg", 670, 473); - //pPage->DrawImage(pJpegImage, 100, 100, 200, 200); - - //BYTE* pAlpha = new BYTE[4 * 400 * 300]; - //for (int nY = 0; nY < 300; nY++) - //{ - // for (int nX = 0; nX < 400; nX++) - // { - // int nIndex = 4 * (nY * 400 + nX); - - // if (nY > 300 / 2) - // { - // pAlpha[nIndex + 0] = 255; - // pAlpha[nIndex + 1] = 0; - // pAlpha[nIndex + 2] = 0; - // pAlpha[nIndex + 3] = 255; - // } - // else - // { - // pAlpha[nIndex + 0] = 0; - // pAlpha[nIndex + 1] = 0; - // pAlpha[nIndex + 2] = 255; - // pAlpha[nIndex + 3] = 128; - // } - // } - //} - - //CImageDict* pJpxImage = oPdf.CreateImage(); - //pJpxImage->LoadJpx(L"D:/test/_pdf/Test.jp2", 400, 300); - //pJpxImage->LoadSMask(pAlpha, 400, 300); - //pPage->DrawImage(pJpxImage, 300, 100, 200, 200); - - //delete[] pAlpha; - - ////CImageDict* pJb2Image = oPdf.CreateImage(); - ////pJb2Image->LoadJb2(L"D:/test/_pdf/Test.jbig2", 400, 300); - ////pPage->DrawImage(pJb2Image, 300, 300, 200, 200); - - //CImageDict* pRawImage = oPdf.CreateImage(); - - //BYTE* pBgra = new BYTE[4 * 100 * 100]; - //for (int nY = 0; nY < 100; nY++) - //{ - // for (int nX = 0; nX < 100; nX++) - // { - // int nIndex = 4 * (nY * 100 + nX); - - // if (nX > nY) - // { - // pBgra[nIndex + 0] = 255; - // pBgra[nIndex + 1] = 0; - // pBgra[nIndex + 2] = 0; - // pBgra[nIndex + 3] = 255; - // } - // else - // { - // pBgra[nIndex + 0] = 0; - // pBgra[nIndex + 1] = 0; - // pBgra[nIndex + 2] = 255; - // pBgra[nIndex + 3] = 20; - // } - // } - //} - - //pRawImage->LoadRaw(pBgra, 100, 100); - //pRawImage->LoadSMask(pBgra, 100, 100); - //pPage->DrawImage(pRawImage, 300, 300, 200, 200); - //delete[] pBgra; - - oPdf.SaveToFile(L"D:/test/_pdf/Test5.pdf"); - oPdf.Close(); -} -void TestDocument6() -{ - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(600); - - CFontDict* pFont = oPdf.CreateFont14(standard14fonts_CourierOblique); - - pPage->BeginText(); - pPage->SetFontAndSize(pFont, 15); - pPage->DrawText(10, 100, (const BYTE*)"Ilya", 4); - - pPage->SetFontAndSize(pFont, 30); - pPage->DrawText(100, 100, (const BYTE*)"Ilya", 4); - - - pPage->SetCharSpace(6); - pPage->DrawText(100, 200, (const BYTE*)"Ilya", 4); - pPage->SetCharSpace(0); - - pPage->SetHorizontalScalling(200.0); - pPage->DrawText(100, 300, (const BYTE*)"Ilya", 4); - pPage->SetHorizontalScalling(100.0); - - double dAngle = 30 * 3.141592f / 180; - pPage->SetTextMatrix(cos(dAngle), -sin(dAngle), sin(dAngle), cos(dAngle), 0, 0); - pPage->DrawText(100, 400, (const BYTE*)"Ilya", 4); - - pPage->SetTextMatrix(1, 0, 0, 1, 0, 0); - pPage->DrawText(100, 500, (const BYTE*)"Ilya", 4); - - pPage->EndText(); - - pFont = oPdf.CreateFont14(standard14fonts_TimesBold); - - pPage->BeginText(); - - - pPage->SetFontAndSize(pFont, 30); - pPage->SetTextRenderingMode(textrenderingmode_Fill); - pPage->DrawText(300, 100, (const BYTE*)"Ilya", 4); - - - pPage->SetTextRenderingMode(textrenderingmode_Stroke); - pPage->DrawText(300, 200, (const BYTE*)"Ilya", 4); - pPage->SetCharSpace(0); - - pPage->SetFillColor(255, 0, 0); - pPage->SetStrokeColor(0, 0, 255); - pPage->SetTextRenderingMode(textrenderingmode_FillThenStroke); - pPage->DrawText(300, 300, (const BYTE*)"Ilya", 4); - pPage->SetHorizontalScalling(100.0); - - pPage->SetTextRenderingMode(textrenderingmode_Invisible); - pPage->DrawText(300, 400, (const BYTE*)"Ilya", 4); - - pPage->SetTextRenderingMode(textrenderingmode_StrokeClipping); - pPage->DrawText(300, 500, (const BYTE*)"Ilya", 4); - - pPage->EndText(); - - pPage->MoveTo(300, 505); - pPage->LineTo(400, 505); - pPage->LineTo(400, 515); - pPage->LineTo(300, 515); - pPage->ClosePath(); - pPage->Fill(); - - oPdf.SaveToFile(L"D:/test/_pdf/Test6.pdf"); - oPdf.Close(); -} -void TestDocument7() -{ - struct TRange - { - unsigned int rangeStart; - unsigned int rangeEnd; - }; - - int nRangesCount = 10; - const TRange arrRanges[] = - { - { 0x1D400, 0x1D4FF }, - { 0x1D500, 0x1D5FF }, - { 0x1D600, 0x1D6FF }, - { 0x1D700, 0x1D7FF }, - - { 0x10000, 0x1007F }, - { 0x10380, 0x1039F }, - { 0x0020, 0x007F }, - { 0x0400, 0x04FF }, - { 0x3040, 0x309F }, - { 0x30A0, 0x30FF } - }; - - CDocument oPdf; - oPdf.CreateNew(); - CPage* pPage = oPdf.AddPage(); - pPage->SetHeight(600); - pPage->SetWidth(1000); - - //CFontCidTrueType* pFont = oPdf.CreateTrueTypeFont(L"D:/test/_pdf/Test.ttf", 0); - CFontCidTrueType* pFont = oPdf.CreateCidTrueTypeFont(L"D:/test/_pdf/cambria.ttc", 1); - - pPage->BeginText(); - - int nX = 10; - int nY = 590; - - for (int nRangeIndex = 0; nRangeIndex < nRangesCount; nRangeIndex++) - { - unsigned int rangeStart = arrRanges[nRangeIndex].rangeStart; - unsigned int rangeEnd = arrRanges[nRangeIndex].rangeEnd; - unsigned int rangeLen = rangeEnd - rangeStart + 1; - unsigned int* pRange = new unsigned int[rangeLen]; - for (unsigned int unIndex = rangeStart; unIndex <= rangeEnd; unIndex++) - { - pRange[unIndex - rangeStart] = unIndex; - } - - pPage->SetFontAndSize((CFontDict*)pFont, 10); - - unsigned char* pString = pFont->EncodeString(pRange, rangeLen); - pPage->DrawText(nX, nY, (const BYTE*)pString, rangeLen * 2); - - delete[] pString; - delete[] pRange; - - nY -= 10; - } - - pPage->EndText(); - - oPdf.SetDocumentID(L"23193r09jscladjalj"); - //oPdf.SetPasswords(L"123", L"qwe"); - oPdf.SaveToFile(L"D:/test/_pdf/Test7.pdf"); - oPdf.Close(); -} -void TestDocument8() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(600); - pPage->SetWidth(600); - - - pPage->GrSave(); - pPage->Ellipse(200, 200, 50, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount = 2; - unsigned char pColors[] = - { - 255, 0, 0, - 0, 0, 255 - }; - - unsigned char pAlphas[] ={ 255, 255 }; - CExtGrState* pExtGrState = NULL; - - double pPoints[] ={0, 1}; - CShading* pShading = oPdf.CreateAxialShading(pPage, 200, 150, 200, 250, pColors, pAlphas, pPoints, 2, pExtGrState); - pPage->DrawShading(pShading); - pPage->GrRestore(); - - pPage->GrSave(); - pPage->Ellipse(400, 200, 50, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount2 = 4; - unsigned char pColors2[] = - { - 255, 0, 0, - 0, 255, 0, - 255, 255, 255, - 0, 0, 255 - }; - unsigned char pAlphas2[] ={ 255, 255, 255, 255 }; - - double pPoints2[] ={ 0, 0.3, 0.7, 1 }; - - CShading* pShading2 = oPdf.CreateAxialShading(pPage, 400, 150, 400, 250, pColors2, pAlphas2, pPoints2, nCount2, pExtGrState); - pPage->DrawShading(pShading2); - pPage->GrRestore(); - - - pPage->GrSave(); - pPage->Ellipse(200, 400, 100, 100); - pPage->Clip(); - pPage->EndPath(); - - int nCount3 = 3; - unsigned char pColors3[] = - { - 255, 0, 0, - 255, 255, 0, - 0, 0, 255 - }; - unsigned char pAlphas3[] ={ 255, 255, 255 }; - - double pPoints3[] ={ 0, 0.5, 1 }; - - CShading* pShading3 = oPdf.CreateRadialShading(pPage, 200, 375, 20, 200, 425, 100, pColors3, pAlphas3, pPoints3, nCount3, pExtGrState); - pPage->DrawShading(pShading3); - pPage->GrRestore(); - - - oPdf.SaveToFile(L"D:/test/_pdf/Test8.pdf"); - oPdf.Close(); -} -void TestDocument9() -{ - CDocument oPdf; - oPdf.CreateNew(); - - CPage* pPage; - - pPage = oPdf.AddPage(); - - pPage->SetHeight(600); - pPage->SetWidth(600); - - CImageDict* pJpegImage = oPdf.CreateImage(); - pJpegImage->LoadJpeg(L"D:/test/_pdf/Test.jpg", 600, 400); - - CImageTilePattern* pPattern = oPdf.CreateImageTilePattern(70, 70, pJpegImage, NULL, imagetilepatterntype_InverseX); - - pPage->GrSave(); - pPage->SetPatternColorSpace(pPattern); - pPage->Ellipse(300, 300, 200, 150); - pPage->Clip(); - pPage->Fill(); - pPage->GrRestore(); - - - oPdf.SaveToFile(L"D:/test/_pdf/Test9.pdf"); - oPdf.Close(); -} - - -void ConvertFolder(std::wstring wsFolderPath) -{ - NSFonts::IApplicationFonts *pAppFonts = NSFonts::NSApplication::Create(); - pAppFonts->Initialize(); - - MetaFile::IMetaFile *pMetaFile = MetaFile::Create(pAppFonts); - - CPdfRenderer oRenderer(pAppFonts); - - pMetaFile->Close(); - - std::wstring sExt; - - double dPx2Mm = 25.4 / 96; - - std::vector vFiles = NSDirectory::GetFiles(wsFolderPath); - - for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) - { - oRenderer.NewPage(); - - std::wstring wsFilePath = wsFolderPath; - wsFilePath.append(vFiles.at(nIndex)); - if (pMetaFile->LoadFromFile(wsFilePath.c_str())) - { - double dW, dH, dX, dY; - pMetaFile->GetBounds(&dX, &dY, &dW, &dH); - - dW *= dPx2Mm; - dH *= dPx2Mm; - dX *= dPx2Mm; - dY *= dPx2Mm; - - double dAspect = dH / dW; - dW = 595.27; - dH = dAspect * dW; - - oRenderer.put_Width(dW); - oRenderer.put_Height(dH); - //pMetaFile->DrawOnRenderer(&oRenderer, -dX, -dY, dW, dH); - pMetaFile->DrawOnRenderer(&oRenderer, 0, 0, dW, dH); - pMetaFile->Close(); - } - - printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); - } - - oRenderer.SaveToFile(wsFolderPath + L"Out.pdf"); - - delete pMetaFile; - delete pAppFonts; -} - -//void TestOnlineBin() -//{ -// std::wstring wsFolderPath = L"D://Test Files//Txt//Gradient//"; -// //std::wstring wsFolderPath = L"D://Test Files//Txt//Text//"; -// std::wstring wsTempFolder = L"D://Test Files//Temp//"; -// -// CApplicationFonts oFonts; -// oFonts.Initialize(); -// -// clock_t oBeginTime = clock(); -// double dPx2Mm = 25.4 / 96; -// std::vector vFiles = GetAllFilesInFolder(wsFolderPath, L"txt"); -// for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) -// { -// std::wstring wsFilePath = wsFolderPath; -// wsFilePath.append(vFiles.at(nIndex)); -// std::wstring wsOutPath = wsFolderPath + L"Out.pdf"; -// -// CPdfRenderer oRenderer(&oFonts); -// oRenderer.SetTempFolder(wsTempFolder); -// oRenderer.OnlineWordToPdf(wsFilePath, wsOutPath); -// -// printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); -// } -// -// clock_t oEndTime = clock(); -// double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; -// printf("%f\n", dElapsedSecs); -//} -// -int _tmain(int argc, _TCHAR* argv[]) -{ - - TestDocument7(); - - - return S_OK; -} - diff --git a/PdfWriter/PdfWriterTest/PdfWriterTest.pro b/PdfWriter/PdfWriterTest/PdfWriterTest.pro deleted file mode 100644 index 1f4574f7fe..0000000000 --- a/PdfWriter/PdfWriterTest/PdfWriterTest.pro +++ /dev/null @@ -1,40 +0,0 @@ -QT -= core -QT -= gui - -TARGET = PdfWriterTest -TEMPLATE = app - -CONFIG += console -CONFIG -= app_bundle - -CORE_ROOT_DIR = $$PWD/../.. -PWD_ROOT_DIR = $$PWD -include($$CORE_ROOT_DIR/Common/base.pri) -include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -include($$CORE_ROOT_DIR/DesktopEditor/graphics/pro/freetype.pri) - -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfWriter) - -INCLUDEPATH += \ - $$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/cximage/jasper/include \ - $$CORE_ROOT_DIR/DesktopEditor/cximage/jpeg \ - $$CORE_ROOT_DIR/DesktopEditor/cximage/png \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include \ - $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include/freetype - -core_windows { -DEFINES += NOMINMAX -DEFINES -= UNICODE -DEFINES -= _UNICODE - -LIBS += -lgdi32 \ - -ladvapi32 \ - -luser32 \ - -lshell32 -} - -DEFINES += CRYPTOPP_DISABLE_ASM -LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib - -SOURCES += PdfWriterTest.cpp diff --git a/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj b/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj deleted file mode 100644 index cf1cc05af7..0000000000 --- a/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {B819B482-8822-4809-B633-09F8946D761E} - Win32Proj - PdfWriterTest - - - - Application - true - v140 - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - ..\..\DesktopEditor\freetype-2.10.4\include;..\..\DesktopEditor\freetype-2.10.4\;..\..\DesktopEditor\cximage\zlib;..\..\DesktopEditor\agg-2.4\include;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) - true - ..\..\DesktopEditor\agg-2.4\include;..\..\DesktopEditor\cximage\zlib;..\..\DesktopEditor\freetype-2.10.4\include;..\..\DesktopEditor\freetype-2.10.4\include\freetype;%(AdditionalIncludeDirectories) - 4018;4005;4267 - true - - - Console - true - - - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) - true - ..\..\DesktopEditor\freetype-2.5.2\include;..\..\DesktopEditor\agg-2.4\include;..\..\DesktopEditor\cximage\zlib;%(AdditionalIncludeDirectories) - - - Console - true - true - true - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj.filters b/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj.filters deleted file mode 100644 index e7b9fbe750..0000000000 --- a/PdfWriter/PdfWriterTest/PdfWriterTest.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/PdfWriter/PdfWriterTest/ReadMe.txt b/PdfWriter/PdfWriterTest/ReadMe.txt deleted file mode 100644 index a6fb50e6ee..0000000000 --- a/PdfWriter/PdfWriterTest/ReadMe.txt +++ /dev/null @@ -1,40 +0,0 @@ -======================================================================== - CONSOLE APPLICATION : PdfWriterTest Project Overview -======================================================================== - -AppWizard has created this PdfWriterTest application for you. - -This file contains a summary of what you will find in each of the files that -make up your PdfWriterTest application. - - -PdfWriterTest.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -PdfWriterTest.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -PdfWriterTest.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named PdfWriterTest.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/PdfWriter/PdfWriterTest/stdafx.cpp b/PdfWriter/PdfWriterTest/stdafx.cpp deleted file mode 100644 index 7c23581ef2..0000000000 --- a/PdfWriter/PdfWriterTest/stdafx.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -// stdafx.cpp : source file that includes just the standard includes -// PdfWriterTest.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/PdfWriter/PdfWriterTest/stdafx.h b/PdfWriter/PdfWriterTest/stdafx.h deleted file mode 100644 index 97e29c0a0b..0000000000 --- a/PdfWriter/PdfWriterTest/stdafx.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include - -#ifdef _DEBUG -#pragma comment(lib, "../../build/lib/win_64/debug/CryptoPPLib.lib") -#pragma comment(lib, "../../build/lib/win_64/debug/UnicodeConverter.lib") -#pragma comment(lib, "../../build/lib/win_64/debug/graphics.lib") -#pragma comment(lib, "../../build/lib/win_64/debug/kernel.lib") -#pragma comment(lib, "Ws2_32.lib") - -#pragma comment(lib, "../x64/Debug/PdfWriter.lib") - - -#else -#pragma comment(lib, "../x64/Release/PdfWriter.lib") -#pragma comment(lib, "../../SDK/lib/win_64/graphics.lib") -#pragma comment(lib, "../../ASCOfficeUtils/ASCOfficeUtilsLib/Win/x64/Release/ASCOfficeUtilsLib.lib") -#pragma comment(lib, "Ws2_32.lib") -#endif - - - -// TODO: reference additional headers your program requires here diff --git a/PdfWriter/PdfWriterTest/targetver.h b/PdfWriter/PdfWriterTest/targetver.h deleted file mode 100644 index 1200ab1d1b..0000000000 --- a/PdfWriter/PdfWriterTest/targetver.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (c) Copyright Ascensio System SIA 2010-2019 - * - * This program is a free software product. You can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License (AGPL) - * version 3 as published by the Free Software Foundation. In accordance with - * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect - * that Ascensio System SIA expressly excludes the warranty of non-infringement - * of any third-party rights. - * - * This program is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For - * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html - * - * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha - * street, Riga, Latvia, EU, LV-1050. - * - * The interactive user interfaces in modified source and object code versions - * of the Program must display Appropriate Legal Notices, as required under - * Section 5 of the GNU AGPL version 3. - * - * Pursuant to Section 7(b) of the License you must retain the original Product - * logo when distributing the program. Pursuant to Section 7(e) we decline to - * grant you any rights under trademark law for use of our trademarks. - * - * All the Product's GUI elements, including illustrations and icon sets, as - * well as technical writing content are licensed under the terms of the - * Creative Commons Attribution-ShareAlike 4.0 International. See the License - * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - * - */ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/PdfWriter/ReadMe.txt b/PdfWriter/ReadMe.txt deleted file mode 100644 index 2dfb42b8f9..0000000000 --- a/PdfWriter/ReadMe.txt +++ /dev/null @@ -1,29 +0,0 @@ -======================================================================== - STATIC LIBRARY : PdfWriter Project Overview -======================================================================== - -AppWizard has created this PdfWriter library project for you. - -No source files were created as part of your project. - - -PdfWriter.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -PdfWriter.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/PdfWriter/test/example/Editor.bin b/PdfWriter/test/example/Editor.bin deleted file mode 100644 index 9e01ef2e58..0000000000 Binary files a/PdfWriter/test/example/Editor.bin and /dev/null differ diff --git a/PdfWriter/test/example/media/image1.jpg b/PdfWriter/test/example/media/image1.jpg deleted file mode 100644 index 1b0c41adf1..0000000000 Binary files a/PdfWriter/test/example/media/image1.jpg and /dev/null differ diff --git a/PdfWriter/test/example/pdf.bin b/PdfWriter/test/example/pdf.bin deleted file mode 100644 index b2212575ea..0000000000 --- a/PdfWriter/test/example/pdf.bin +++ /dev/null @@ -1 +0,0 @@ -ysjvb0kByZ9UqgEWAP8AAGRbTHIqAODBJgBcNxwwAODBJgBcNxwwAET8LQBcTHIqAET8LQBcTHIqAODBJgBjAAEAABYAAAAAKQcAQwBhAGwAaQBiAHIAaQAq4MgQACsAAAAAUAEASADgwSYAToEsAFABAGUATHIqAE6BLABQAQBsAINkLQBOgSwAUAEAbABdwC4AToEsAFABAG8ANxwwAE6BLACCoIYBAAAAAAAAAAAAoIYBAPsVYAD9LSkAA82JAAABMlSRABZEcsQAZFsNAAAAZ/UvAFyhe0oAffUvAFy3f2EAAAAAAFzNg3gAffUvAFxh/8IAZ/UvAFxPvYYAOZlNAFyjwZ0AqI59AFy3f2EAs+pfAFzLPSUAqI59AFwfQjwAOZlNAGFjAQEAAGJ5IAAAAGRbH9E5AHy5LwBcT72GAHy5LwBcT72GALS1XQBcH9E5ALS1XQBcH9E5AHy5LwB6IAAAAIKghgEAAAAAAAAAAACghgEAMX2gAIxDYwAW////AFABAEUAAAAAAG6/BQBQAQByANM6BABuvwUAUAEAbwBHSwYAbr8FAFABAGcApmoJAG6/BQBQAQBqACQ0DABuvwUAUAEAaQDMng0Abr8FAFABAHAAp/oOAG6/BQArAQAAAFABAHcAChcSAG6/BQBQAQBvAICAFgBuvwUAUAEAZQBkrxkAbr8FAFABAHIAeaocAG6/BQBQAQBpAE3FHgBuvwUAUAEAagCXOSAAbr8FAFABAGcAsLwhAG6/BQBQAQBwAGCLJABuvwUAUAEAdwB4DykAbr8FACsAAAAAUAEAbwDueC0Abr8FAFABAGkATJgwAG6/BQBQAQBlACf0MQBuvwUAUAEAagBd5jQAbr8FAFABAHIABlE2AG6/BQBQAQBnAHphOABuvwUAUAEAcAD4KjsAbr8FAFABAGUAAAAAAFCMDQBQAQBpADbyAgBQjA0AUAEAbwAQTgQAUIwNAFABAHIAb20HAFCMDQBQAQBqAOR9CQBQjA0AUAEAcAA6PwwAUIwNAFABAGcAnlsPAFCMDQBQAQB3ABslEgBQjA0AUAEAbwCyYBYAUIwNAFABAGkAEYAZAFCMDQBQAQBlAOvbGgBQjA0AUAEAcgAizh0AUIwNAFABAGoAlt4fAFCMDQBQAQBnAD9JIQBQjA0AUAEAcAAAAAAAMlkVAFABAG8AYxwDADJZFQAWACBgAFABAGkAwjsGADJZFQArAgAAAFABAHcAnJcHADJZFQBQAQBlADPTCwAyWRUAUAEAagAQpw4AMlkVAFABAHIAuBEQADJZFQBQAQBnAE4ZEgAyWRUAUAEAcACsJBUAMlkVAFABAG8ACjAYADJZFQBQAQBpAO05GwAyWRUAFv///wArAAAAAFABAHcAyJUcADJZFQBQAQBqAF7RIAAyWRUAUAEAZQAHPCIAMlkVAFABAHIAPS4lADJZFQBQAQBnALI+JwAyWRUAUAEAbwAwCCoAMlkVAFABAGkAPH4uADJZFQBQAQB3ABbaLwAyWRUAUAEAagCtFTQAMlkVAFABAGUAVoA1ADJZFQBQAQByAIxyOAAyWRUAUAEAcAABgzoAMlkVAHlAAAAAekAAAACCoIYBAAAAAAAAAAAAoIYBAPsVYAD9LSkAgqCGAQAAAAAAAAAAAKCGAQAAAAAAAAAAAIJVfQEATqv//7JUAABVfQEA/SYrAPk+4wAeAR0AAAAAAAAAANwdeQCSvlAAFcALAAAaEABtAGUAZABpAGEALwBpAG0AYQBnAGUAMQAuAGoAcABnABwAG/9kWwAAAAAAAAAAXNwdeQAAAAAAXNwdeQCSvlAAXAAAAACSvlAAYWMAAQAAYh4AgqCGAQAAAAAAAAAAAKCGAQAAAAAAAAAAAMs= \ No newline at end of file diff --git a/PdfWriter/test/test.cpp b/PdfWriter/test/test.cpp deleted file mode 100644 index 29453fc650..0000000000 --- a/PdfWriter/test/test.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include "../PdfRenderer.h" -#include "../../PdfReader/PdfReader.h" -#include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Directory.h" -#include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" -#include "../../DesktopEditor/xmlsec/src/include/CertificateCommon.h" - -void TEST(CPdfRenderer* pRenderer) -{ - // ТЕСТОВЫЕ КОММАНДЫ - pRenderer->PathCommandStart(); - pRenderer->PathCommandMoveTo(10, 10); - pRenderer->PathCommandLineTo(20, 20); - pRenderer->PathCommandCurveTo(70, 30, 30, 20, 50, 50); - pRenderer->PathCommandClose(); - pRenderer->put_BrushColor1(0xFF0000); - pRenderer->put_PenColor(0x0000FF); - pRenderer->put_PenSize(1); - pRenderer->DrawPath(c_nStroke | c_nWindingFillMode); - pRenderer->PathCommandEnd(); -} - -void TEST2(CPdfRenderer* pRenderer) -{ - pRenderer->OnlineWordToPdf(NSFile::GetProcessDirectory() + L"/../example/pdf.bin", L""); -} - -void TEST3(CPdfRenderer* pRenderer) -{ - pRenderer->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/../example1/1/pdf.bin", L""); -} - -int main() -{ - CApplicationFontsWorker oWorker; - oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; - oWorker.m_bIsNeedThumbnails = false; - - if (!NSDirectory::Exists(oWorker.m_sDirectory)) - NSDirectory::CreateDirectory(oWorker.m_sDirectory); - - NSFonts::IApplicationFonts* pApplicationFonts = oWorker.Check(); - - CPdfRenderer pdfWriter(pApplicationFonts); - pdfWriter.SetTempFolder(NSFile::GetProcessDirectory() + L"/wtemp"); - - PdfReader::CPdfReader* pReader = new PdfReader::CPdfReader(pApplicationFonts); - pReader->SetTempDirectory(NSFile::GetProcessDirectory() + L"/rtemp"); - - // PDFDoc монополизирует доступ к файлу для чтения и не отпускает пока не деструкнится. - // Для дозаписи файл нужно прочитать в память для ридера, а доступ к файлу отдать вритеру. - std::wstring sSrcFile = NSFile::GetProcessDirectory() + L"/test.pdf"; - std::wstring sDstFile = NSFile::GetProcessDirectory() + L"/test2.pdf"; - - if (NSFile::CFileBinary::Exists(sDstFile)) - NSFile::CFileBinary::Remove(sDstFile); - - std::wstring sPassword; - bool bResult = pReader->LoadFromFile(sSrcFile); - if (!bResult) - { - sPassword = L"123456"; - pReader->LoadFromFile(sSrcFile, L"", sPassword, sPassword); - bResult = pReader->GetError() == 0; - } - - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); - - dWidth *= 25.4 / dPageDpiX; - dHeight *= 25.4 / dPageDpiY; - - ICertificate* pCertificate = NULL; - if (true) - { - std::wstring sCertificateFile = NSFile::GetProcessDirectory() + L"/test.pfx"; - std::wstring sPrivateKeyFile = L""; - std::string sCertificateFilePassword = "test"; - std::string sPrivateFilePassword = ""; - - pCertificate = NSCertificate::FromFiles(sPrivateKeyFile, sPrivateFilePassword, sCertificateFile, sCertificateFilePassword); - } - - if (false) - { - pReader->ConvertToRaster(0, NSFile::GetProcessDirectory() + L"/res.png", 4, dWidth * dPageDpiX / 25.4, dHeight * dPageDpiX / 25.4, true, pReader->GetFontManager()); - RELEASEOBJECT(pReader); - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; - } - - if (false && bResult) - { - pdfWriter.SetPassword(L"123456"); - pdfWriter.NewPage(); - pdfWriter.BeginCommand(c_nPageType); - pdfWriter.put_Width(dWidth); - pdfWriter.put_Height(dHeight); - pReader->DrawPageOnRenderer(&pdfWriter, 0, NULL); - - if (pCertificate) - { - // Подпись будет на текущей странице - pdfWriter.Sign(10, 10, 50, 50, NSFile::GetProcessDirectory() + L"/test.jpg", pCertificate); - pdfWriter.Sign(10, 70, 50, 50, NSFile::GetProcessDirectory() + L"/test.png", pCertificate); - pdfWriter.Sign(10, 130, 50, 50, NSFile::GetProcessDirectory() + L"/test.jpg", pCertificate); - pdfWriter.Sign(0, dHeight, 0, 0, L"", pCertificate); // Невидимая подпись - } - - pdfWriter.EndCommand(c_nPageType); - pdfWriter.SaveToFile(sDstFile); - - RELEASEOBJECT(pReader); - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; - } - - bool bNewDstFile = true; - if (bNewDstFile) - NSFile::CFileBinary::Copy(sSrcFile, sDstFile); - if (bResult && pReader->EditPdf(&pdfWriter, bNewDstFile ? sDstFile : sSrcFile, sPassword)) - { - if (true && pCertificate) - { - // Подпись не позволяет вносить иные изменения кроме заполнения форм, подписания и комментирования документа - if (pReader->EditPage(0)) - { - pdfWriter.Sign(10, 70, 50, 50, NSFile::GetProcessDirectory() + L"/test.png", pCertificate); - } - } - else - { - if (pReader->EditPage(0)) - { - TEST(&pdfWriter); - pdfWriter.PageRotate(90); - } - - pReader->DeletePage(1); - - if (pReader->EditPage(1)) - { - TEST3(&pdfWriter); - } - - if (pReader->EditPage(2)) - { - // При редактировании страницы нельзя изменить её пропорции - pdfWriter.put_Width(dWidth); - pdfWriter.put_Height(dHeight); - - TEST2(&pdfWriter); - } - - if (pReader->AddPage(3)) - { - // Новой странице необходимо выставить длину и ширину, иначе будут значения по умолчанию - pdfWriter.put_Width(dWidth); - pdfWriter.put_Height(dHeight); - - TEST(&pdfWriter); - } - - if (pReader->AddPage(800)) - { - // Новой странице необходимо выставить длину и ширину, иначе будут значения по умолчанию - pdfWriter.put_Width(dWidth); - pdfWriter.put_Height(dHeight); - - TEST3(&pdfWriter); - } - } - - pReader->EditClose(sPassword); - } - - RELEASEOBJECT(pReader); - RELEASEINTERFACE(pApplicationFonts); - RELEASEOBJECT(pCertificate); - return 0; -} diff --git a/PdfWriter/test/test.pro b/PdfWriter/test/test.pro deleted file mode 100644 index b3ba6209e7..0000000000 --- a/PdfWriter/test/test.pro +++ /dev/null @@ -1,19 +0,0 @@ -QT -= core -QT -= gui - -TARGET = test -TEMPLATE = app - -CONFIG += console -CONFIG -= app_bundle - -CORE_ROOT_DIR = $$PWD/../.. -PWD_ROOT_DIR = $$PWD -include($$CORE_ROOT_DIR/Common/base.pri) -include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) - -ADD_DEPENDENCY(UnicodeConverter, kernel, graphics, PdfReader, PdfWriter, ooxmlsignature) - -SOURCES += test.cpp - -DESTDIR = $$PWD/build