Skip to content
Commits on Source (6)
  • Jouk Jansen's avatar
    f290eb04
  • Alexei Podtelezhnikov's avatar
  • Charlie Jiang's avatar
    [ftinspect] Fix the glyph index selector layout when the window resizes. · 2186a044
    Charlie Jiang authored
    Fixes #26. When the window resizes, the invisible tabs don't get notified.
    Therefore, when the active tab changes, we need to trigger a manual
    relayouting of invisible tabs.
    
    * src/ftinspect/widgets/glyphindexselector.hpp,
      src/ftinspect/widgets/glyphindexselector.cpp:
      Extract public method `relayoutNavigation` from `resizeEvent`.
    
    * src/ftinspect/panels/abstracttab.hpp: Add `relayout` virtual method.
    
    * src/ftinspect/maingui.cpp: Call `AbstractTab::relayout` on the new tab
      when the active tab changes.
    
    * src/ftinspect/panels/singular.cpp, src/ftinspect/panels/singular.hpp,
      src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      Implement `relayout` method and call `relayoutNavigation` of the glyph
      index selector in `relayout`.
    2186a044
  • Alexei Podtelezhnikov's avatar
  • Charlie Jiang's avatar
    [ftinspect] Fix named instances switching. · f563855d
    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.
    f563855d
  • Charlie Jiang's avatar
    [ftinspect] Fix default named instance handling. · 399eb8cf
    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.
    399eb8cf
