[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2-demos] master 9a746ee 31/41: [ftinspect] Add transformation a
From: |
Werner Lemberg |
Subject: |
[freetype2-demos] master 9a746ee 31/41: [ftinspect] Add transformation and scaling info to the composite glyph view. |
Date: |
Mon, 3 Oct 2022 11:27:03 -0400 (EDT) |
branch: master
commit 9a746eeafdd3b0a2eaff284f752f67e1eeaffcb3
Author: Charlie Jiang <w@chariri.moe>
Commit: Werner Lemberg <wl@gnu.org>
[ftinspect] Add transformation and scaling info to the composite glyph view.
Note: Untested since no font with non-1.0 scale subglyphs is found.
* src/ftinspect/engine/fontinfo.cpp, src/ftinspect/engine/fontinfo.hpp:
Fetch transformation and scaling info from the font.
* src/ftinspect/models/fontinfomodels.cpp,
src/ftinspect/models/fontinfomodels.hpp:
Change the "Position" column to "Position and Transformation".
Display the transformation info.
---
src/ftinspect/engine/fontinfo.cpp | 61 ++++++++++++++++++++----
src/ftinspect/engine/fontinfo.hpp | 32 +++++++++++--
src/ftinspect/models/fontinfomodels.cpp | 83 +++++++++++++++++++++------------
src/ftinspect/models/fontinfomodels.hpp | 4 +-
4 files changed, 132 insertions(+), 48 deletions(-)
diff --git a/src/ftinspect/engine/fontinfo.cpp
b/src/ftinspect/engine/fontinfo.cpp
index 5927409..e99dcb6 100644
--- a/src/ftinspect/engine/fontinfo.cpp
+++ b/src/ftinspect/engine/fontinfo.cpp
@@ -571,6 +571,21 @@ SFNTTableInfo::getForAll(Engine* engine,
}
+
+FT_UInt16
+readUInt16(void* ptr)
+{
+ return bigEndianToNative(*static_cast<uint16_t*>(ptr));
+}
+
+
+double
+readF2Dot14(void* ptr)
+{
+ return static_cast<int16_t>(readUInt16(ptr)) / 16384.0;
+}
+
+
void
CompositeGlyphInfo::get(Engine* engine,
std::vector<CompositeGlyphInfo>& list)
@@ -641,7 +656,7 @@ CompositeGlyphInfo::get(Engine* engine,
if (loc + 16 > end)
continue;
- auto len = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
+ auto len = static_cast<FT_Int16>(readUInt16(buffer + loc));
loc += 10; // skip header
if (len >= 0) // not a composite one
continue;
@@ -652,18 +667,18 @@ CompositeGlyphInfo::get(Engine* engine,
{
if (loc + 6 > end)
break;
- auto flags = static_cast<FT_UInt16>(buffer[loc] << 8 | buffer[loc + 1]);
+ auto flags = readUInt16(buffer + loc);
loc += 2;
- auto index = static_cast<FT_UInt16>(buffer[loc] << 8 | buffer[loc + 1]);
+ auto index = readUInt16(buffer + loc);
loc += 2;
FT_Int16 arg1, arg2;
//
https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description
if (flags & 0x0001)
{
- arg1 = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
+ arg1 = static_cast<FT_Int16>(readUInt16(buffer + loc));
loc += 2;
- arg2 = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
+ arg2 = static_cast<FT_Int16>(readUInt16(buffer + loc));
loc += 2;
}
else
@@ -672,17 +687,43 @@ CompositeGlyphInfo::get(Engine* engine,
arg2 = buffer[loc + 1];
loc += 2;
}
+
+ subglyphs.emplace_back(index, flags,
+ flags & 0x0002 ? SubGlyph::PT_Offset
+ : SubGlyph::PT_Align,
+ std::pair<short, short>(arg1, arg2),
+ (flags & 0x0800) != 0);
+ // TODO: Use "Default behavior" when neither SCALED_COMPONENT_OFFSET
+ // and UNSCALED_COMPONENT_OFFSET are set.
+
+ auto& glyph = subglyphs.back();
if (flags & 0x0008)
+ {
+ glyph.transformationType = SubGlyph::TT_UniformScale;
+ glyph.transformation[0] = readF2Dot14(buffer + loc);
loc += 2;
+ }
else if (flags & 0x0040)
+ {
+ glyph.transformationType = SubGlyph::TT_XYScale;
+ glyph.transformation[0] = readF2Dot14(buffer + loc);
+ glyph.transformation[1] = readF2Dot14(buffer + loc + 2);
loc += 4;
+ }
else if (flags & 0x0080)
+ {
+ glyph.transformationType = SubGlyph::TT_Matrix;
+ glyph.transformation[0] = readF2Dot14(buffer + loc);
+ glyph.transformation[1] = readF2Dot14(buffer + loc + 2);
+ glyph.transformation[2] = readF2Dot14(buffer + loc + 4);
+ glyph.transformation[3] = readF2Dot14(buffer + loc + 6);
loc += 8;
-
- subglyphs.emplace_back(index, flags,
- flags & 0x0002 ? SubGlyph::PT_Offset
- : SubGlyph::PT_Align,
- std::pair<short, short>(arg1, arg2));
+ }
+ else
+ {
+ glyph.transformationType = SubGlyph::TT_UniformScale;
+ glyph.transformation[0] = 1.0;
+ }
if (!(flags & 0x0020))
break;
diff --git a/src/ftinspect/engine/fontinfo.hpp
b/src/ftinspect/engine/fontinfo.hpp
index f28dc81..5a5fb1b 100644
--- a/src/ftinspect/engine/fontinfo.hpp
+++ b/src/ftinspect/engine/fontinfo.hpp
@@ -5,6 +5,7 @@
#pragma once
#include <set>
+#include <cstring>
#include <QDateTime>
#include <QByteArray>
#include <QString>
@@ -248,27 +249,44 @@ struct CompositeGlyphInfo
{
struct SubGlyph
{
- enum PositionType
+ enum PositionType : uint8_t
{
PT_Offset, // Child's points are added with a xy-offset
PT_Align // One point of the child is aligned with one point of the
parent
};
+ enum TransformationType : uint8_t
+ {
+ TT_UniformScale, // uniform scale for x- and y-axis
+ TT_XYScale, // separate scale for x- and y-axis
+ TT_Matrix // 2x2 matrix
+ };
unsigned short index;
unsigned short flag;
PositionType positionType;
// For PT_Offset: <deltaX, deltaY>
// For PT_Align: <childPoint, parentPoint>
std::pair<short, short> position;
+ bool positionScaled;
+ TransformationType transformationType;
+ // For TT_UniformScale: transformation[0] is the scale
+ // For TT_XYScale: transformation[0]: x-scale; transformation[1]: y-scale
+ // For TT_Matrix: transformation is layouted as
+ // [xscale, scale01, scale10, yscale]
+ double transformation[4];
+
SubGlyph(unsigned short index,
unsigned short flag,
PositionType positionType,
- std::pair<short, short> position)
+ std::pair<short, short> position,
+ bool positionScaled)
: index(index),
flag(flag),
positionType(positionType),
- position(std::move(position))
- { }
+ position(std::move(position)),
+ positionScaled(positionScaled)
+ {
+ }
friend bool
@@ -278,7 +296,11 @@ struct CompositeGlyphInfo
return lhs.index == rhs.index
&& lhs.flag == rhs.flag
&& lhs.positionType == rhs.positionType
- && lhs.position == rhs.position;
+ && lhs.position == rhs.position
+ && lhs.positionScaled == rhs.positionScaled
+ && lhs.transformationType == rhs.transformationType
+ && !std::memcmp(lhs.transformation, rhs.transformation,
+ 4 * sizeof(double));
}
diff --git a/src/ftinspect/models/fontinfomodels.cpp
b/src/ftinspect/models/fontinfomodels.cpp
index ea63e03..107c42d 100644
--- a/src/ftinspect/models/fontinfomodels.cpp
+++ b/src/ftinspect/models/fontinfomodels.cpp
@@ -571,6 +571,53 @@ CompositeGlyphsInfoModel::parent(const QModelIndex& child)
const
}
+QString
+generatePositionTransformationText(CompositeGlyphInfo::SubGlyph const& info)
+{
+ QString result;
+ switch (info.transformationType)
+ {
+ case CompositeGlyphInfo::SubGlyph::TT_UniformScale:
+ result += QString("scale: %1, ")
+ .arg(QString::number(info.transformation[0]));
+ break;
+ case CompositeGlyphInfo::SubGlyph::TT_XYScale:
+ result += QString("xy scale: (%1, %2), ")
+ .arg(QString::number(info.transformation[0]),
+ QString::number(info.transformation[1]));
+ break;
+ case CompositeGlyphInfo::SubGlyph::TT_Matrix:
+ result += QString("2x2 scale: [%1, %2; %3, %4], ")
+ .arg(QString::number(info.transformation[0]),
+ QString::number(info.transformation[1]),
+ QString::number(info.transformation[2]),
+ QString::number(info.transformation[3]));
+ break;
+ }
+
+ auto pos = info.position;
+ switch (info.positionType)
+ {
+ case CompositeGlyphInfo::SubGlyph::PT_Offset:
+ if (info.positionScaled)
+ result += QString("scaled offset: (%1, %2)")
+ .arg(QString::number(info.position.first),
+ QString::number(info.position.second));
+ else
+ result += QString("offset: (%1, %2)")
+ .arg(QString::number(info.position.first),
+ QString::number(info.position.second));
+ break;
+ case CompositeGlyphInfo::SubGlyph::PT_Align:
+ result += QString("anchor points: %1 (parent) <- %2 (this glyph)")
+ .arg(QString::number(info.position.first),
+ QString::number(info.position.second));
+ break;
+ }
+ return result;
+}
+
+
QVariant
CompositeGlyphsInfoModel::data(const QModelIndex& index,
int role) const
@@ -584,25 +631,6 @@ CompositeGlyphsInfoModel::data(const QModelIndex& index,
auto& n = nodes_[id];
auto glyphIdx = n.glyphIndex;
- if (role == Qt::ToolTipRole && index.column() == CGIM_Position)
- {
- if (!n.subGlyphInfo)
- return {};
- auto pos = n.subGlyphInfo->position;
- switch (n.subGlyphInfo->positionType)
- {
- case CompositeGlyphInfo::SubGlyph::PT_Offset:
- return QString("Add a offset (%1, %2) to the subglyph's points")
- .arg(pos.first)
- .arg(pos.second);
- case CompositeGlyphInfo::SubGlyph::PT_Align:
- return QString("Align parent's point %1 to subglyph's point %2")
- .arg(pos.first)
- .arg(pos.second);
- }
- return {};
- }
-
if (role == Qt::DecorationRole && index.column() == CGIM_Glyph)
{
auto glyphIndex = n.glyphIndex;
@@ -628,19 +656,12 @@ CompositeGlyphsInfoModel::data(const QModelIndex& index,
case CGIM_Flag:
if (!n.subGlyphInfo)
return {};
- return QString::number(n.subGlyphInfo->flag, 16).rightJustified(4, '0');
- case CGIM_Position:
+ return QString("0x%1").arg(n.subGlyphInfo->flag, 4, 16, QLatin1Char('0'));
+ case CGIM_PositionTransformation:
{
if (!n.subGlyphInfo)
return {};
- auto pos = n.subGlyphInfo->position;
- switch (n.subGlyphInfo->positionType)
- {
- case CompositeGlyphInfo::SubGlyph::PT_Offset:
- return QString("Offset (%1, %2)").arg(pos.first).arg(pos.second);
- case CompositeGlyphInfo::SubGlyph::PT_Align:
- return QString("Align %1 -> %2").arg(pos.first).arg(pos.second);
- }
+ return generatePositionTransformationText(*n.subGlyphInfo);
}
default:;
}
@@ -665,8 +686,8 @@ CompositeGlyphsInfoModel::headerData(int section,
return tr("Glyph");
case CGIM_Flag:
return tr("Flags");
- case CGIM_Position:
- return tr("Position");
+ case CGIM_PositionTransformation:
+ return tr("Position and Transformation");
default:;
}
return {};
diff --git a/src/ftinspect/models/fontinfomodels.hpp
b/src/ftinspect/models/fontinfomodels.hpp
index 22d4aab..ab73c80 100644
--- a/src/ftinspect/models/fontinfomodels.hpp
+++ b/src/ftinspect/models/fontinfomodels.hpp
@@ -259,9 +259,9 @@ public:
enum Columns : int
{
- CGIM_Glyph = 0, // TODO: transformation, scale? consider more flags?
+ CGIM_Glyph = 0,
CGIM_Flag = 1,
- CGIM_Position = 2,
+ CGIM_PositionTransformation = 2,
CGIM_Max
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] master 9a746ee 31/41: [ftinspect] Add transformation and scaling info to the composite glyph view.,
Werner Lemberg <=