Использование объектов Glyph | s.NET
Работа с глифами имеет решающее значение при кодировании шрифтов, поскольку это их единица. Когда основная информация о глифах объяснена в статье параграфа Что такое шрифт, здесь мы собираемся научить вас функциональности Aspose.Font для работы с глифами и в частности, объекты Glyph.
Объект Глиф
Глифы любого шрифта представлены типом Glyph в библиотеке Aspose.Font. Итак, тип Glyph — это универсальный объект для глифов шрифта, независимо от формата шрифта (TrueType, Compact Font Format и т. д.).
Функциональность, предоставляемая объектом Glyph
Какой функционал предоставляет нам этот объект?
На этот вопрос отвечают его свойства.
- Во-первых, давайте посмотрим на свойство State. Некоторые шрифты могут быть повреждены, как и их глифы. Свойство State сообщает нам, поврежден ли глиф. Если он имеет значение ParsedWithErrors, то этот глиф был проанализирован с ошибками, и не все данные глифа были получены.
- Свойства WidthVectorX и LeftSidebearingX рассказывают нам о таких метриках глифа, как ширина продвижения и левостороннее направление соответственно.
- Свойства WidthVectorY и LeftSidebearingY имеют тот же смысл, что и WidthVectorX и LeftSidebearingX, но WidthVectorY и LeftSidebearingY связаны с координатами вертикальной оси Y.
Этот пример суммирует величины продвижения глифов текста “Hello world” при размере шрифта 10 без учёта парного кернинга. Результат выражается в тех же единицах, что и размер шрифта; если размер указан в пикселях, ширина также будет в пикселях.
Добавьте следующие пространства имен в начало файла:
1 using Aspose.Font;
2 using Aspose.Font.Glyphs;Перед выполнением фрагментов подготовьте загруженный объект Aspose.Font.Font с именем font. Тесты загружают TTF/LatoWeb-Regular.ttf из DataDir, который указывает на tests-data/Aspose.Font в проекте примеров, с помощью Font.Open, FontDefinition, FontType.TTF и FileSystemStreamSource. В своём приложении используйте собственный каталог с файлами шрифтов. Эта подготовка загрузки находится вне фрагментов.
Следующий пример сопоставляет каждому символу Unicode его глиф через UnicodeToGid и суммирует масштабированные величины продвижения. Для прилагаемого шрифта Lato результат равен 50.99:
1// Calculate text width from glyph advances
2
3const string text = "Hello world";
4const int fontSize = 10;
5double width = 0;
6
7// Sum glyph advances at the requested size, without pair kerning.
8foreach (char symbol in text)
9{
10 GlyphId gid = font.Encoding.UnicodeToGid(symbol);
11 Glyph glyph = font.GetGlyphById(gid);
12 width += ((double)glyph.WidthVectorX / font.Metrics.UnitsPerEM) * fontSize;
13}Чтобы получить ограничивающую рамку глифа, используйте свойство GlyphBBox объекта Glyph.
Чтобы получить визуальное представление глифов, вам необходимо знать координаты точек всех глифов.
Как получить координаты всех точек глифа из объекта Glyph?
Следующие свойства, IsEmpty и Path, были разработаны для этого случая.
Свойство IsEmpty является вспомогательным. Он сообщает нам, пуст ли путь к глифу или, другими словами, у глифа вообще нет инструкций по рисованию. Если он имеет значение false, пришло время построить всю фигуру глифа, используя очень полезное свойство Path.
В концепции библиотеки Aspose.Font представление любого глифа разделено на простейшие графические примитивы, называемые сегментами и представленные интерфейсом IPathSegment. Интерфейс IPathSegment — это базовый абстрактный графический примитив.
Конкретные графические примитивы представлены такими типами, как MoveTo, LineTo, CurveTo и ClosePath.
Тип ClosePath используется для обозначения конца текущего графического контура.
Типы MoveTo, LineTo и CurveTo по своему определению соответствуют одинаковым постскриптумным операторам.
Также типы MoveTo и LineTo по своему определению соответствуют функциям MoveToEx() и LineTo() из библиотеки Windows GDI, тип CurveTo используется для описания кривых Безье.
Свойство Glyph Path предоставляет нам коллекцию всех графических примитивов для этого глифа.
Свойство Path имеет тип SegmentPath, и каждый объект этого типа имеет свойство Segments типа PathSegmentCollection. Это свойство Segments возвращает все графические примитивы, входящие в состав объекта SegmentPath. Другими словами, мы можем получить все графические примитивы для глифа, используя запись glyph.Path.Segments.
Этот
пример собирает конечные точки сегментов пути и управляющие точки Bézier в points — список объектов типа
Point. При приведении к int дробная часть координат отбрасывается.
Пример не группирует точки по контурам и не обрабатывает ClosePath. Для восстановления контуров нужно отслеживать их границы и обрабатывать ClosePath.
Добавьте следующие пространства имен в начало файла:
1 using System.Collections.Generic;
2 using Aspose.Font.Glyphs;
3 using Aspose.Font.RenderingPath;
4 using Point = System.Drawing.Point;Перед выполнением фрагмента получите из загруженного шрифта непустой Glyph с именем glyph, например через font.GetGlyphById(font.Encoding.UnicodeToGid('S')). В тестах используются глифы A и S. Выбор и проверка глифа находятся вне фрагмента.
1// Collect integer coordinates from a glyph path
2
3List<Point> points = new List<Point>();
4IPathSegment? prevSegment = null;
5
6// Collect endpoints and Bezier control points without grouping contours.
7foreach (IPathSegment segment in glyph.Path.Segments)
8{
9 if (segment is LineTo || segment is CurveTo)
10 {
11 if (prevSegment is MoveTo moveTo)
12 {
13 AddPoint((int)moveTo.X, (int)moveTo.Y, points);
14 }
15 if (segment is LineTo line)
16 {
17 AddPoint((int)line.X, (int)line.Y, points);
18 }
19 else if (segment is CurveTo curve)
20 {
21 AddPoint((int)curve.X1, (int)curve.Y1, points);
22 AddPoint((int)curve.X2, (int)curve.Y2, points);
23 AddPoint((int)curve.X3, (int)curve.Y3, points);
24 }
25 }
26 prevSegment = segment;
27}
28
29void AddPoint(int x, int y, List<Point> target)
30{
31 target.Add(new Point(x, y));
32}Как рассчитать значение кернинга для глифов?
Еще одна метрика Glyph, но не предоставляемая объектом типа Glyph. Здесь речь идет о кернинге. Такая характеристика, как кернинг, относится не к одному, а к паре глифов. То есть для расчета кернинга нужно использовать идентификатор не одного, а двух глифов.
Интерфейс IFontMetrics в библиотеке Aspose.Font определяет метод GetKerningValue(), который принимает идентификаторы глифов для пары глифов и возвращает значение кернинга, связанное с этой парой. Если для пары глифов нет информации о кернинге, метод возвращает 0. Реализация интерфейса IFontMetrics существует для всех классов поддерживаемых форматов шрифтов и доступна с помощью свойства Metrics.
Следующий фрагмент использует тот же загруженный font и получает значение кернинга для глифов символов A и C. В прилагаемом шрифте Lato для этой пары нет корректировки, поэтому результат равен 0:
1// Get kerning for the glyphs associated with A and C
2
3double kerning = font.Metrics.GetKerningValue(
4 font.Encoding.UnicodeToGid('A'), font.Encoding.UnicodeToGid('C'));Как получить глифы из шрифта?
Доступ к любому глифу в шрифте можно получить по специальному идентификатору глифа. Это правило справедливо для любого формата шрифта.
Идентификаторы глифа GlyphId могут быть двух типов: целые или строковые. Эти типы данных GlyphId связаны с такими характеристиками глифа, как индекс глифа и имя глифа соответственно.
Также каждый глиф имеет индекс, равный его нумерации в шрифте. Важным моментом является то, что нумерация начинается не с 1, а с 0, поэтому если шрифт содержит 15 глифов, они имеют идентификаторы глифов 0–14.
Глифы обычно также имеют имена глифов, которые представляют собой краткие текстовые метки в формате ASCII без пробелов. Например, имя глифа для символа «+» — «плюс».
Так тип данных «целое число» соответствует такой характеристике глифа, как индекс глифа, а тип данных «строка» соответствует названию глифа. Каждый глиф шрифта представляет собой изображение символа, с которым этот глиф связан, поэтому глиф связан не только со своим идентификатором, но и с уникальным кодом, соответствующим этому символу.
Связь между кодами символов и идентификаторами глифов называется кодировкой. Доступ к глифам в шрифте можно получить напрямую по идентификаторам глифов или с помощью кодировки.
В последнем случае сначала рассчитывается идентификатор глифа на основе кода символа. Затем получается глиф, соответствующий вычисленному идентификатору.
Какой тип идентификатора глифа следует использовать для доступа к нужному глифу?
Это зависит от формата шрифта. Глифы в шрифтах формата шрифта Type 1 и компактного формата шрифта (CFF) доступны по имени глифа. Фактически глифы в шрифтах этих форматов хранятся в виде массива и физически доступны по числовому индексу, но на более высоком логическом уровне для получения глифа используется его имя.
Шрифты TrueType используют целочисленный тип для идентификаторов глифов. Если шрифт TrueType имеет таблицу «post», для доступа к глифу можно использовать имя глифа или идентификатор глифа строкового типа.
Получение глифов из шрифта с помощью библиотеки Aspose.Font.
Библиотека Aspose.Font представляет пространство имен Aspose.Font.Glyphs, в котором размещаются глифы, идентификаторы глифов и другие объекты. Класс GlyphId — это базовый абстрактный класс для идентификаторов глифов. Объекты этого класса используются для получения желаемых глифов.
Идентификаторы глифов для целых чисел и строкового типа представлены классами GlyphUInt32Id и GlyphStringId соответственно.
Оба этих класса унаследованы от базового абстрактного класса GlyphId и, в частности, объекты этого абстрактного класса GlyphId передаются в функцию библиотеки для доступа к нужному глифу. Таким образом, чтобы получить необходимый глиф, вы создаете объект типа GlyphUInt32Id или GlyphStringId, а затем передаете созданный объект одной из функций, предназначенных для получения глифов.
В большинстве случаев вы не знаете, какой идентификатор глифа соответствует конкретному символу, поэтому для получения идентификатора глифа вам необходимо найти связь между кодом символа и идентификатором глифа.
Как уже говорилось выше, за такие отношения отвечает кодировка шрифта. Функциональность базового кодирования шрифтов определяется интерфейсом IFontEncoding.
Базовый интерфейс IFont, реализованный всеми классами шрифтов, определяет свойство Encoding типа IFontEncoding, поэтому любой объект шрифта, созданный библиотекой Aspose.Font, обеспечивает реализацию функциональности IFontEncoding с помощью свойство Кодировка.
Для вычисления идентификатора глифа для кода символа были разработаны следующие методы: UnicodeToGid(), DecodeToGid и DecodeToGidParameterized:
- Используйте метод UnicodeToGid(), если код вашего символа — Юникод.
- Если код вашего символа не является юникодом, используйте метод DecodeToGid().
- Метод DecodeToGidParameterized() предназначен для сложных случаев, когда для расчета идентификаторов глифа необходимы специальные параметры.
После того, как вы получили идентификатор глифа или, другими словами, ссылку на объект GlyphId, вы можете получить глиф, связанный с этим GlyphId, используя функциональность, определенную интерфейсом IGlyphAccessor.
Интерфейс IGlyphAccessor реализуется любым классом, производным от базового класса Font, и доступен через свойство IFont.GlyphAccessor.
Интерфейс IGlyphAccessor определяет метод GetGlyphById(). Используйте этот метод, чтобы получить переданный глиф для GlyphId.
Пример использования метода GetGlyphById для получения GlyphId и соответствующего глифа включен в пример из главы Функциональность, предоставляемая объектом Glyph.
Следующие 2 метода этого интерфейса предназначены для получения идентификаторов глифов:
- Если вам нужно получить идентификатор глифа для каждого символа в некоторой текстовой строке, вы можете использовать метод GetGlyphsForText().
- Метод GetAllGlyphIds() предназначен для получения всех идентификаторов глифов, имеющихся в шрифте.
Кроме того, интерфейс IGlyphAccessor определяет свойство GlyphIdType, которое сообщает нам, какой тип данных, целое число или строка имеет идентификатор глифа.
Поддержка извлечения глифов более эффективна для шрифтов TrueType. Здесь вы можете найти информацию о том, как получить доступ к глифам шрифта.
All the examples of using the Aspose.Font are stored in Aspose.Font.Examples.sln solution, in the net-examples of the Aspose.Font Documentation
Если у вас возникли какие-либо проблемы, вы можете опубликовать их в разделе Aspose.Font.Product Family на Форуме бесплатной поддержки, и в течение нескольких часов наша служба поддержки все прояснит. для тебя.