[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2-demos] master 0a44f99 21/41: [ftinspect] Add SFNT `name` tabl
From: |
Werner Lemberg |
Subject: |
[freetype2-demos] master 0a44f99 21/41: [ftinspect] Add SFNT `name` table retrieving. |
Date: |
Mon, 3 Oct 2022 11:27:02 -0400 (EDT) |
branch: master
commit 0a44f99bf66e75311110a15c85927c6e08da4b49
Author: Charlie Jiang <w@chariri.moe>
Commit: Werner Lemberg <wl@gnu.org>
[ftinspect] Add SFNT `name` table retrieving.
* src/ftinspect/engine/fontinfo.cpp, src/ftinspect/engine/fontinfo.hpp:
New files, add `SFNTName` to retrieve `name` table.
Conversions to `QString` from mainstream encodings are supported.
* src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
Add `currentFontSFNTNames` and retrieve the `name` table when loading the
font. Also pass the SFNT name table when loading palettes.
* src/ftinspect/engine/mmgx.cpp, src/ftinspect/engine/paletteinfo.cpp:
Uncomment functional code to make use of the `name` table.
* src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
---
src/ftinspect/CMakeLists.txt | 1 +
src/ftinspect/engine/engine.cpp | 8 +-
src/ftinspect/engine/engine.hpp | 3 +
src/ftinspect/engine/fontinfo.cpp | 166 +++++++++++++++++++++++++++++++++++
src/ftinspect/engine/fontinfo.hpp | 61 +++++++++++++
src/ftinspect/engine/mmgx.cpp | 20 ++---
src/ftinspect/engine/paletteinfo.cpp | 20 ++---
src/ftinspect/meson.build | 1 +
8 files changed, 258 insertions(+), 22 deletions(-)
diff --git a/src/ftinspect/CMakeLists.txt b/src/ftinspect/CMakeLists.txt
index bbb9112..19c9591 100644
--- a/src/ftinspect/CMakeLists.txt
+++ b/src/ftinspect/CMakeLists.txt
@@ -25,6 +25,7 @@ add_executable(ftinspect
"engine/rendering.cpp"
"engine/paletteinfo.cpp"
"engine/mmgx.cpp"
+ "engine/fontinfo.cpp"
"glyphcomponents/glyphbitmap.cpp"
"glyphcomponents/glyphoutline.cpp"
diff --git a/src/ftinspect/engine/engine.cpp b/src/ftinspect/engine/engine.cpp
index 9cf30b4..459f815 100644
--- a/src/ftinspect/engine/engine.cpp
+++ b/src/ftinspect/engine/engine.cpp
@@ -328,7 +328,9 @@ Engine::loadFont(int fontIndex,
ftSize_ = NULL;
curFamilyName_ = QString();
curStyleName_ = QString();
+
curPaletteInfos_.clear();
+ curSFNTNames_.clear();
}
else
{
@@ -344,6 +346,8 @@ Engine::loadFont(int fontIndex,
fontType_ = FontType_TrueType;
else
fontType_ = FontType_Other;
+
+ SFNTName::get(this, curSFNTNames_);
loadPaletteInfos();
curMMGXState_ = MMGXAxisInfo::get(this, curMMGXAxes_);
}
@@ -850,8 +854,8 @@ Engine::loadPaletteInfos()
// size never exceeds max val of ushort.
curPaletteInfos_.reserve(paletteData_.num_palettes);
for (int i = 0; i < paletteData_.num_palettes; ++i)
- curPaletteInfos_.emplace_back(ftFallbackFace_, paletteData_, i, nullptr);
- // no `NULL` here - we need `std::nullptr_t`
+ curPaletteInfos_.emplace_back(ftFallbackFace_, paletteData_, i,
+ &curSFNTNames_);
}
diff --git a/src/ftinspect/engine/engine.hpp b/src/ftinspect/engine/engine.hpp
index 7b264d7..cba152e 100644
--- a/src/ftinspect/engine/engine.hpp
+++ b/src/ftinspect/engine/engine.hpp
@@ -8,6 +8,7 @@
#include "fontfilemanager.hpp"
#include "paletteinfo.hpp"
+#include "fontinfo.hpp"
#include "mmgx.hpp"
#include "rendering.hpp"
@@ -122,6 +123,7 @@ public:
FT_Palette_Data& currentFontPaletteData() { return paletteData_; }
MMGXState currentFontMMGXState() { return curMMGXState_; }
std::vector<MMGXAxisInfo>& currentFontMMGXAxes() { return curMMGXAxes_; }
+ std::vector<SFNTName>& currentFontSFNTNames() { return curSFNTNames_; }
QString glyphName(int glyphIndex);
long numberOfFaces(int fontIndex);
@@ -211,6 +213,7 @@ private:
std::vector<PaletteInfo> curPaletteInfos_;
MMGXState curMMGXState_ = MMGXState::NoMMGX;
std::vector<MMGXAxisInfo> curMMGXAxes_;
+ std::vector<SFNTName> curSFNTNames_;
// basic objects
FT_Library library_;
diff --git a/src/ftinspect/engine/fontinfo.cpp
b/src/ftinspect/engine/fontinfo.cpp
new file mode 100644
index 0000000..3eb5b78
--- /dev/null
+++ b/src/ftinspect/engine/fontinfo.cpp
@@ -0,0 +1,166 @@
+// fontinfo.cpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#include "fontinfo.hpp"
+
+#include "engine.hpp"
+
+#include <memory>
+#include <utility>
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#include <QTextCodec>
+#else
+#include <QStringConverter>
+#include <QByteArrayView>
+#endif
+#include <freetype/ftmodapi.h>
+#include <freetype/ttnameid.h>
+
+
+void
+SFNTName::get(Engine* engine,
+ std::vector<SFNTName>& list)
+{
+ auto face = engine->currentFallbackFtFace();
+ if (!face || !FT_IS_SFNT(face))
+ {
+ list.clear();
+ return;
+ }
+
+ auto newSize = FT_Get_Sfnt_Name_Count(face);
+ if (list.size() != static_cast<size_t>(newSize))
+ list.resize(newSize);
+
+ FT_SfntName sfntName;
+ FT_SfntLangTag langTag;
+ for (unsigned int i = 0; i < newSize; ++i)
+ {
+ FT_Get_Sfnt_Name(face, i, &sfntName);
+ auto& obj = list[i];
+ obj.platformID = sfntName.platform_id;
+ obj.encodingID = sfntName.encoding_id;
+ obj.languageID = sfntName.language_id;
+ obj.nameID = sfntName.name_id;
+
+ auto len = sfntName.string_len >= INT_MAX
+ ? INT_MAX - 1
+ : sfntName.string_len;
+ obj.strBuf = QByteArray(reinterpret_cast<const char*>(sfntName.string),
+ len);
+ obj.str = sfntNameToQString(sfntName, &obj.strValid);
+
+ if (obj.languageID >= 0x8000)
+ {
+ auto err = FT_Get_Sfnt_LangTag(face, obj.languageID, &langTag);
+ if (!err)
+ obj.langTag = utf16BEToQString(reinterpret_cast<char*>(langTag.string),
+ langTag.string_len);
+ }
+ }
+}
+
+
+QString
+SFNTName::sfntNameToQString(FT_SfntName const& sfntName,
+ bool* outSuccess)
+{
+ return sfntNameToQString(sfntName.platform_id, sfntName.encoding_id,
+ reinterpret_cast<char const*>(sfntName.string),
+ sfntName.string_len,
+ outSuccess);
+}
+
+
+QString
+SFNTName::sfntNameToQString(SFNTName const& sfntName, bool* outSuccess)
+{
+ return sfntNameToQString(sfntName.platformID, sfntName.encodingID,
+ sfntName.strBuf.data(), sfntName.strBuf.size(),
+ outSuccess);
+}
+
+
+QString
+SFNTName::sfntNameToQString(unsigned short platformID,
+ unsigned short encodingID,
+ char const* str,
+ size_t size,
+ bool* outSuccess)
+{
+ // TODO not complete.
+ if (size >= INT_MAX - 1)
+ return "";
+
+ if (outSuccess)
+ *outSuccess = true;
+
+ switch (platformID)
+ {
+ case TT_PLATFORM_APPLE_UNICODE:
+ // All UTF-16BE.
+ return utf16BEToQString(str, size);
+ case TT_PLATFORM_MACINTOSH:
+ if (encodingID == TT_MAC_ID_ROMAN)
+ return QString::fromLatin1(str, static_cast<int>(size));
+
+ if (outSuccess)
+ *outSuccess = false;
+ return "<encoding unsupported>";
+ case TT_PLATFORM_ISO:
+ switch (encodingID)
+ {
+ case TT_ISO_ID_7BIT_ASCII:
+ case TT_ISO_ID_8859_1:
+ return QString::fromLatin1(str, static_cast<int>(size));
+ case TT_ISO_ID_10646:
+ return utf16BEToQString(str, size);
+ default:
+ if (outSuccess)
+ *outSuccess = false;
+ return "<encoding unsupported>";
+ }
+ case TT_PLATFORM_MICROSOFT:
+ switch (encodingID)
+ {
+ /* TT_MS_ID_SYMBOL_CS is Unicode, similar to PID/EID=3/1 */
+ case TT_MS_ID_SYMBOL_CS:
+ case TT_MS_ID_UNICODE_CS:
+ case TT_MS_ID_UCS_4: // This is UTF-16LE as well, according to MS doc
+ return utf16BEToQString(str, size);
+
+ default:
+ if (outSuccess)
+ *outSuccess = false;
+ return "<encoding unsupported>";
+ }
+ }
+
+ if (outSuccess)
+ *outSuccess = false;
+ return "<platform unsupported>";
+}
+
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+QTextCodec* utf16BECodec = QTextCodec::codecForName("UTF-16BE");
+#else
+QStringDecoder utf16BECvt = (QStringDecoder(QStringDecoder::Utf16BE))(size);
+#endif
+
+QString
+SFNTName::utf16BEToQString(char const* str,
+ size_t size)
+{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ if (size >= INT_MAX)
+ size = INT_MAX - 1;
+ return utf16BECodec->toUnicode(str, static_cast<int>(size));
+#else
+ return utf16BECvt(QByteArrayView(reinterpret_cast<char*>(str), size));
+#endif
+}
+
+
+// end of fontinfo.cpp
diff --git a/src/ftinspect/engine/fontinfo.hpp
b/src/ftinspect/engine/fontinfo.hpp
new file mode 100644
index 0000000..c1b9ff3
--- /dev/null
+++ b/src/ftinspect/engine/fontinfo.hpp
@@ -0,0 +1,61 @@
+// fontinfo.hpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#pragma once
+
+#include <set>
+#include <vector>
+#include <QByteArray>
+#include <QString>
+#include <freetype/freetype.h>
+#include <freetype/ftsnames.h>
+
+class Engine;
+struct SFNTName
+{
+ unsigned short nameID;
+ unsigned short platformID;
+ unsigned short encodingID;
+ unsigned short languageID;
+ QByteArray strBuf;
+ QString str;
+ QString langTag;
+ bool strValid = false;
+
+ static void get(Engine* engine,
+ std::vector<SFNTName>& list);
+ static QString sfntNameToQString(FT_SfntName const& sfntName,
+ bool* outSuccess = NULL);
+ static QString sfntNameToQString(SFNTName const& sfntName,
+ bool* outSuccess = NULL);
+ static QString sfntNameToQString(unsigned short platformID,
+ unsigned short encodingID,
+ char const* str, size_t size,
+ bool* outSuccess = NULL);
+ static QString utf16BEToQString(char const* str, size_t size);
+
+
+ friend bool
+ operator==(const SFNTName& lhs,
+ const SFNTName& rhs)
+ {
+ return lhs.nameID == rhs.nameID
+ && lhs.platformID == rhs.platformID
+ && lhs.encodingID == rhs.encodingID
+ && lhs.languageID == rhs.languageID
+ && lhs.strBuf == rhs.strBuf
+ && lhs.langTag == rhs.langTag;
+ }
+
+
+ friend bool
+ operator!=(const SFNTName& lhs,
+ const SFNTName& rhs)
+ {
+ return !(lhs == rhs);
+ }
+};
+
+
+// end of fontinfo.hpp
diff --git a/src/ftinspect/engine/mmgx.cpp b/src/ftinspect/engine/mmgx.cpp
index b978272..570d55f 100644
--- a/src/ftinspect/engine/mmgx.cpp
+++ b/src/ftinspect/engine/mmgx.cpp
@@ -39,7 +39,7 @@ MMGXAxisInfo::get(Engine* engine,
infos.resize(mm->num_axis);
- //auto& sfnt = engine->currentFontSFNTNames();
+ auto& sfnt = engine->currentFontSFNTNames();
for (unsigned int i = 0; i < mm->num_axis; ++i)
{
auto& axis = mm->axis[i];
@@ -58,15 +58,15 @@ MMGXAxisInfo::get(Engine* engine,
if (state == MMGXState::GX_OVF)
{
auto strid = mm->axis[i].strid;
- //for (auto& obj : sfnt)
- //{
- // if (obj.nameID == strid && obj.strValid)
- // {
- // info.name = obj.str;
- // nameSet = true;
- // break;
- // }
- //}
+ for (auto& obj : sfnt)
+ {
+ if (obj.nameID == strid && obj.strValid)
+ {
+ info.name = obj.str;
+ nameSet = true;
+ break;
+ }
+ }
}
// XXX security flaw
diff --git a/src/ftinspect/engine/paletteinfo.cpp
b/src/ftinspect/engine/paletteinfo.cpp
index 7abd2ae..302f3f7 100644
--- a/src/ftinspect/engine/paletteinfo.cpp
+++ b/src/ftinspect/engine/paletteinfo.cpp
@@ -4,7 +4,7 @@
#include "paletteinfo.hpp"
-//#include "fontinfo.hpp"
+#include "fontinfo.hpp"
PaletteInfo::PaletteInfo(FT_Face face,
FT_Palette_Data& data,
@@ -15,15 +15,15 @@ PaletteInfo::PaletteInfo(FT_Face face,
if (sfntNames && data.palette_name_ids)
{
auto id = data.palette_name_ids[index];
- name = "(unsupported)";
- //for (auto& obj : *sfntNames)
- //{
- // if (obj.nameID == id && obj.strValid)
- // {
- // name = obj.str;
- // break;
- // }
- //}
+ name = "(invalid)";
+ for (auto& obj : *sfntNames)
+ {
+ if (obj.nameID == id && obj.strValid)
+ {
+ name = obj.str;
+ break;
+ }
+ }
}
else
name = "(unnamed)";
diff --git a/src/ftinspect/meson.build b/src/ftinspect/meson.build
index 71450ab..405cff8 100644
--- a/src/ftinspect/meson.build
+++ b/src/ftinspect/meson.build
@@ -26,6 +26,7 @@ if qt5_dep.found()
'engine/rendering.cpp',
'engine/paletteinfo.cpp',
'engine/mmgx.cpp',
+ 'engine/fontinfo.cpp',
'glyphcomponents/glyphbitmap.cpp',
'glyphcomponents/glyphoutline.cpp',
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] master 0a44f99 21/41: [ftinspect] Add SFNT `name` table retrieving.,
Werner Lemberg <=