Skip to main content Skip to footer

What's New in GrapeCity Documents v6.2

We are pleased to announce the GrapeCity Documents v6.2 release! The latest version of GcDocs adds styles support to SpreadJS .sjs file format in GcExcel .NET, support for SpreadJS .sjs in GcExcel Java, optimized loading and saving of PDF files in GcPdf, new paint and text tools in GcImageViewer, support for OMath in GcWord, enhancements in GcPdfViewer and many more additions to the Document APIs.

Learn more about the great new features below!

Ready to Check Out the Latest? Download GrapeCity Documents now!

GrapeCity Documents for PDF (GcPdf)

Improvements in processing existing PDF documents produced by software other than GcPdf

With the new v6.2 release, GcPdf enhances the loading and saving of PDF documents and provides the following advantages:

  1. GcPdf can now load and save PDF documents that may not be strictly compliant with the PDF specification.
  2. GcPdf will now preserve any custom data embedded in PDF documents not part of the PDF specification.
  3. The average speed of loading PDF documents has been improved.

Due to changes in how GcPdf works with loaded PDFs, some of the lower-level GcPdf APIs had to be changed, which may require minor changes in your code if it uses those APIs; complete list of the affected APIs.

Work with password-protected files without specifying the password

GcPdf now allows working with password-protected files without specifying the password. After loading a password-protected file, you can now perform the following without specifying the password:

  • Read/Write properties that are not based on PDF string objects, for example:
    • You can get/set values of CheckBoxField or RadioButtonField
    • Fetch certain document’s statistics, e.g., get the count of pages, annotations, etc
    • Get or change the document metadata because, typically, the metadata is not encrypted
    • Change the value of some types of fields: CheckBoxField, RadioButtonField; the values of TextBoxField and CombTextField can be changed but with some limitations
  • You can add new objects if they can be defined without using PDF strings; for example, you can add a SquareAnnotation to a page or all pages

A new DecryptionOptions class has been introduced that represents the decryption options. You can pass it as an (optional) argument to the GcPdfDocument.Load() method when loading an encrypted PDF. In particular, you can set the DecryptionOptions.ThrowExceptionIfInvalidPassword flag to false (it is true by default) to allow loading password-protected PDFs without specifying their passwords. Another related flag is DecryptionOptions.ThrowExceptionIfUnsupportedSecurityOptions. It is also true by default. Setting it to false will enable GcPdf to load documents with unknown or broken security handlers.

The following code adds an annotation to a password-protected PDF without specifying the password:

using var fs = File.OpenRead("financial-report.pdf");
var doc = new GcPdfDocument();

doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });
// Get the size of the first page:
var page = doc.Pages[0];
var pageSize = page.Size;
// Add a square annotation:
SquareAnnotation sa = new SquareAnnotation();
sa.Page = page;
sa.Rect = new RectangleF(10, 10, pageSize.Width - 20, pageSize.Height - 20);
sa.Color = Color.Red;
doc.Save("AnnotationAdded.pdf");

Financial Report Original

Financial Report Modified

Help | Demo

New API for working with low-level PDF primitives (GrapeCity.Documents.Pdf.Spec and GrapeCity.Documents.Pdf.Wrappers namespaces)

