Робота з перетвореннями в PostScript | C++

Перетворення вмісту в документі PS

У цій статті ми розглянемо, як виконати різні перетворення: переклад, масштабування, обертання та зсув прямокутного шляху, доданого до PsDocument.

Ми розбиваємо один фрагмент коду на кілька частин коду: початок, кінець і кожну трансформацію окремо. Перетворення в PostScript завжди виконується в графічному стані, який пов’язаний операторами “gsave” і “grestore”. Тому в нашому PsDocument є методи “WriteGraphicsSave()” і “WriteGraphicsRestore()”. Між цими методами ми можемо додавати будь-який вміст, у тому числі стан вкладеної графіки, і робити будь-які перетворення чи вирізання. Ці перетворення не вплинуть на зовнішні графічні стани, але вплинуть на вкладені.

Якщо ми робимо перетворення без методів “WriteGraphicsSave()” і “WriteGraphicsRestore()”, ми робимо це в графічному стані верхнього рівня, і весь вміст, який є в PsDocument, буде піддано цьому перетворенню .

Алгоритм налаштування будь-якої трансформації вмісту документа з нуля включає наступні кроки:

  1. Створіть вихідний потік для отриманого файлу PS.
  2. Створіть PsSaveOptions.
  3. Створіть PsDocument із уже створеним вихідним потоком і параметрами збереження.
  4. Збережіть стан графіки. Отже, ми створили новий графічний стан, попередній графічний стан було поміщено в стек графічних станів.
  5. Додайте необхідну трансформацію: перенесення, масштаб, обертання, зсув або будь-яку їх комбінацію. У нашому коді ми показуємо вплив кожного компонента трансформації окремо та по 3 компоненти одночасно в кінці.
  6. Додайте необхідний вміст, який потрібно трансформувати. У нашому випадку ми створили прямокутник GraphicsPath з прямокутника, а потім заповнили його. Ми створили один прямокутник до будь-яких перетворень і просто заповнюємо його після кожного перетворення в поточному стані графіки.
  7. Відновіть стан графіки, щоб повернутися до попереднього, де застосовані трансформації не впливають. У нашому випадку це графічний стан верхнього рівня.

У цьому фрагменті коду ми створюємо PsDocument із вихідного потоку та PsSaveOptions, перетворюємо стан графіки верхнього рівня в точки 100,100, щоб змістити перший прямокутник, і, нарешті, створюємо перший прямокутник GraphicsPath з прямокутника.

 1    // The path to the documents directory.
 2    System::String dataDir = RunExamples::GetDataDir_WorkingWithCanvas();
 3    
 4    //Create output stream for PostScript document
 5    {
 6        System::SharedPtr<System::IO::Stream> outPsStream = System::MakeObject<System::IO::FileStream>(dataDir + u"Transformations_outPS.ps", System::IO::FileMode::Create);
 7        // Clearing resources under 'using' statement
 8        System::Details::DisposeGuard<1> __dispose_guard_0({ outPsStream});
 9        // ------------------------------------------
10        
11        try
12        {
13            //Create save options with default values
14            System::SharedPtr<PsSaveOptions> options = System::MakeObject<PsSaveOptions>();
15            
16            // Create new 1-paged PS Document
17            System::SharedPtr<PsDocument> document = System::MakeObject<PsDocument>(outPsStream, options, false);
18            
19            document->Translate(100.0f, 100.0f);
20            
21            //Create graphics path from the rectangle
22            System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
23            path->AddRectangle(System::Drawing::RectangleF(0.0f, 0.0f, 150.0f, 100.0f));

Тут ми встановлюємо помаранчевий колір як поточну фарбу для стану графіки верхнього рівня та заповнюємо цей прямокутник.

Отриманий PS-файл демонструватиме першу фігуру, яка знаходиться у графічному стані верхнього рівня та не зазнає жодних трансформацій.

1            ////////////////////////////////////// No transformations ///////////////////////////////////////////////////////////////
2            //Set paint in graphics state on upper level
3            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Orange()));
4            
5            //Fill the first rectangle that is on on upper level graphics state and that is without any transformations.
6            document->Fill(path);
7            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Тепер ми створюємо новий графічний стан, який буде транслюватися на 250 точок за віссю X відносно графічного стану верхнього рівня, і додаємо до цього нового графічного стану той самий прямокутний контур, пофарбований синім кольором. Зрештою, ми виходимо з поточного стану графіки на графічний стан верхнього рівня.

 1            ////////////////////////////////////// Translation //////////////////////////////////////////////////////////////////////
 2            
 3            //Save graphics state in order to return back to this state after transformation
 4            document->WriteGraphicsSave();
 5            
 6            //Displace current graphics state on 250 to the right. So we add translation component to the current transformation.
 7            document->Translate(250.0f, 0.0f);
 8            
 9            //Set paint in the current graphics state
10            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Blue()));
11            
12            //Fill the second rectangle in the current graphics state (has translation transformation)
13            document->Fill(path);
14            
15            //Restore graphics state to the previus (upper) level
16            document->WriteGraphicsRestore();
17            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Перекладіть стан графіки верхнього рівня, щоб поставити наступні прямокутники.

1            //Displace on 200 to the bottom.
2            document->Translate(0.0f, 200.0f);

Тут ми створюємо графічний стан, який буде масштабовано 0,5 за віссю X і 0,75 за віссю Y, і додаємо до цього нового графічного стану той самий прямокутний контур, пофарбований червоним кольором. Зрештою, ми виходимо з поточного стану графіки на графічний стан верхнього рівня.

 1            ////////////////////////////////////// Scaling //////////////////////////////////////////////////////////////////////////
 2            //Save graphics state in order to return back to this state after transformation
 3            document->WriteGraphicsSave();
 4            
 5            //Scale current graphics state on 0.5 in X axis and on 0.75f in Y axis. So we add scale component to the current transformation.
 6            document->Scale(0.5f, 0.75f);
 7            
 8            //Set paint in the current graphics state
 9            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Red()));
10            
11            //Fill the third rectangle in the current graphics state (has scale transformation)
12            document->Fill(path);
13            
14            //Restore graphics state to the previus (upper) level
15            document->WriteGraphicsRestore();
16            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Перекладіть стан графіки верхнього рівня, щоб розмістити наступні прямокутники.

1            //Displace upper level graphics state on 250 to the right.
2            document->Translate(250.0f, 0.0f);

Потім ми створюємо новий графічний стан, який буде повернуто на 45 градусів за годинниковою стрілкою відносно графічного стану верхнього рівня, і додаємо до цього нового графічного стану той самий прямокутний контур, пофарбований зеленим кольором. Зрештою, ми виходимо з поточного стану графіки на графічний стан верхнього рівня.

 1            ////////////////////////////////////// Rotation //////////////////////////////////////////////////////////////////////
 2            //Save graphics state in order to return back to this state after transformation
 3            document->WriteGraphicsSave();
 4            
 5            //Rotate current graphics state on 45 degrees around origin of current graphics state (350, 300). So we add rotation component to the current transformation.
 6            document->Rotate(45);
 7            
 8            //Set paint in the current graphics state
 9            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Green()));
10            
11            //Fill the fourth rectangle in the current graphics state (has rotation transformation)
12            document->Fill(path);
13            
14            //Restore graphics state to the previus (upper) level
15            document->WriteGraphicsRestore();
16            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Перекладіть графічний стан верхнього рівня, щоб розмістити наступні прямокутники на порожньому місці сторінки.

1            //Returns upper level graphics state back to the left and displace on 200 to the bottom.
2            document->Translate(-250.0f, 200.0f);

Потім ми створюємо новий графічний стан, який буде зрізано, і додаємо до цього нового графічного стану той самий прямокутний контур, пофарбований рожевим кольором. Зрештою, ми виходимо з поточного стану графіки на графічний стан верхнього рівня.

 1            ////////////////////////////////////// Shearing //////////////////////////////////////////////////////////////////////
 2            //Save graphics state in order to return back to this state after transformation
 3            document->WriteGraphicsSave();
 4            
 5            //Shear current graphics state. So we add shear component to the current transformation.
 6            document->Shear(0.1f, 0.2f);
 7            
 8            //Set paint in the current graphics state
 9            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Pink()));
10            
11            //Fill the fifth rectangle in the current graphics state (has shear transformation)
12            document->Fill(path);
13            
14            //Restore graphics state to the previus (upper) level
15            document->WriteGraphicsRestore();
16            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Перекладіть графічний стан верхнього рівня, щоб розмістити наступні прямокутники на порожньому місці сторінки.

1            //Displace upper level graphics state on 250 to the right.
2            document->Translate(250.0f, 0.0f);

Тепер ми створюємо останній графічний стан, який буде піддано складній трансформації, що містить компоненти трансляції, масштабування та обертання, і додаємо до цього нового графічного стану той самий прямокутний шлях, пофарбований Аквамариновим кольором. Зрештою, ми виходимо з поточного стану графіки на графічний стан верхнього рівня.

 1            ////////////////////////////////////// Complex transformation ////////////////////////////////////////////////////////
 2            //Save graphics state in order to return back to this state after transformation
 3            document->WriteGraphicsSave();
 4            
 5            //Transform current graphics state with complex transformation. So we add translation, scale and rotation components to the current transformation.
 6            document->Transform(System::MakeObject<System::Drawing::Drawing2D::Matrix>(1.2f, -0.965925f, 0.258819f, 1.5f, 0.f, 50.0f));
 7            
 8            //Set paint in the current graphics state
 9            document->SetPaint(System::MakeObject<System::Drawing::SolidBrush>(System::Drawing::Color::get_Aquamarine()));
10            
11            //Fill the sixth rectangle in the current graphics state (has complex transformation)
12            document->Fill(path);
13            
14            //Restore graphics state to the previus (upper) level
15            document->WriteGraphicsRestore();
16            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Переведіть графічний стан верхнього рівня, щоб розмістити останній прямокутник у порожньому місці на сторінці.

1            //Returns upper level graphics state back to the left and displace on 200 to the bottom.
2            document->Translate(-250.0f, 200.0f);

Останній заповнений прямокутник, який ми знову перевели в графічний стан верхнього рівня, показує, що він не зазнав трансформацій графічних станів нижнього рівня і зміни кольорів у ньому.

Помаранчевий колір - ліва поточна фарба.

1            ////////////////////////////////////// Again no transformation ////////////////////////////////////////////////////////
2            // Demonstrates that current graphics state's color is orange that was set up at the beginning of the code. 
3            //Fill the seventh rectangle in the current graphics state (has no transformation)
4            document->Fill(path);
5            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Нарешті ми закриваємо поточну сторінку та зберігаємо документ.

 1            //Close current page
 2            document->ClosePage();
 3            
 4            //Save the document
 5            document->Save();
 6        }
 7        catch(...)
 8        {
 9            __dispose_guard_0.SetCurrentException(std::current_exception());
10        }
11    }

Див. роботу з перетвореннями в документі PS у .NET або [Java](/page/{{lang.url- фрагмент}}java/ps/working-with-transformations/).


Результат виконання цього коду наступний

Трансформації

Ви можете завантажити приклади та файли даних із GitHub.

Have any questions about Aspose.Page?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.