LangLayers.cs
//
// This code is part of GrapeCity Documents for PDF samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Layers;
using GrapeCity.Documents.Pdf.Annotations;
using GrapeCity.Documents.Pdf.Graphics;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Drawing;

namespace GcPdfWeb.Samples
{
    // This sample creates a PDF with a GrapeCity Document API data sheet.
    // PDF layers (optional content) are used to provide the data sheet
    // in several languages in the same one page PDF. A supporting viewer
    // (e.g. Adobe Reader) can be used to turn different languages on or off.
    public class LangLayers
    {
        // Layer names correspond to included languages:
        const string c_lyrEN = "English";
        const string c_lyrRU = "Russian";

        public void CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();

            // Add layers for different languages,
            // set default visibility to false for all languages except one:
            doc.OptionalContent.AddLayer(c_lyrEN);
            doc.OptionalContent.AddLayer(c_lyrRU);
            doc.OptionalContent.SetLayerDefaultState(c_lyrRU, false);

            var page = doc.Pages.Add();
            page.Landscape = true;
            var g = page.Graphics;

            // Background image:
            var picBack = Image.FromFile(Path.Combine("Resources", "ImagesBis", "2020-website-gcdocs-headers_tall.png"));
            var rc = page.Bounds;
            rc.Height *= 0.5f;
            g.DrawImage(picBack, rc, null, ImageAlign.StretchImage);

            // Image with some screenshots:
            var picScreens = Image.FromFile(Path.Combine("Resources", "ImagesBis", "docs-main-02.png"));
            var picScreensSize = new SizeF(picScreens.Width / 2, picScreens.Height / 2);
            var rcScreen = new RectangleF(
                page.Bounds.Width - picScreensSize.Width - 8,
                8,
                picScreensSize.Width,
                picScreensSize.Height);
            g.DrawImage(picScreens, rcScreen, null, ImageAlign.StretchImage);

            // Text formats:
            var fReg = Font.FromFile(Path.Combine("Resources", "Fonts", "OpenSans-Regular.ttf"));
            var fBold = Font.FromFile(Path.Combine("Resources", "Fonts", "OpenSans-Bold.ttf"));
            var tfNorm = new TextFormat() { Font = fReg, FontSize = 9, ForeColor = Color.White };
            var tfCap = new TextFormat(tfNorm) { FontSize = tfNorm.FontSize * 1.6f };
            var tfBlack = new TextFormat(tfNorm) { ForeColor = Color.FromArgb(32, 32, 32) };
            var tfHdr = new TextFormat(tfBlack) { Font = fBold };

            // Draw English texts:
            var ip = new PointF(36, 24);
            var ip1 = ip;
            ip = DrawText1(c_lyrEN, doc, g, ip1, tfNorm, tfCap);
            ip.Y += 82;
            var ip2 = ip;
            DrawText2(c_lyrEN, doc, g, ip2, tfHdr, tfBlack);

            // Draw Russian texts:
            DrawText1(c_lyrRU, doc, g, ip1, tfNorm, tfCap);
            DrawText2(c_lyrRU, doc, g, ip2, tfHdr, tfBlack);

            // Save the PDF:
            doc.Save(stream);
        }

        class Texts
        {
            public string Caption { get; set; }
            public string SubCap { get; set; }
            public string Bullet1 { get; set; }
            public string Bullet2 { get; set; }
            public string Bullet3 { get; set; }
            public string Bullet4 { get; set; }
            public string Bullet5 { get; set; }
            public string Bullet6 { get; set; }
            public string Pt1Hdr { get; set; }
            public string Pt1Txt { get; set; }
            public string Pt2Hdr { get; set; }
            public string Pt2Txt { get; set; }
            public string Pt3Hdr { get; set; }
            public string Pt3Txt { get; set; }
            public string Pt4Hdr { get; set; }
            public string Pt4Txt { get; set; }
            public string Pt5Hdr { get; set; }
            public string Pt5Txt { get; set; }
            public string Pt6Hdr { get; set; }
            public string Pt6Txt { get; set; }
        }

