Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/29: Рейтинг темы: голосов - 29, средняя оценка - 4.59
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
1

Как вытянуть из шрифта его название которое вшито внутри файла

26.06.2012, 16:43. Показов 6005. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!!!

Ребята подскажите по такому вопросу!!!

Как можно вытянуть название файла шрифта которое вшито внутри файла и определить поддерживает он кирилицу или нет?

Заранее благодарен
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.06.2012, 16:43
Ответы с готовыми решениями:

Как узнать точно название шрифта, которое нужно ввести?
Не отображается шрифт... Сегодня изучал шрифты. Задача была изменить шрифт, но пока без...

Как сделать окошко в которое пользователь впишет название файла и он откроется?
Как сделать окошко в которое пользователь впишет название файла и он откроется? пример:...

Как создать экземпляр класса внутри другого, явно не указывая его название
Как создать екземпляр класса внутри класса явно не указывая его название и не присваивая в...

Разработать приложение которое определяет название месяца по введенному его номеру
1.Разработать приложение которое определяет название месяца по введенному его номеру.

8
return (true);
1976 / 1111 / 221
Регистрация: 19.04.2011
Сообщений: 2,345
26.06.2012, 19:15 2
Цитата Сообщение от Sasha Посмотреть сообщение
Как можно вытянуть название файла шрифта
https://developer.apple.com/fo... l#Overview
Искать таблицу name
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
26.06.2012, 23:14  [ТС] 3
mimicria, а как вообще выйти на name?
0
return (true);
1976 / 1111 / 221
Регистрация: 19.04.2011
Сообщений: 2,345
27.06.2012, 08:09 4
В описании формата есть всё. Читаешь Table Directory (смещение 0). В ней есть поле numTables (число таблиц). Сразу же после нее (смещение 12) находятся Table Directory entries числом numTables. В каждой entry есть поле offset (смещение таблицы от начала файла) и поле length(размер таблицы). Кроме того есть поле tag, чтобы найти нужную таблицу. Находишь нужную таблицу по tag, читаешь из файла length байт по смещению offset. Первыми идут 3 unsigned short заголовка, из которых нужны Number of NameRecords (2-й unsigned short) и Offset to start of string storage(3-й). Далее перебираешь все NameRecord (их количество уже известно) и проверяешь 1-й (Platform ID) и 4-й (Name ID) unsigned short пока не получишь Platform ID == 3 (M$) и Name ID == 1 (Font Family name)
Еще для ленивых вот: http://www.codeproject.com/Art... m-TTF-file
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
27.06.2012, 11:12  [ТС] 5
Цитата Сообщение от mimicria Посмотреть сообщение
В описании формата есть всё. Читаешь Table Directory (смещение 0). В ней есть поле numTables (число таблиц). Сразу же после нее (смещение 12) находятся Table Directory entries числом numTables. В каждой entry есть поле offset (смещение таблицы от начала файла) и поле length(размер таблицы). Кроме того есть поле tag, чтобы найти нужную таблицу. Находишь нужную таблицу по tag, читаешь из файла length байт по смещению offset. Первыми идут 3 unsigned short заголовка, из которых нужны Number of NameRecords (2-й unsigned short) и Offset to start of string storage(3-й). Далее перебираешь все NameRecord (их количество уже известно) и проверяешь 1-й (Platform ID) и 4-й (Name ID) unsigned short пока не получишь Platform ID == 3 (M$) и Name ID == 1 (Font Family name)
Еще для ленивых вот: http://www.codeproject.com/Art... m-TTF-file
Спасибо я сделал вроде работает, но а как теперь определить поддерживает шрифт кирилицу или нет?
0
1 / 1 / 0
Регистрация: 15.03.2021
Сообщений: 8
17.03.2021, 09:58 6
Считывание имени шрифта из файла шрифта
1 Аннотация
В статье изложен способ считывания имени шрифта, который скрыт в файле шрифта, и представлена программа, создающая список имён в документе, всех шрифтов, файлы которых собраны в одну произвольную папку.
2 Назначение
Программа, например, позволяет решить следующую задачу.
Есть наборы состоящие из нескольких тысяч файлов шрифтов, но в них могут быть дубликаты одной и той же гарнитуры, причём, одни лучше, другие хуже. Например, в одних может быть кириллический шрифт, а в других нет. При загрузке же в систему, она выбирает только один вариант гарнитуры и он может оказаться не лучшим.
3 Преимущества
В систему Windows папку Fonts для исследований можно установить только порядка одной тыс. шрифтов, хотя в произвольную папку дисковая система NTFS позволяет загрузить более миллиарда файлов шрифтов.
Программа позволяет из произвольной папки, загруженной несколькими десятками тыс. файлов шрифтов, считывает их имена менее, чем за одну минуту.
Программа выводит список имён всех файлов и названия гарнитуры того шрифта, который они дают, в документ MS OFFICE Word. Просмотрев все имена в документе, ещё до загрузки в систему, можно выбрать файлы с лучшими шрифтами.
4 Условия использования и ограничения
Надо ограничивать число загружаемых файлов в одну папку – 3,5 тыс. Т.к., если в папке будет более 10 тыс. файлов, то начнёт тормозить система а в Word перестанет функционировать опция сортировки строк с именами файлов введённые в документ.
Если программа зависает, т.е. спустя несколько минут продолжает работать, то можно её остановить нажатием клавиш Ctrl + Break, перейти в окно проекта, вывести Debug, навести курсор на строку "StrName" и выявить некорректный файл который сбивает программу и удалить его из папки.
Были обнаружены ряд файлов, имя которых программа неправильно вывела.
В одном из случаев это произошло из-за того, что разработчик записал имя в кириллическом шрифте кодом ANSI. Но изображение символов у ANSI и UNICOD совпадают только до кода 127 = #7F – это латиница. При дальнейшем увеличении кода у ANSI идут русские буквы, а UNICOD их выдаёт за пределами 1040 = #0410. А т.к. в программе для вывода символов в UNICOD применена функция ChrW(), переводящая двухбайтный код в символ, то, если имя в латинице, то программа даёт верное имя, а русский или какой-либо другой язык уже в неправильном виде.
Например, вместо кода #0410 – кириллического символа "А" в UNICOD, было записано #C0. Но код #C0 в UNICOD представляет другой символ, хотя для ANSI он соответствует "А". В результате было программой выведено неправильное имя в UNICOD , но верное в ANSI. Поэтому, программа, чтобы избежать такие случаи неправильно вывода имени в UNICOD, которое присутствует у всех файлов, дублирует его в ANSI.
Можно предположить, что программу будут применять для выбора не простых гарнитур, поэтому в папку для исследования не стоит загружать файлы размером менее 50 Кб, т.к. это примитивные шрифты.
5 Порядок применения
Программа, составлена в Microsoft (MS) OFFICE VBA (Visual Basic Application), выводит все названия шрифтов из файлов с расширением .TTF и .OTF этих шрифтов, расположенных в одной папке. В программе в строках "ReadName = Dir("d:\TrFont\*.ttf")" и StrName = "d:\TrFont" & ReadName надо заменить имена диска и папки "TrFont", на те, в которых собраны Ваши нужные для считывания файлы шрифтов.
Для корректной работы программы нужно при установке Word добавить многоязыковую поддержку.
6 Спецификация файла шрифта
Выявим структуру файла шрифта, которая приводит к имени шрифта.
В Табл. "Имена таблиц файла шрифта" ( см. ниже) даны коды, которые стоят в начале, взятого для примера, одного из файлов шрифта .
На 5 и 6 месте от начала содержания файла два адреса показывают количество таблиц для данного файла шрифта. В нашем примере они имеют код – 00 0E, в десятичной системе это означает 14 таблиц.
Со следующей строчки таблицы, начиная с 13 адреса, есть указатели таблиц. Каждая графа включает коды 5 адресов. Первая графа адрес начала строки, в которой записаны данные каждой таблицы. Вторая графа – коды конвертированные в текст имени таблицы.
Следующие затем три графы – 12 адресов включают: значения контрольной суммы – 4 адреса, смещение адреса начала содержания таблицы – 4 адреса и длину таблицы – 4 адреса. Итак, каждый указатель занимает 16 адресов. Среди этих таблиц обязательно есть таблица name, указывающая на место положения поля имён шрифта.

