Skip to content
Commits on Source (2)
  • Charlie Jiang's avatar
    [ftinspect] Fix named instances switching. · b29e5106
    Charlie Jiang authored
    * src/ftinspect/engine/mmgx.cpp, src/ftinspect/engine/mmgx.hpp:
      Load the default values of MMGX axes from the named instance instead of
      the global default one.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Switch the named instance using `FT_Set_Named_Instance` when loading
      fonts.
    b29e5106
  • Charlie Jiang's avatar
    [ftinspect] Fix default named instance handling. · d966a3a2
    Charlie Jiang authored
    Now the named instance selector no longer doubles the default named instance.
    `FT_Get_Default_Named_Instance` is used to get the default NI index.
    The default one is labeled as " (default)".
    
    * src/ftinspect/widgets/tripletselector.cpp: Properly handle the new 1-based
      named instance indices. Label the default NI correctly.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `Engine::defualtNamedInstanceIndex`.
    
    * src/ftinspect/engine/mmgx.cpp: Change comments.
    d966a3a2
......@@ -71,6 +71,7 @@ FaceID::operator<(const FaceID& other) const
// font, face, and named instance indices. Getting a key from a value is
// slow, but this must be done only once, since `faceRequester` is only
// called if the font is not yet in the cache.
// Note: Instance indices start from 1, and 0 is used to indicate no MM/GX handling.
FT_Error
faceRequester(FTC_FaceID ftcFaceID,
......@@ -101,8 +102,7 @@ faceRequester(FTC_FaceID ftcFaceID,
QString font = engine->fontFileManager_[faceID.fontIndex].filePath();
long faceIndex = faceID.faceIndex;
if (faceID.namedInstanceIndex > 0)
faceIndex += faceID.namedInstanceIndex << 16;
faceIndex += (faceID.namedInstanceIndex) << 16;
*faceP = NULL;
return FT_New_Face(library,
......@@ -227,8 +227,8 @@ int
Engine::numberOfNamedInstances(int fontIndex,
long faceIndex)
{
// We return `n` named instances plus one;
// instance index 0 represents a face without a named instance selected.
// With the new `FT_Get_Default_Named_Instance` func, we no longer to return
// one more entries.
int numNamedInstances = -1;
if (fontIndex < 0)
return -1;
......@@ -237,7 +237,7 @@ Engine::numberOfNamedInstances(int fontIndex,
[&](FT_Face face)
{
numNamedInstances
= static_cast<int>((face->style_flags >> 16) + 1);
= static_cast<int>((face->style_flags >> 16));
});
return numNamedInstances;
......@@ -264,6 +264,25 @@ Engine::namedInstanceName(int fontIndex,
}
unsigned
Engine::defaultNamedInstanceIndex(int fontIndex,
int faceIndex)
{
if (fontIndex < 0)
return 0;
unsigned ret = 0;
withFace(FaceID(fontIndex, faceIndex, 0),
[&](FT_Face face)
{
if (FT_Get_Default_Named_Instance(face, &ret) != 0)
{
// XXX error handling?
}
});
return ret;
}
bool
Engine::currentFontTricky()
{
......@@ -359,6 +378,8 @@ Engine::loadFont(int fontIndex,
else
fontType_ = FontType_Other;
switchNamedInstance(namedInstanceIndex);
curCharMaps_.clear();
curCharMaps_.reserve(ftFallbackFace_->num_charmaps);
for (int i = 0; i < ftFallbackFace_->num_charmaps; i++)
......@@ -366,7 +387,8 @@ Engine::loadFont(int fontIndex,
SFNTName::get(this, curSFNTNames_);
loadPaletteInfos();
curMMGXState_ = MMGXAxisInfo::get(this, curMMGXAxes_);
curMMGXState_ = MMGXAxisInfo::get(
this, static_cast<unsigned>(namedInstanceIndex), curMMGXAxes_);
}
curNumGlyphs_ = numGlyphs;
......@@ -1035,4 +1057,25 @@ Engine::loadPaletteInfos()
}
void
Engine::switchNamedInstance(int index)
{
if (!ftFallbackFace_ || !FT_HAS_MULTIPLE_MASTERS(ftFallbackFace_))
return;
auto err = FT_Set_Named_Instance(ftFallbackFace_, index);
if (err)
{
// XXX error handling
}
if (ftSize_)
{
err = FT_Set_Named_Instance(ftSize_->face, index);
if (err)
{
// XXX error handling
}
}
}
// end of engine.cpp
......@@ -145,6 +145,8 @@ public:
QString namedInstanceName(int fontIndex,
long faceIndex,
int index);
unsigned defaultNamedInstanceIndex(int fontIndex,
int faceIndex);
bool currentFontTricky();
bool currentFontBitmapOnly();
......@@ -286,6 +288,7 @@ private:
void queryEngine();
void loadPaletteInfos();
void switchNamedInstance(int index);
// It is safe to put the implementation into the corresponding cpp file.
template <class Func>
......
......@@ -10,7 +10,8 @@
MMGXState
MMGXAxisInfo::get(Engine* engine,
MMGXAxisInfo::get(Engine* engine,
unsigned namedInstanceIndex,
std::vector<MMGXAxisInfo>& infos)
{
auto face = engine->currentFallbackFtFace();
......@@ -37,6 +38,12 @@ MMGXAxisInfo::get(Engine* engine,
return state;
}
FT_Var_Named_Style* namedInstance = nullptr;
// named instance index starts from 1, but we need to reference using a
// 0-based index.
if (namedInstanceIndex > 0 && namedInstanceIndex <= mm->num_namedstyles)
namedInstance = &mm->namedstyle[namedInstanceIndex - 1];
infos.resize(mm->num_axis);
auto& sfnt = engine->currentFontSFNTNames();
......@@ -54,6 +61,9 @@ MMGXAxisInfo::get(Engine* engine,
FT_Get_Var_Axis_Flags(mm, i, &flags);
info.hidden = (flags & FT_VAR_AXIS_FLAG_HIDDEN) != 0;
if (namedInstance)
info.def = namedInstance->coords[i] / 65536.0;
auto nameSet = false;
if (state == MMGXState::GX_OVF)
{
......
......@@ -33,6 +33,7 @@ struct MMGXAxisInfo
bool isMM;
static MMGXState get(Engine* engine,
unsigned namedInstanceIndex,
std::vector<MMGXAxisInfo>& infos);
......
......@@ -162,7 +162,7 @@ TripletSelector::repopulateNamedInstances(bool fontSwitched)
newFaces.reserve(newSize);
for (long i = 0; i < newSize; i++)
{
newFaces.emplace_back(engine_->namedInstanceName(fontIndex, faceIndex, i));
newFaces.emplace_back(engine_->namedInstanceName(fontIndex, faceIndex, i + 1));
if (!needToRecreate && newFaces[i] != niComboBox_->itemData(i))
needToRecreate = true;
}
......@@ -181,16 +181,19 @@ TripletSelector::repopulateNamedInstances(bool fontSwitched)
QSignalBlocker blk3(niComboBox_);
niComboBox_->clear();
for (long i = 0; i < newSize; i++)
// Returned index starts from 1, therefore minus 1.
auto defaultId = engine_->defaultNamedInstanceIndex(fontIndex, faceIndex) - 1;
for (unsigned i = 0; i < static_cast<unsigned>(newSize); i++)
{
auto& name = newFaces[i];
auto displayName = QString("%1: %2").arg(i).arg(name);
if (i == 0)
displayName = "* " + displayName;
auto displayName = QString("%1: %2").arg(i + 1).arg(name);
if (i == defaultId)
displayName = displayName + " (default)";
niComboBox_->addItem(displayName, name);
}
niComboBox_->setCurrentIndex(0);
if (defaultId >= 0 && newSize > 0)
niComboBox_->setCurrentIndex(static_cast<int>(defaultId));
// Note: no signal is emitted from any combobox until this block ends.
}
......@@ -460,10 +463,9 @@ TripletSelector::loadTriplet()
if (faceIndex < 0)
faceIndex = 0;
if (instanceIndex < 0)
instanceIndex = 0;
engine_->loadFont(fontIndex, faceIndex, instanceIndex);
if (instanceIndex < 0 || niComboBox_->count() == 0)
instanceIndex = -1; // No instance available.
engine_->loadFont(fontIndex, faceIndex, instanceIndex + 1);
// TODO: This may mess up with bitmap-only fonts.
if (!engine_->fontValid())
......