        static Dictionary<string, Texts> _texts = new Dictionary<string, Texts>()
        {
            { "English", new Texts() {
                Caption = "Fast, Efficient Document APIs for .NET 5 and Java Applications",
                SubCap = "Take total control of your documents with ultra-fast, low-footprint APIs for enterprise apps.",
                Bullet1 = "Generate, load, edit, save XLSX spreadsheets, PDF, Images, and DOCX files using C# .NET, VB.NET, or Java",
                Bullet2 = "View, edit, print, fill and submit documents in JavaScript PDF Viewer and PDF Editor",
                Bullet3 = "Compatible on Windows, macOS, and Linux",
                Bullet4 = "No dependencies on Excel, Word, or Acrobat",
                Bullet5 = "Deploy to a variety of cloud-based services, including Azure, AWS, and AWS Lambda",
                Bullet6 = "Product available individually or as a bundle",
                Pt1Hdr = "High-Speed, Small Footprint, No Dependencies",
                Pt1Txt = "The .NET 5 Document API is designed to generate large, optimized documents fast – while remaining lightweight and extensible, giving you greater flexibility, and creativity in developing your applications.",
                Pt2Hdr = "Full .NET Support for Windows, Linux, and Mac",
                Pt2Txt = "Develop for any .NET platform or major operating system with a single code base. Use in your apps for .NET, C#, VB.NET .NET Framework, Mono, Xamarin.iOS, and Xamarin.Android.",
                Pt3Hdr = "Comprehensive, Highly Programmable",
                Pt3Txt = "Do more with your Excel spreadsheets, Word documents, PDFs, and images with our feature-rich APIs. Create, load, edit, save, and convert your business documents with intuitive tools.",
                Pt4Hdr = "Zero Dependencies",
                Pt4Txt = "Generate and edit digital documents in your applications without any dependencies on Adobe Acrobat, Microsoft Word, or Excel. Build your documents even faster with zero dependencies.",
                Pt5Hdr = "Deploy Apps to the Cloud",
                Pt5Txt = "Be everywhere with cloud-based deployment using NuGet and GrapeCity Documents. You can now deploy to Azure, AWS, and AWS Lambda in a few short steps.",
                Pt6Hdr = "Supports Hundreds of Features",
                Pt6Txt = "Generate full-featured documents and nearly lossless imports! These APIs complete your toolkit through high-performance features, including Excel pivot tables, PDF digital signatures, and Word text comments.",
            }},
            { "Russian", new Texts() {
                Caption = "Document API - для быстрой и эффективной работы с офисными документами под .NET 5 и Java",
                SubCap = "Полный контроль над офисным документооборотом с помощью сверх-быстрых, нетребовательных к памяти библиотек Document API",
                Bullet1 = "Создание, загрузка, редактирование и сохранение файлов XLSX, PDF, DOCX и изображений из кода на C#, VB.NET и Java",
                Bullet2 = "Просмотр, редактирование, печать, заполнение и пересылка PDF файлов с помощью просмотрщика и редактора на чистом JavaScript",
                Bullet3 = "Полная совместимость с операционными системами Windows, macOS и Linux",
                Bullet4 = "Отсутствие зависимостей от Excel, Word и Acrobat",
                Bullet5 = "Развертывание на Azure, AWS и AWS Lambda",
                Bullet6 = "Продукты доступны индивидуально или составе единой студии",
                Pt1Hdr = "Быстрые, маленькие библиотеки без внешних зависимостей",
                Pt1Txt = "Наши API созданы для генерации сложных оптимизированных документов с большой скоростью и малыми требованиями к памяти, для лёгкой и удобной разработки аппликаций.",
                Pt2Hdr = "Полная поддержка .NET под Windows, Linux и macOS",
                Pt2Txt = "Единый код для всех платформ и операционных систем, поддержка разработки на C# и VB.NET под .NET 5, .NET Framework, Mono, Xamarin.iOS и Xamarin.Android.",
                Pt3Hdr = "Функциональность и программируемость",
                Pt3Txt = "Полная поддержка функциональности MS Excel, MS Word и PDF документов и изображений. Создание, загрузка, редактирование, сохранение и конвертация документов.",
                Pt4Hdr = "Отсутствие внешних зависимостей",
                Pt4Txt = "Быстрое и эффективное создание и редактирование электронных документов без зависимостей от Adobe Acrobat, Microsoft Word и Excel.",
                Pt5Hdr = "Разворачивание аппликаций в \"облаке\"",
                Pt5Txt = "Простое и удобное разворачивание аппликаций в Azure, AWS и AWS Lambda. Все зависимости от GrapeCity Documents могут разрешаться через NuGet.",
                Pt6Hdr = "Широкая поддержка возможностей форматов",
                Pt6Txt = "Доступ практически ко всем возможностям, заложенным в спецификациях форматов документов - сводные таблицы Excel, множественные цифровые подписи PDF, комментарии и многое другое.",
            }}
        };