......@@ -1018,6 +1018,9 @@
"\n"
"Usage: ftbench [options] fontname\n"
"\n"
" -a \"axis1 axis2 ...\"\n"
" Specify the design coordinates for each, if any,\n"
" Multiple Master axis at start-up.\n"
" -C Compare with cached version (if available).\n"
" -c N Use at most N iterations for each test\n"
" (0 means time limited).\n"
......
......@@ -925,7 +925,7 @@
FT_Fixed* coords;
const char* ps_name;
FT_Long instance_count;
FT_UInt instance_count;
FT_UInt default_named_instance;
FT_Var_Named_Style* named_styles;
......@@ -957,14 +957,14 @@
/* Show named instances. */
instance_count = face->style_flags >> 16;
instance_count = (FT_UInt)face->style_flags >> 16;
named_styles = mm->namedstyle;
FT_Get_Default_Named_Instance( face, &default_named_instance );
default_named_instance--; /* `named_styles` is a zero-based array */
printf( "\n" );
printf( " named instances (%lu)\n", instance_count );
printf( " named instances (%u)\n", instance_count );
for ( i = 0; i < instance_count; i++ )
{
......
......@@ -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);
......
......@@ -198,6 +198,8 @@ MainGUI::switchTab()
else
leftWidget_->setVisible(!isComparator);
tabs_[tabWidget_->currentIndex()]->relayout();
reloadCurrentTabFont();
if (current == continuousTab_
......
......@@ -16,6 +16,7 @@ public:
virtual void repaintGlyph() = 0;
virtual void reloadFont() = 0;
virtual void relayout() {}
};
......
......@@ -65,6 +65,13 @@ ContinuousTab::reloadFont()
}
void
ContinuousTab::relayout()
{
indexSelector_->relayoutNavigation();
}
void
ContinuousTab::applySettings()
{
......
......@@ -46,6 +46,7 @@ public:
void repaintGlyph() override;
void reloadFont() override;
void relayout() override;
void highlightGlyph(int index);
void applySettings();
......
......@@ -459,6 +459,13 @@ SingularTab::reloadFont()
}
void
SingularTab::relayout()
{
indexSelector_->relayoutNavigation();
}
void
SingularTab::setCurrentGlyphAndSize(int glyphIndex,
double sizePoint)
......
......@@ -46,6 +46,7 @@ public:
void repaintGlyph() override;
void reloadFont() override;
void relayout() override;
// The size remains unchanged if `sizePoint` <= 0.
void setCurrentGlyphAndSize(int glyphIndex,
double sizePoint);
......
......@@ -20,6 +20,20 @@ GlyphIndexSelector::GlyphIndexSelector(QWidget* parent)
}
void
GlyphIndexSelector::relayoutNavigation()
{
auto minimumWidth = minimumSizeHint().width();
if (toEndButton_->isVisible())
{
if (width() < minimumWidth)
navigationWidget_->setVisible(false);
}
else if (navigationWidget_->minimumSizeHint().width() + minimumWidth <= width())
navigationWidget_->setVisible(true);
}
void
GlyphIndexSelector::setMinMax(int min,
int max)
......@@ -87,15 +101,7 @@ void
GlyphIndexSelector::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
auto minimumWidth = minimumSizeHint().width();
if (toEndButton_->isVisible())
{
if (width() < minimumWidth)
navigationWidget_->setVisible(false);
}
else if (navigationWidget_->minimumSizeHint().width() + minimumWidth
<= width())
navigationWidget_->setVisible(true);
relayoutNavigation();
}
......
......@@ -24,6 +24,8 @@ public:
GlyphIndexSelector(QWidget* parent);
~GlyphIndexSelector() override = default;
void relayoutNavigation();
// Never triggers repaint!
void setMinMax(int min,
int max);
......
......@@ -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())
......
......@@ -9,6 +9,12 @@ $!------------------------------------------------------------------------------
$!
$ on error then goto err_exit
$!
$! Get platform
$ vax = f$getsyi("ARCH_NAME").eqs. "VAX"
$ axp = f$getsyi("ARCH_NAME").eqs. "Alpha"
$ ia64 = f$getsyi("ARCH_NAME").eqs. "IA64"
$ x86_64 = f$getsyi("ARCH_NAME").eqs. "x86_64"
$!
$! Just some general constants
$!
$ Make = ""
......@@ -34,16 +40,25 @@ $!
$! Create option file
$!
$ open/write optf 'optfile'
$ If f$getsyi("HW_MODEL") .gt. 1024
$ If .not. vax
$ Then
$ write optf "[-.freetype2.lib]freetype2shr.exe/share"
$ else
$ write optf "[-.freetype2.lib]freetype.olb/lib"
$ endif
$ gosub check_create_vmslib
$ write optf "sys$library:libbz2.olb/lib"
$ write optf "sys$library:libpng.olb/lib"
$ write optf "sys$library:libz.olb/lib"
$!
$!
$! Check external libraries
$!
$ have_png = f$search("sys$library:libpng.olb") .nes. ""
$ have_bz2 = f$search("sys$library:libbz2.olb") .nes. ""
$ have_z = f$search("sys$library:libz.olb") .nes. ""
$ have_harfbuzz = f$search("sys$library:libharfbuzz.olb") .nes. ""
$ if ( have_harfbuzz ) then write optf "sys$library:libharfbuzz.olb/lib"
$ if ( have_bz2 ) then write optf "sys$library:libbz2.olb/lib"
$ if ( have_png ) then write optf "sys$library:libpng.olb/lib"
$ if ( have_z ) then write optf "sys$library:libz.olb/lib"
$ write optf "sys$share:decw$xlibshr.exe/share"
$ close optf
$!
......@@ -122,7 +137,7 @@ GRAPHOBJ64 = $(OBJDIR)grobjs_64.obj, \
# C flags
CFLAGS = $(CCOPT)$(INCLUDES)/obj=$(OBJDIR)/define=("FT2_BUILD_LIBRARY=1")\
/warn=disable=("MACROREDEF","MAYLOSEDATA3")
/warn=(noinfo,disable=("MACROREDEF","MAYLOSEDATA3"))
.c.obj :
cc$(CFLAGS)/point=32/list=$(MMS$TARGET_NAME).lis/show=all $(MMS$SOURCE)
......@@ -286,20 +301,20 @@ $(OBJDIR)gblender.obj : $(GRAPHSRC)gblender.c
$(OBJDIR)gblblit.obj : $(GRAPHSRC)gblblit.c
$(OBJDIR)grinit.obj : $(GRAPHSRC)grinit.c
set def $(GRAPHSRC)
$(CC)$(CCOPT)/include=([.x11],[])/point=32/list/show=all\
$(CC)$(CCOPT)/warn=noinfo/include=([.x11],[])/point=32/list/show=all\
/define=(DEVICE_X11,"FT2_BUILD_LIBRARY=1")/obj=[-.objs] grinit.c
pipe link/map/full/exec=nl: [-.objs]grinit.obj | copy sys$input nl:
mc sys$library:vms_auto64 grinit.map grinit.lis
$(CC)$(CCOPT)/include=([.x11],[])/point=64/obj=[-.objs] grinit_64.c
$(CC)$(CCOPT)/warn=noinfo/include=([.x11],[])/point=64/obj=[-.objs] grinit_64.c
delete grinit_64.c;*
set def [-]
$(OBJDIR)grx11.obj : $(GRX11SRC)grx11.c
set def $(GRX11SRC)
$(CC)$(CCOPT)/include=([-])/point=32/list/show=all\
$(CC)$(CCOPT)/warn=noinfo/include=([-])/point=32/list/show=all\
/define=(DEVICE_X11,"FT2_BUILD_LIBRARY=1")/obj=[--.objs] grx11.c
pipe link/map/full/exec=nl: [--.objs]grx11.obj | copy sys$input nl:
mc sys$library:vms_auto64 grx11.map grx11.lis
$(CC)$(CCOPT)/include=([-])/point=64/obj=[--.objs] grx11_64.c
$(CC)$(CCOPT)/warn=noinfo/include=([-])/point=64/obj=[--.objs] grx11_64.c
delete grx11_64.c;*
set def [--]
$(OBJDIR)grdevice.obj : $(GRAPHSRC)grdevice.c
......