In this release, GcPdf introduces a new API that allows developers familiar with the PDF specification to directly access the primitive PDF objects, which are the building blocks of any PDF document. These include:

  • PDF array, see GrapeCity.Documents.Pdf.Spec types PdfArray, PdfArrayObject, IPdfArray, IPdfArrayExt, and GrapeCity.Documents.Pdf.Wrappers.PdfArrayWrapper.
  • PDF bool, see GrapeCity.Documents.Pdf.Spec types PdfBool, PdfBoolObject, IPdfBool and IPdfBoolExt.
  • PDF dictionary, see GrapeCity.Documents.Pdf.Spec types PdfDict, PdfDictObject, IPdfDict, IPdfDictExt, and GrapeCity.Documents.Pdf.Wrappers.PdfDictWrapper.
  • PDF name, see GrapeCity.Documents.Pdf.Spec types PdfName, PdfNameObject, IPdfName and IPdfNameExt.
  • PDF null, see GrapeCity.Documents.Pdf.Spec types PdfNull, PdfNullObject, IPdfNull and IPdfNullExt.
  • PDF number, see GrapeCity.Documents.Pdf.Spec types PdfNumber, PdfNumberObject, IPdfNumber and IPdfNumberExt.
  • PDF reference, see GrapeCity.Documents.Pdf.Spec types PdfRef, PdfRefObject, IPdfRef and IPdfRefExt.
  • PDF stream, see GrapeCity.Documents.Pdf.Spec.PdfStreamObjectBase.
  • PDF string, see GrapeCity.Documents.Pdf.Spec types PdfString, PdfStringObject, IPdfString and IPdfStringExt.

These new APIs can be used, for instance, to access custom properties that are sometimes added by PDF producers but are not described in the PDF spec. For example, the DocumentInfo object is a PDF dictionary. The PDF specification lists the properties which can be present in this dictionary (Creator, Author, etc.). Still, in many real-life PDF files, the DocumentInfo dictionary includes a "SourceModified" property which is absent in the PDF spec. The types from the GrapeCity.Documents.Pdf.Spec namespace now allow developers to access/edit such custom items.

Please see the GcPdf reference for more information on the GrapeCity.Documents.Pdf.Spec and GrapeCity.Documents.Pdf.Wrappers namespaces.

Example: Fetch Image properties

Using the new API above, many PDFs created by image scanners (most of which consist of only one JPEG or G4 TIFF image per page) can now be processed with the images retrieved from the stream. GcPdf includes the new PdfImageInfo class, a descendant of the new PdfDictWrapper object. The class consists of a lot of methods that allow to get properties/data of underlying PDF stream objects. This addition would retrieve stream images and directly decompress or process images.

You can retrieve the following image properties:

  • Directly retrieve the stream for each image on each page (retrieved with GetImages())
  • Retrieve the compression format of the above image stream (Filter)
  • Retrieve black and white information of the above image stream (Decode or BlackIs1)
  • Retrieve information that can identify the color of the above image stream (ColorSpace or BitsPerComponent)
  • Retrieve the stream and the information of each mask (ImageMask)
  • and more

The following code retrieves image properties from a PDF stream:

using (FileStream fs = new FileStream(@"..\..\..\06-1.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
      GcPdfDocument doc = new GcPdfDocument();
      doc.Load(fs);

      GcPdfDocument doc = new GcPdfDocument();
      doc.Load(fs);
      var imgs = doc.GetImages();
      // Get the info about the first image in the PDF
      // (we know there is one image, so no index checks for example's simplicity sake):
                
      PdfImage pi = (PdfImage) imgs[0].Image; // NOTE: no cast here, PdfImageBase is the type of the Image property.
      Console.WriteLine($"PdfImage object ID: {pi.ObjID}");
      // The PdfImage is a descendant of PdfDictWrapper object it has a lot of methods
      // which allow to get properties/data of underlying PDF stream object
      using (PdfStreamInfo psi = pi.GetPdfStreamInfo())
      {
            Console.WriteLine($"    Image stream length: {psi.Stream.Length}");
            Console.WriteLine($"        ImageFilterName: {psi.ImageFilterName}");
            Console.WriteLine($"ImageFilterDecodeParams: {psi.ImageFilterDecodeParams}");
            // dump content of ImageFilterDecodeParams
            foreach (var kvp in psi.ImageFilterDecodeParams.Dict)
            {
                 Console.WriteLine($"{kvp.Key}: {kvp.Value}");
            }
            // example how to get value of BlackIs1:
            var blackIs1 = psi.ImageFilterDecodeParams.GetBool(PdfName.Std.BlackIs1, null);
            Console.WriteLine($"BlackIs1: {blackIs1}");
       }
      // dump properties of PdfImage dictionary
      Console.WriteLine();
      Console.WriteLine("Properties of PdfImage dictionary:");
      foreach (KeyValuePair<PdfName, IPdfObject> kvp in pi.PdfDict.Dict)
      {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
      } 
      var cs = pi.Get<IPdfObject>(PdfName.Std.ColorSpace);
      Console.WriteLine($"ColorSpace: {cs.GetType().Name} {cs}");
      var bpc = pi.Get<IPdfObject>(PdfName.Std.BitsPerComponent);
      Console.WriteLine($"BitsPerComponent: {bpc?.GetType().Name} {bpc}");
}

The output displays all Image properties retrieved.

Image Properties

Demo

Set Format in TextField

GcPdf now allows users to specify the date, time, number formats, and special formats to TextField in an intuitive way using new direct methods SetPercentFormat, SetNumberFormat, SetDateFormat, SetTimeFormat, SetSpecialFormat methods added to TextField, CombTextField, ComboBoxField classes. The new methods would support setting properties similar to the TextField properties in Acrobat.

New enums SpecialFormat, CurrencySymbolStyle, NumberNegativeStyle, and NumberSeparatorStyle have been added. These are used as parameters in the methods above.

The following code sets the number value on TextField using the new method and parameters:

GcPdfDocument doc = new GcPdfDocument();
var p = doc.NewPage();
var g = p.Graphics;

TextField result = new TextField();
result.Widget.Page = p;
result.Widget.Rect = new System.Drawing.RectangleF(100,100,100,100);
result.Widget.Border.Width = 1;

result.SetNumberFormat(2, Field.NumberSeparatorStyle.Dot, Field.NumberNegativeStyle.ShowParentheses, "\u20ac", Field.CurrencySymbolStyle.BeforeNoSpace);

result.Value = "12345.67f";
result.SetNumberValue(12345.67f, 2, Field.NumberSeparatorStyle.Dot, Field.NumberNegativeStyle.None, "$", Field.CurrencySymbolStyle.BeforeNoSpace);

p.Doc.AcroForm.Fields.Add(result);

doc.Save("NumberTextField.pdf");

Help | Demo

GrapeCity Documents PDF Viewer (GcPdfViewer)

Document List Panel Enhancements

GcPdfViewer now supports enhancing the Document List panel using custom HTML markup. GcPdfViewer provides name, path, title, and previewContent properties in DocumentListItem type, allowing the user to specify custom HTML markup to represent the documents' list. The following is a brief description of the properties:

  • Name - Display the name of the Document list item
  • Path - Absolute or relative URL to a PDF document
  • Title - Item tooltip
  • PreviewContent - the HTML content to be used as the preview content in the document list

The existing client-side properties and methods - documentListUrl option and addDocumentListPanel and loadDocumentList methods have been enhanced to accept DocumentListItem as a parameter to specify a predefined list of document list items.

The following code sets properties to the first tile, ‘Finance’, in the Document list panel:

const options = { 
		workerSrc: "/documents-api-pdfviewer/demos/product-bundles/build/gcpdfviewer.worker.js",
		supportApi: {
			apiUrl: window.top.SUPPORTAPI_URL,
			token: window.top.SUPPORTAPI_TOKEN,
			webSocketUrl: false
		},
		restoreViewStateOnLoad: false
	};
	const baseAssetsPath = "/documents-api-pdfviewer/demos/product-bundles/assets/";
	options.documentListUrl = [ 
        { 
            path: baseAssetsPath + "pdf/documents-list/financial-report.pdf",
            title: "Finance",
			previewContent: renderPreviewCard("Finance", 
							"View Financial, budget reports and collaborate over them.", 
							baseAssetsPath + "images/preview/svg/Finance.svg")
        },
];
 

Documents List Panel

For the complete code, please have a look at this demo.

Help | Demo

Keyboard Shortcuts

GcPdfViewer supports several keyboard shortcuts that can make working with PDF documents in the viewer more efficient. GcPdfViewer also supports redefining, disabling, overriding, and removing the default keyboard shortcuts, as well as binding the default keyboard shortcuts to other keys and creating custom keyboard shortcuts via API using the shortcuts option of the ViewerOptions class.

GcPdfViewer also supports redefining, disabling, overriding, and removing the default keyboard shortcuts, as well as binding the default keyboard shortcuts to other keys and creating custom keyboard shortcuts via API using the shortcuts option of the ViewerOptions class.

The following code helps to bind the holdToPan action to the 'P' key:

// Bind the "P" shortcut to the holdToPan action and leave the Ctrl+P shortcut for the "print" action.
viewer.options.shortcuts["P"] = [{ ctrl: true, tool: "print" }, { tool: "holdToPan" }];

Look at the full list of keyboard shortcuts supported in the Help link below.

Help

GrapeCity Documents for Excel (GcExcel)

This new release includes updates to the existing GcExcel .NET Excel and Java library and API tools and additions to our Javascript-based GrapeCity Documents Data Viewer. Have a look at the details of the release below:

  • SpreadJS .sjs file format support in GcExcel Java
  • Styles support in SpreadJS .sjs file format
  • Support for double-sided printing
  • Alignment options for Shape Text
  • Set Vertical text direction in a Shape and Chart

GrapeCity Documents Data Viewer

  • Load SpreadJS .sjs files
  • Keyboard shortcuts
  • Numerical Count aggregation in the status bar

View the full blog for release details.

GrapeCity Documents for Word (GcWord)

Support for Office Math functions and conversion to MathML

GcWord now supports creating and editing Office Math content in Word documents. The OMath support in GcWord includes complete API to work with mathematical symbols, formulas, and equations widely used in scientific, mathematical, and general-purpose Word documents. Following are key highlights of the new API introduced with OMath support -

  • The two main classes used to represent Office Math content in GcWord are OMathParagraph and OMath. OMathParagraph represents a paragraph with Office Math content, while OMath represents an inline Office Math zone and can be included in an OMathParagraph or a regular paragraph.
  • Specialized classes (such as OMathFunction, OMathEquationArray, OMathRadical, etc.) are provided to represent the various math structures living inside an OMath zone. These classes are derived from the common abstract OMathStruct base.
  • Access to Office Math content is provided by the new RangeBase properties: OMathParagraphs, OMaths, OMathStructs, OMathElements, and OMathMatrixRows.
  • To easily add built-in equations supported by MS Word, convenient Add/Insert methods are provided on RangeBase, OMathParagraph, OMath, and OMathElement classes accepting an OMathBuiltInEquationenum value identifying the desired equation.
  • A utility MathMLConverter class is included to allow for easy conversion between GcWord OMath content and MathML.

For the full details on OMath support in GcWord, please see the docs.

The following code adds an equation to a Word file with OMath class and its functions:

var sampleDoc = new GcWordDocument();
var om = sampleDoc.Body.AddParagraph().AddOMathParagraph().AddOMath();

om.AddRun("Γ").Font.Italic = false;
om.AddDelimiter(new string[] { "z" });
om.AddRun("=");

var nary = om.AddNary("", "0", "∞", "∫");
nary.Base.AddSuperscript("t", "z-1");
nary.Base.AddSuperscript("e", "-t");
nary.Base.AddRun("dt");
om.AddRun("=");

var frac = om.AddFraction();
var superscript = frac.Numerator.AddSuperscript("e", "-");
superscript.Superscript.AddRun("γ").Font.Bidi = true; //w:cs was used
superscript.Superscript.AddRun("z");
frac.Denominator.AddRun("z");

nary = om.AddNary("", "k=1", "∞", "∏");
superscript = nary.Base.AddSuperscript("", "-1");
var delimiter = superscript.Base.AddDelimiter();
var item = delimiter.Items.Add();
item.AddRun("1+");
item.AddFraction("z", "k", null);

superscript = nary.Base.AddSuperscript("e", "z");
superscript.Superscript.AddRun("/").OMathFormat.IsLiteral = true; //m:lit used.
superscript.Superscript.AddRun("k");

om.AddRun(",  γ≈0.577216");

sampleDoc.Save("MathEquation.docx");

OMath

Help | Demo

New helper ‘Add<content object>(..)’ methods to add content to Word documents.

Till now, it was possible to add content objects in Word documents in one or more ways. For example, it was possible to add ‘runs’ of a paragraph either by paragraph creation constructor call - doc.Body.Paragraphs.Add(“text“) or using a paragraph.GetRange().Runs.Add(…) and create a paragraph before this call. However, with the v6.2 release, creating runs directly on paragraph elements will now be possible using the new ‘AddRun(..)’ method.

Similarly, GcWord adds ‘Add<content object>(..)’ methods to each kind of content in Word documents so that they can be directly added to their parent object, making the code shorter and more efficient. Each of these objects can now be directly added to different sections or content objects in Word documents using new Helper methods:

  • Table
  • Paragraph
  • ContentControl
  • SimpleField
  • Hyperlink
  • BidirectionalOverride
  • OMathParagraph
  • OMath
  • Run
  • Footnote
  • Endnote
  • ComplexField
  • GroupShape
  • Shape
  • Picture
  • InkShape

Have a look at the following code that adds a paragraph run to a paragraph with the new method ‘AddRun(..)’:

GcWordDocument doc = new GcWordDocument();
            
// add paragraph with default formatted text
var p = doc.Body.AddParagraph("text1");
            
// add another text into the paragraph formatted with "Heading1" style
// previously code should look like: p.GetRange().Runs.Add("text2", doc.Styles[BuiltInStyleId.Heading1]);
// now the code is shorter and more clear what content can be added into the object
 p.AddRun("text2", doc.Styles[BuiltInStyleId.Heading1]);

Look at the following resources to see a complete list of newly supported helper methods.

Help | Demo - Built-in Table Styles | Demo - Nested Table Helpers | Demo - Hyperlink Fields Helpers | Demo - Content Controls Helpers

Escape template tags in GcWord Templates

If you want to prevent a particular data template tag from being processed by the data template engine (i.e., quote it literally in your document after template expansion), insert a backslash before the tag’s opening double curly brace.

The following code snippet shows how to escape tags that would otherwise print the data values:

var dsPoint = new string[] { "2.2", "3.3", "4.4" };
var doc = new GcWordDocument();
doc.Body.Paragraphs.Add(@"\{{dsPoint.value}:todouble():format(0.#%)}");
doc.DataTemplate.DataSources.Add("dsPoint", dsPoint);
doc.DataTemplate.Process(CultureInfo.GetCultureInfo("en-US"));
doc.Save("DocumentWithSingleSlash.docx");

Escape Template Tags

Additionally, to use backslashes before a template tag without disabling the template processing, GcWord allows you to insert two or more backslashes, depending on how many are needed. It will remove one backslash from prepending backslashes when processing template tags.

The following code adds a double-slash to the template syntax. This would add a single backslash in the resultant Word file when the template syntax is processed:

var dsPoint = new string[] { "2.2", "3.3", "4.4" };

var doc = new GcWordDocument();
doc.Body.Paragraphs.Add(@"\\{{dsPoint.value}:todouble():format(0.#%)}");
doc.DataTemplate.DataSources.Add("dsPoint", dsPoint);
doc.DataTemplate.Process(CultureInfo.GetCultureInfo("en-US"));
doc.Save("DocumentWithDoubleSlash.docx");

Adds Double Slash to Template Syntax

GrapeCity Documents Image Viewer (GcImageViewer)

New Paint and Text Tools

Now draw freehand content or add text effortlessly over images to add additional information to your images. GcImageViewer adds new Paint and Text tools to draw or add text over images. The tools have been added to the second toolbar of the viewer.

Have a look at the details below.

Paint Tools

Paint Tools

Paint options

  • Pencil - draw freehand strokes without anti-aliasing
  • Brush - draw freehand brush strokes with smooth edges and anti-aliasing
  • Clone Stamp - copy pixels from one area to another using a seamless painting technique
  • Eraser - erase part of the image

Settings

  • Size settings button - the Pen/Brush/Eraser/Clone Stamp tools size hardness and opacity
  • Brush color - the Pen/Brush tools painting color
  • “Use original image” toggle - use the original image, combined with your recent edits as a background source for new edits

Other options

  • Undo/Redo buttons - revert or restore changes with a single click.
  • Apply changes button - save and apply the edited adjustments to the image.
  • Cancel changes button - discard the modifications and revert back to the original image.

Text Tools

Text Tools

The text tools toolbar contains the “Text” tool and related settings such as Font Size, Font Name, Text Color, and Bold and Italic font styles.

You can also perform the following operations with the text tools:

  • Press the Text tool and click the desired position to start the text input
  • Press Ctrl+Enter to finish editing the text.
  • Move the selected text or add another one by using the Text tool button again
  • Change the properties for multiple selected objects at once
  • Double-click click text object to activate the text editor

Help Paint Tools | Help Text Tools | Demo Paint Tools | Demo Text Tools

New Image Filters - Vibrance and Saturation

Image filters can help you enhance your photos. Whether you need marketing images for your business, analyze image details, or enhance images, various image filters are supported in GcPdfViewer. In the v6.2 release, GcPdfViewer adds two new widely used filters - Vibrance and Saturation. The two filters are added to the Image Filters panel, along with other filters. Also added is the ability to set the ‘Intensity’ of the filter by adjusting the slider, the ‘Preview’ button to preview the image filter temporarily, and the ‘Apply/Cancel' buttons to apply or cancel applying the image filter.

Vibrance

Saturation

Help | Demo

GrapeCity Documents for PDF and Imaging

Helper classes for drawing layouts to GcGraphics

In the last release, GcPdf, GcImaging added a new layout engine, introducing LayoutRect and other related classes in the GrapeCity.Documents.Layout namespace to implement a layout model based on constraints and a flat hierarchy of elements where multiple elements are drawn on a PDF page or images without calculating the positions of each element relative to the other. The new layout engine thereby adds flexibility to position and size the elements enabling the drawing of complex graphic layouts on PDFs and images.

In the v6.2 release, GcPdf, and GcImaging add additional classes - SurfaceLayer, ViewSpace, and Visual classes in GrapeCity.Documents.Layout.Composition namespace is a medium between the layout engine and the drawing surface, making drawing even more complex graphics, text, and images easier. Here is a brief about the functions of these classes:

  • Surface is the main class in the Composition engine. It contains a LayoutHost (the layout engine's root object) and one or several views (layers). Layers consist of visuals (drawable elements) and nested layers. The Rendermethod of the Surface class calls the PerformLayout method of LayoutHost class to calculate the surface layout. Then it draws all the layers, including nested ones, from the bottom to the top layer on the specified GcGraphics object.
  • Layers are of two types: Layer and View class objects (derived from Layer objects). The View object encapsulates the LayoutView object, representing a separate coordinate system with its transformation matrix. The Layerobject functions as a lightweight View with its own list of visuals, nested layers, and possible clipping area.
  • Layers contain Visuals and Spaces. The Space object represents a LayoutRect that may affect the layout of other elements but is never drawn itself. The Visual class derives from the Space class. The visual class represents an element that will be drawn on the target GcGraphics.

Furthermore, these classes enable you to customize the z-order and clipping of the drawn graphics. For example, it is possible to compose a PDF page from a number of visuals, then further adjust those visuals before rendering to the document. Some visuals or layers can be hidden. Others moved in z-order, and so on.

Additional API is also introduced to achieve various layouts. To read about the new classes and functions of each, refer to the documentation.

To learn more about the typical steps to create a layout, refer to this content: Documents for Imaging | Composition

Here is an example of a complex layout that can be achieved using these APIs.

Complex Graphics

See this online demo for the complete source code that is used to produce this layout: Documents for PDF | Text Flow (C#)

Help | Demo

What do you think of the new release? Drop your comments below.

Ready to Check Out the Latest? Download GrapeCity Documents now!

comments powered by Disqus