        static PointF DrawText1(string lang, GcPdfDocument doc, GcPdfGraphics g, PointF ip, TextFormat tf, TextFormat tfCap)
        {
            var txts = _texts[lang];
            g.BeginLayer(lang);

            var tl = g.CreateTextLayout();
            tl.MaxWidth = 72 * 5;

            tl.AppendLine(txts.Caption, tfCap);
            tl.AppendLine(tf);
            tl.AppendLine(txts.SubCap, tf);
            tl.AppendLine(tf);
            g.DrawTextLayout(tl, ip);

            // Bullet list:
            ip.Y += tl.ContentHeight;
            tl.Clear();
            const string bullet = "\x2022\x2003";
            tl.FirstLineIndent = -g.MeasureString(bullet, tf).Width;
            tl.ParagraphSpacing += 4;

            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet1, tf);
            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet2, tf);
            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet3, tf);
            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet4, tf);
            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet5, tf);
            tl.Append(bullet, tf);
            tl.AppendLine(txts.Bullet6, tf);
            g.DrawTextLayout(tl, ip);

            g.EndLayer();

            ip.Y += tl.ContentHeight;
            return ip;
        }

        static void DrawText2(string lang, GcPdfDocument doc, GcPdfGraphics g, PointF ip, TextFormat tfHdr, TextFormat tfBlack)
        {
            var picIcons = Image.FromFile(Path.Combine("Resources", "ImagesBis", "2020-icon-sprites-dx.png"));
            var iconSize = new SizeF(picIcons.Width / 12, picIcons.Height / 2);

            var tl = g.CreateTextLayout();
            tl.FirstLineIndent = 0;
            tl.MaxWidth = (doc.Pages[0].Bounds.Width - ip.X * 2 - 36) / 3;
            var ip1 = ip;
            var txts = _texts[lang];

            drawItem(ip, 0, txts.Pt1Hdr, txts.Pt1Txt);
            ip.X += tl.MaxWidth.Value + 18;
            ip1.Y = Math.Max(ip1.Y, ip.Y + tl.ContentHeight);
            drawItem(ip, 1, txts.Pt2Hdr, txts.Pt2Txt);
            ip.X += tl.MaxWidth.Value + 18;
            ip1.Y = Math.Max(ip1.Y, ip.Y + tl.ContentHeight);
            drawItem(ip, 2, txts.Pt3Hdr, txts.Pt3Txt);

            ip1.Y = Math.Max(ip1.Y, ip.Y + tl.ContentHeight);
            ip1.Y += iconSize.Height + 18;
            ip = ip1;
            drawItem(ip, 3, txts.Pt4Hdr, txts.Pt4Txt);
            ip.X += tl.MaxWidth.Value + 18;
            drawItem(ip, 4, txts.Pt5Hdr, txts.Pt5Txt);
            ip.X += tl.MaxWidth.Value + 18;
            drawItem(ip, 5, txts.Pt6Hdr, txts.Pt6Txt);

            void drawItem(PointF p, int imgIdx, string header, string text)
            {
                if (lang == c_lyrEN)
                {
                    // Draw icons just once:
                    var xImg = p.X + tl.MaxWidth.Value / 2 - iconSize.Width / 2;
                    var xImgAll = xImg - imgIdx * iconSize.Width;
                    var imgRc = new RectangleF(
                        xImgAll,
                        p.Y,
                        iconSize.Width * 6,
                        iconSize.Height);
                    var rcClip = new RectangleF(new PointF(xImg, p.Y), iconSize);
                    rcClip.Width -= 1;
                    g.DrawImage(picIcons, imgRc, rcClip, ImageAlign.StretchImage);
                }
                tl.Clear();
                tl.AppendLine(header, tfHdr);
                tl.AppendLine(text, tfBlack);
                g.BeginLayer(lang);
                g.DrawTextLayout(tl, new PointF(p.X, p.Y + iconSize.Height + 8));
                g.EndLayer();
            }
        }
    }
}