Табл. Имена таблиц файла шрифта


00 00010000000E0030000300B0
Адр.ИмяКонтр.суммаАдрес поляДлина поля
0DOS/2 9A A3 81 1400 00 D3 20 00 00 00 4E
1Dcmap DF 9A 39 A700 00 E0 38 00 00 06 42
ADmaxp 01 E1 01 5D00 00 01 48 00 00 00 20
BDname 58 DA AB AB 00 00 01 68 00 00 02 43
CDpost 2A 8F 2B BC 00 00 CA 6C 00 00 01 B6
DDprep 53 FA AE 56 00 00 04 10 00 00 01 07

Взяв из ячейки на пересечении строки "name" и графы "Адрес поля" значение начала "Табл. Поле "name"", переходим к рассмотрению кодов поля "name".
Для выбранного примера соответственно Табл. Поле "name" (см. табл. в конце статьи) имеет начло адрес 00 00 01 68.
Табл. Поле "name" первая графа – начальный адрес строк кода. Затем идут 32 графы строк кода. Нечётные строки – сам код, чётные – перевод значения кода, если он имеет графическое представление, в символ, чтобы можно было прочитать имена шрифта.
На 4 и 5 месте адресного поля name есть двухбайтное значение числа различных видов имён одного и того же шрифта.
На 6 и 7 месте – смещение до начала перечня всех этих имён. В примере это двухбайтное число 01 02, если его сложить с началом – 01 68, то получим 02 6А. В таблице (показано стрелкой) видим, что по этому адресу закончены ID (идентификаторы) строки и идут различные виды имён шрифта.
Начиная с 8 адреса, идут друг за другом ID строки, длинной 12 адресов, указатели адресов различных имён шрифта. ID строки выделены столбиками.
Даже не вникая в их назначение, в рассматриваемом файле (но не у всех) можно заметить закономерность: первые семь ID строки имеют в начале 00, а на 8 месте, как будто счётчик: 0, 1, 2 до 6. Затем идут семь ID строки с началом 01 и опять на 8 месте счётчик. Далее – 03 также с номерами от 0 до 6.
В табл. Поле "name" ячейки Id платформы и "счётчика" выделены рамками.
Расшифруем значения чисел ID строк.
Первые два адреса ID строки представляют двухбайтное число – значение платформы системы. Например, для одних систем данные представлены в ANSI кодировке, обозначены 01, для других, например, MS – 03 – кодах UNICODE.
Затем – два адреса особого кода (Encoding ID). В нашем случае он 00 или 01.
На 5 и 6 месте указан язык шрифта (Language ID). Чаще всего здесь стоит код 0409 – английский. А в общем их несколько десятков.
На 7 и 8 месте характер имени (Name ID). Значения могут быть такими:
0 – отметка о создании (Copyright notice)
1 – гарнитура шрифта (Font Fammily)
2 – подсемейство (Font Subfammily)
3 – идентификатор
4 – полное имя шрифта (Full name)
5 – версия таблицы имён (Version of the name table)
‎Строка версии. Должен начинаться с синтаксиса 'Version n.nn' (надстрочный, подстрочный, или смешанный).‎
6 ‎Постскриптум для шрифта
На предпоследнем месте ID строки дан двухбайтное значение длины уникальной, в соответствие с установленными идентификаторами (ID), записи имени шрифта. И в последних двух адресах – его смещение по отношению к началу перечня всех типов этих имён.
7 Описание программы
На первом этапе идёт поиск параметров таблицы "name".
Программа считывает для определения общего числа таблиц лишь адрес 6 (см. Табл. Имена таблиц файла шрифта), т.к. количество таблиц не превышает 30, и сохраняет его в переменной b.
Программа, начиная с адреса #0D = 13, через каждые 16 адресов считывает 4 адреса имени таблиц и сравнивает их со строкой "name". Как только устанавливает совпадение, считывает содержание 4 адресов начала поля таблицы name, переведённое в десятичное значение – q, и другие 4 адреса – её длину.
Программа переходит на адрес q – начало поля имён шрифта. Для выбранного примера (см. предыдущую Табл. Имена таблиц файла шрифта) в строке "name" в графе 4 адрес – 00 00 01 68 . Команда "Get 1, v, b" вписывает в b это значение, только вместо #68 выдаёт десятичное значение 104, затем программа производит расчёт всего значения адреса в десятинном исчисление: q = 1* 256 + 104 + = 360 = #0168.
На втором этапе программа обрабатывает данные Табл. Поле "name" – в примере по адресу #0168.
Программа ищет имена шрифтов в ANSI и UNICOD кодировках.
Программа перебирает ID строки, в которых есть нужный формат платформы (ANSI – ID = 01 или UNICOD – ID = 03) и приемлемый формат имени шрифта, например, для проверки дублирования, когда в имени учтена к.л. модификация – курсив (Italic) или жирный (Bold), – полное имя шрифта – ID =4. Можно также выбрать, если внести в программу соответствующие поправки, например, вариант только имени гарнитуры ID =1.
Итак, искомая строка для UNICOD может иметь вид "0301" = s или "0304" = s , где s лишь усечённая для поиска часть ID строки: первая пара – 1 и 2 коды и вторая пара – 6 и 7 коды ID строки.
И аналогично для ANSI "0101" = s или "0104" = s.
При совпадении значений строк, например, "0101" = s, идёт считывание длины записи имени шрифта и адрес его положения, а затем самого имени шрифта.
Например, от ID строки (см. табл. Поле "name") с началом 00 03 – указатель платформы UNICOD и счётчиком 00 04 – указатель ID на полное имя шрифта, в конце ID строки указан двухбайтный адрес 00 BB, от которого отходит стрелка (см. другую стрелку) и доходит до адреса 03 26. Действительно, при сложении адреса начала перечня имён шрифта – 02 6A + 1 = 02 6В (см. адрес, указанный предыдущей стрелкой) и смещении 00 BB получим 03 26. Это адрес начала полного имени шрифта Tiff-Heavy.
Если при переборе всех ID строк, в ней нужных значений ID нет или установлена длина имени равной нулю, то в документ программа вписывает: "… Name no found".

Не могу не обратить внимание на моральную сторону некоторых публикаций. Вопрос считывания имени шрифта из файла в Интернете ставили не раз, но нормального ответа так никто и не дал. Авторы сами разобрались в проблеме, но выразить словами её решение не смогли, допустили недомолвки, из-за которых читатели сами этот вопрос не могут решить.
Поэтому, уважаемые знатоки, чтобы избежать бесполезных публикаций, дайте вначале почитать предложения своим друзьям. И только после их положительных отзывов о статье, выкладывайте её в свет.

Код программы


Visual Basic
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
Sub ReadName()
    Dim StrName As String, ReadName As String, RUName As String, s As String
    Dim b As Byte: Const t As Integer = 256
    Dim q As Long, k As Long, i As Long, f As Long, v As Long, w As Long
    ReadName = Dir("d:\TrFont\*") ' считывание имени файла из папки TrFont
        Do Until ReadName = "" ' циклы считывания файлов до условия,
        ' при котором нет файла для текущего просмотра
            Open "d:\TrFont\" & ReadName For Binary As #1
                RUName = "": q = 0: k = q: e = t  ' t устанавливает большой шаг, для выхода из циклов For
                Get 1, 6, b ' считывание общего числа таблиц в переменную b
                 For f = 13 To b * 16 Step 16 ' поиск таблицы name среди b других таблиц
                 Seek #1, f
                s = Input(4, #1)  ' последовательное считывание имён таблиц
                    If "name" = s Then
                    e = 1 ' устанавливает нормальный шаг для выполнения циклов For
                    Exit For 'выход из цикла, если "name" = s
                    End If
                Next
                            v = f + 7:  w = v + 4
                            For i = 1 To 4 Step e 'считывание адресов в name таблицы
                            v = v + 1: w = w + 1
                            Get 1, v, b
                            q = q + b * t ^ (4 - i)
                            Get 1, w, b
                            k = k + b * t ^ (4 - i)
                            Next ' на выходе адреса начала - q и длины  - k поля форматов имён  шрифта
                Get 1, q + 5, b:   f = b * t:    Get 1, , b: f = f + b ' f - смещение к полю форматов имён шрифта
                For i = q + f - 11 To q Step -e * 12 ' считывание символов усечённых ID строк в обратном порядке
Get 1, i, b: s = Hex(b):   Get 1, , b: s = s + Hex(b): Get 1, i + 6, b: s = s + Hex(b): Get 1, , b: s = s + Hex(b)
                    If "0304" = s Then 'если "0304" = s, то считывание имени шрифта
                    Get 1, i + 8, b: v = b * t: Get 1, , b: v = v + b
                    Get 1, i + 10, b: w = b * t: Get 1, , b: w = w + b
                    Seek #1, q + f + w + 1
                    Get 1, , b
                        If b = 38 Then ' в начале имени пропускает "&"
                        v = v - 2
                        Seek #1, q + f + w + 3
                        Else
                        Seek #1, q + f + w + 1
                        End If
                            For w = 1 To v Step 2
Get 1, , b: s = CLng(b) * t ' при b =#ff = 255, чтобы избежать ошибки нужна функция CLng(b)
Get 1, , b: s = s + b: RUName = RUName & ChrW(s)   'вывод UNICODE символов имён шрифтов
                            Next w
                    Exit For
                    End If
            Next
                    If RUName = "" Then
                     RUName = "UNICODE Name no found"
                    End If
            For i = q + 7 To q + f Step e * 12 ' считывание символов усечённых ID строк по порядку
    Get 1, i, b: s = Hex(b):    Get 1, , b: s = s + Hex(b): Get 1, i + 6, b: s = s + Hex(b): Get 1, , b: s = s + Hex(b)
                    If "0104" = s Then 'считывание имени шрифта, если "0104" = s
                    Get 1, i + 8, b: v = b * t: Get 1, , b: v = v + b
                    Get 1, i + 10, b: w = b * t: Get 1, , b: w = w + b
                        Seek #1, q + f + w + 1
                        StrName = RUName & ";" & Input(v, #1)   'добавление ANSI имени шрифта
                    Exit For
                    End If
            Next
                    If i >= q + f Or v = 0 Then ' имя не найдено или его длина установлена - 00
                    StrName = RUName & ";" & "ANSI Name no found"
                    End If
                    Close 1
                Selection.TypeText vbCrLf & ReadName & _
                ";" & StrName 'вывод имени файла и пары имён шрифта
                ReadName = Dir
                 Loop
    End Sub




Табл. Поле "name"

Миниатюры
Как вытянуть из шрифта его название которое вшито внутри файла  
1
D1973
17.03.2021, 10:59
  #7

Не по теме:

VitVas, все, конечно, хорошо... Но вот только раздел этот - C++ Builder... При чем тут Ваш код на VB?

0
1 / 1 / 0
Регистрация: 15.03.2021
Сообщений: 8
17.03.2021, 11:11 8
В моём тексте - Visual Basic Application, и внешний вид кода выглядит неплохо.
0
Модератор
9457 / 6210 / 2420
Регистрация: 21.01.2014
Сообщений: 26,468
Записей в блоге: 3
17.03.2021, 11:45 9
Цитата Сообщение от VitVas Посмотреть сообщение
и внешний вид кода выглядит неплохо
Вы не понимаете, о чем я говорю? Это другой раздел, не имеющий никакого отношения ни к VB, ни к VBA
0
17.03.2021, 11:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.03.2021, 11:45
Помогаю со студенческими работами здесь

Как вытянуть в текстовую строку название Свойства (Property)?
Задача в том, что бы вытянуть из имеющихся Свойств название и передать их в конструктор другого...

Pugixml - вытянуть тег из файла при разном его вложении
Всем привет, хотелось бы получить помощи, имею такие вот исходные данные, Пример: <root>...

Как вытянуть id из массива и занести его в таблицу?
<?php if ($rez=$db->query("SELECT `blok`.`id`, `blok`.`id_p`, `blok`.`id_raz`,...

Как можно узнать из файла .m3u название песни и вывести это название в Label?
Я делаю свою программку для прослушивания радиостанций (хоть таких и полно - но мне хочется создать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru