freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype-demos][gsoc-2022-chariri-final] 2 commits: [ftin


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-final] 2 commits: [ftinspect] Rewrite `MainGUI`.
Date: Sat, 03 Sep 2022 16:26:04 +0000

Charlie Jiang pushed to branch gsoc-2022-chariri-final at FreeType / FreeType Demo Programs

Commits:

  • 47238404
    by Charlie Jiang at 2022-09-04T00:23:30+08:00
    [ftinspect] Rewrite `MainGUI`.
    
    Note: This commit compiles, but the main view is removed, so you will get a
    blank right panel. The singular view will be added back with major changes
    in the next commit.
    
    This commit mainly introduces below changes:
    
    1. The original `MainGUI` contains almost all GUI elements. Most of them are
       taken out to modular components. The current `MainGUI` serves only as
       a skeleton provides coordinate between components, greatly shortened.
       It also provides some auxiliary code such as calling to file chooser.
    2. The left panel is moved to `SettingPanel` class. The current
       `settingpanel.[ch]pp` are directly modified from the latest code, so they
       contains some options not implemented in the `Engine`.
       Structural code that is only added accompanying later change is removed,
       such as the comparator mode. Such code will be added back with the
       related feature. However, code for unimplemented options are simply
       commented out.
    3. The main part is transformed into a tabbed view. The original code is
       removed. Refactored, it will be added back in the next commit.
    4. The navigation buttons (Next/Prev Font/Face/NI) are changed into the new
       triplet-selector, which is a major UI improvement.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp: As described.
    
    * src/ftinspect/panels/abstracttab.hpp: Add `AbstractTab` which is an
      interface for all tabs listening for font reloading and repainting.
    
    * src/ftinspect/panels/settingpanel.cpp,
      src/ftinspect/panels/settingpanel.hpp:
      As described, this is the left panel. This requires intensive reviewing
      since many bugs had rooted here.
    
    * src/ftinspect/widgets/tripletselector.cpp,
      src/ftinspect/widgets/tripletselector.hpp:
      As described, this is the triplet (Font/Subface/NI) selector.
      This component is also responsible for repopulating triplet information
      and keep up with the font file change (i.e. the
      `FontFileManager::currentFileChanged` event is captured here).
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `fontValid` and `namedInstanceName` since `TripletSelector` requires
      them. However, they'll subject to change later.
    
    * src/ftinspect/ftinspect.cpp: Remove call to `MainGUI::setDefaults`.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
    
  • 14556570
    by Charlie Jiang at 2022-09-04T00:23:36+08:00
    [ftinspect] Add the `SingularTab` and related widgets.
    
    This introduces the new singular tab. However, because the new tab heavily
    depend on the new engine structure, it's current not functional. No bitmap
    or outline will be displayed. This would be fixed after the `Engine` was
    refactored in the next commit.
    
    The new singular tab has the size and glyph index selector moved out as
    modular widgets to be reused.
    
    The new scroll and shortcut behaviours are introduced in this commit, which
    depend on scroll events introduced in the custom `QGraphicsViewx`.
    
    The infinity panning of grid is implemented mainly via
    `SingularTab::updateGrid` and `Grid::updateRect`.
    
    This commit is introducing new features since it would be unfavorable to
    "backport" old version of glyph components, and add those new features in
    future commits - this is way too complex.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `currentFontNumberOfGlyphs` and `dpi` functions.
    
    * src/ftinspect/widgets/fontsizeselector.cpp,
      src/ftinspect/widgets/fontsizeselector.hpp:
      This is the new font size selector to replace the old size/DPI/zoom boxes.
      This widget is capable of handling wheel and key events delegated from
      other widgets.
      The support for fixed sizes and bitmap-only font is not yet added.
    
    * src/ftinspect/widgets/glyphindexselector.cpp,
      src/ftinspect/widgets/glyphindexselector.hpp:
      This is the new glyph index selector to replace the old navi buttons.
      This selector is aware of index min/max, consists of a group of navi
      buttons, a text box (actually a spin box without buttons) to directly
      input glyph index.
    
    * src/ftinspect/glyphcomponents/graphicsdefault.cpp,
      src/ftinspect/glyphcomponents/graphicsdefault.hpp:
      This struct contains all default graphical settings (mainly for singular
      view, e.g. the grid line color).
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp:
      Add the new tab into the main window.
    
    * src/ftinspect/glyphcomponents/glyphbitmap.cpp,
      src/ftinspect/glyphcomponents/glyphbitmap.hpp:
      This will now delegate rendering to the engine instead of doing rendering
      itself. However, since the rendering part of the `Engine` is not
      implemented, code initializing `image_` is left commented.
      Also add another constructor for initializing directly from a `QImage`.
    
    * src/ftinspect/glyphcomponents/glyphoutline.cpp,
      src/ftinspect/glyphcomponents/glyphoutline.hpp,
      src/ftinspect/glyphcomponents/glyphpointnumbers.cpp,
      src/ftinspect/glyphcomponents/glyphpointnumbers.hpp,
      src/ftinspect/glyphcomponents/glyphpoints.cpp,
      src/ftinspect/glyphcomponents/glyphpoints.hpp:
      Constructors of those items now accept a `FT_Glyph` instead of
      `FT_Outline`. The conversion is done inside the view, and the view won't
      be displayed if the glyph isn't outline glyph.
      This simplifies the code of `SingularTab`.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
    

30 changed files:

Changes:

  • src/ftinspect/CMakeLists.txt
    ... ... @@ -28,10 +28,17 @@ add_executable(ftinspect
    28 28
       "glyphcomponents/glyphpointnumbers.cpp"
    
    29 29
       "glyphcomponents/glyphpoints.cpp"
    
    30 30
       "glyphcomponents/grid.cpp"
    
    31
    +  "glyphcomponents/graphicsdefault.cpp"
    
    31 32
     
    
    32 33
       "widgets/customwidgets.cpp"
    
    34
    +  "widgets/tripletselector.cpp"
    
    35
    +  "widgets/glyphindexselector.cpp"
    
    36
    +  "widgets/fontsizeselector.cpp"
    
    33 37
     
    
    34 38
       "models/customcomboboxmodels.cpp"
    
    39
    +
    
    40
    +  "panels/settingpanel.cpp"
    
    41
    +  "panels/singular.cpp"
    
    35 42
     )
    
    36 43
     target_link_libraries(ftinspect
    
    37 44
       Qt5::Core Qt5::Widgets
    

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -237,6 +237,50 @@ Engine::numberOfNamedInstances(int fontIndex,
    237 237
     }
    
    238 238
     
    
    239 239
     
    
    240
    +QString
    
    241
    +Engine::namedInstanceName(int fontIndex, long faceIndex, int index)
    
    242
    +{
    
    243
    +  if (fontIndex < 0)
    
    244
    +    return {};
    
    245
    +
    
    246
    +  FT_Face face;
    
    247
    +  QString name;
    
    248
    +
    
    249
    +  // search triplet (fontIndex, faceIndex, index)
    
    250
    +  FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>
    
    251
    +                           (faceIDMap_.value(FaceID(fontIndex,
    
    252
    +                                                    faceIndex,
    
    253
    +                                                    index)));
    
    254
    +  if (ftcFaceID)
    
    255
    +  {
    
    256
    +    // found
    
    257
    +    if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
    
    258
    +      name = QString("%1 %2")
    
    259
    +               .arg(face->family_name)
    
    260
    +               .arg(face->style_name);
    
    261
    +  }
    
    262
    +  else
    
    263
    +  {
    
    264
    +    // not found; try to load triplet (fontIndex, faceIndex, index)
    
    265
    +    ftcFaceID = reinterpret_cast<FTC_FaceID>(faceCounter_);
    
    266
    +    faceIDMap_.insert(FaceID(fontIndex, faceIndex, index),
    
    267
    +                      faceCounter_++);
    
    268
    +
    
    269
    +    if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
    
    270
    +      name = QString("%1 %2")
    
    271
    +               .arg(face->family_name)
    
    272
    +               .arg(face->style_name);
    
    273
    +    else
    
    274
    +    {
    
    275
    +      faceIDMap_.remove(FaceID(fontIndex, faceIndex, 0));
    
    276
    +      faceCounter_--;
    
    277
    +    }
    
    278
    +  }
    
    279
    +
    
    280
    +  return name;
    
    281
    +}
    
    282
    +
    
    283
    +
    
    240 284
     int
    
    241 285
     Engine::loadFont(int fontIndex,
    
    242 286
                      long faceIndex,
    
    ... ... @@ -299,6 +343,7 @@ Engine::loadFont(int fontIndex,
    299 343
           fontType_ = FontType_TrueType;
    
    300 344
       }
    
    301 345
     
    
    346
    +  curNumGlyphs_ = numGlyphs;
    
    302 347
       return numGlyphs;
    
    303 348
     }
    
    304 349
     
    
    ... ... @@ -394,6 +439,14 @@ Engine::numberOfOpenedFonts()
    394 439
     }
    
    395 440
     
    
    396 441
     
    
    442
    +bool
    
    443
    +Engine::fontValid()
    
    444
    +{
    
    445
    +  // TODO: use fallback font
    
    446
    +  return ftSize_ != NULL;
    
    447
    +}
    
    448
    +
    
    449
    +
    
    397 450
     void
    
    398 451
     Engine::openFonts(QStringList fontFileNames)
    
    399 452
     {
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -85,13 +85,20 @@ public:
    85 85
       int numberOfOpenedFonts();
    
    86 86
     
    
    87 87
       // (for current fonts)
    
    88
    +  bool fontValid();
    
    88 89
       int currentFontType() const { return fontType_; }
    
    89 90
       const QString& currentFamilyName() { return curFamilyName_; }
    
    90 91
       const QString& currentStyleName() { return curStyleName_; }
    
    92
    +  int currentFontNumberOfGlyphs() { return curNumGlyphs_; }
    
    93
    +
    
    91 94
       QString glyphName(int glyphIndex);
    
    92 95
       long numberOfFaces(int fontIndex);
    
    93 96
       int numberOfNamedInstances(int fontIndex,
    
    94 97
                                  long faceIndex);
    
    98
    +  QString namedInstanceName(int fontIndex, long faceIndex, int index);
    
    99
    +
    
    100
    +  // (settings)
    
    101
    +  int dpi() { return dpi_; }
    
    95 102
     
    
    96 103
       //////// Setters (direct or indirect)
    
    97 104
     
    
    ... ... @@ -138,6 +145,7 @@ private:
    138 145
     
    
    139 146
       QString curFamilyName_;
    
    140 147
       QString curStyleName_;
    
    148
    +  int curNumGlyphs_ = -1;
    
    141 149
     
    
    142 150
       FT_Library library_;
    
    143 151
       FTC_Manager cacheManager_;
    

  • src/ftinspect/ftinspect.cpp
    ... ... @@ -23,7 +23,6 @@ main(int argc,
    23 23
     
    
    24 24
       Engine engine;
    
    25 25
       MainGUI gui(&engine);
    
    26
    -  gui.setDefaults();
    
    27 26
     
    
    28 27
       gui.show();
    
    29 28
     
    

  • src/ftinspect/glyphcomponents/glyphbitmap.cpp
    ... ... @@ -5,47 +5,44 @@
    5 5
     
    
    6 6
     #include "glyphbitmap.hpp"
    
    7 7
     
    
    8
    +#include "../engine/engine.hpp"
    
    9
    +
    
    8 10
     #include <cmath>
    
    11
    +#include <utility>
    
    12
    +#include <qevent.h>
    
    9 13
     #include <QPainter>
    
    10 14
     #include <QStyleOptionGraphicsItem>
    
    15
    +#include <freetype/ftbitmap.h>
    
    11 16
     
    
    12 17
     
    
    13
    -GlyphBitmap::GlyphBitmap(FT_Outline* outline,
    
    14
    -                         FT_Library lib,
    
    15
    -                         FT_Pixel_Mode pxlMode,
    
    16
    -                         const QVector<QRgb>& monoColorTbl,
    
    17
    -                         const QVector<QRgb>& grayColorTbl)
    
    18
    -: library_(lib),
    
    19
    -  pixelMode_(pxlMode),
    
    20
    -  monoColorTable_(monoColorTbl),
    
    21
    -  grayColorTable_(grayColorTbl)
    
    18
    +GlyphBitmap::GlyphBitmap(QImage* image,
    
    19
    +                         QRect rect)
    
    20
    +: image_(image),
    
    21
    +  boundingRect_(rect)
    
    22 22
     {
    
    23
    -  // make a copy of the outline since we are going to manipulate it
    
    24
    -  FT_Outline_New(library_,
    
    25
    -                 static_cast<unsigned int>(outline->n_points),
    
    26
    -                 outline->n_contours,
    
    27
    -                 &transformed_);
    
    28
    -  FT_Outline_Copy(outline, &transformed_);
    
    29
    -
    
    30
    -  FT_BBox cbox;
    
    31
    -  FT_Outline_Get_CBox(outline, &cbox);
    
    32
    -
    
    33
    -  cbox.xMin &= ~63;
    
    34
    -  cbox.yMin &= ~63;
    
    35
    -  cbox.xMax = (cbox.xMax + 63) & ~63;
    
    36
    -  cbox.yMax = (cbox.yMax + 63) & ~63;
    
    37
    -
    
    38
    -  // we shift the outline to the origin for rendering later on
    
    39
    -  FT_Outline_Translate(&transformed_, -cbox.xMin, -cbox.yMin);
    
    40
    -
    
    41
    -  boundingRect_.setCoords(cbox.xMin / 64, -cbox.yMax / 64,
    
    42
    -                  cbox.xMax / 64, -cbox.yMin / 64);
    
    23
    +
    
    24
    +}
    
    25
    +
    
    26
    +
    
    27
    +GlyphBitmap::GlyphBitmap(int glyphIndex, 
    
    28
    +                         FT_Glyph glyph,
    
    29
    +                         Engine* engine)
    
    30
    +{
    
    31
    +  QRect bRect;
    
    32
    +  image_ = NULL; // TODO: refactr Engine
    
    33
    +  //image_ = engine->renderingEngine()->tryDirectRenderColorLayers(glyphIndex,
    
    34
    +  //                                                               &bRect, true);
    
    35
    +
    
    36
    +  //if (!image_)
    
    37
    +  //  image_ = engine->renderingEngine()->convertGlyphToQImage(glyph, &bRect, 
    
    38
    +  //                                                           true);
    
    39
    +  boundingRect_ = bRect; // QRect to QRectF
    
    43 40
     }
    
    44 41
     
    
    45 42
     
    
    46 43
     GlyphBitmap::~GlyphBitmap()
    
    47 44
     {
    
    48
    -  FT_Outline_Done(library_, &transformed_);
    
    45
    +  delete image_;
    
    49 46
     }
    
    50 47
     
    
    51 48
     QRectF
    
    ... ... @@ -60,40 +57,9 @@ GlyphBitmap::paint(QPainter* painter,
    60 57
                        const QStyleOptionGraphicsItem* option,
    
    61 58
                        QWidget*)
    
    62 59
     {
    
    63
    -  FT_Bitmap bitmap;
    
    64
    -
    
    65
    -  int height = static_cast<int>(ceil(boundingRect_.height()));
    
    66
    -  int width = static_cast<int>(ceil(boundingRect_.width()));
    
    67
    -  QImage::Format format = QImage::Format_Indexed8;
    
    68
    -
    
    69
    -  // XXX cover LCD and color
    
    70
    -  if (pixelMode_ == FT_PIXEL_MODE_MONO)
    
    71
    -    format = QImage::Format_Mono;
    
    72
    -
    
    73
    -  QImage image(QSize(width, height), format);
    
    74
    -
    
    75
    -  if (pixelMode_ == FT_PIXEL_MODE_MONO)
    
    76
    -    image.setColorTable(monoColorTable_);
    
    77
    -  else
    
    78
    -    image.setColorTable(grayColorTable_);
    
    79
    -
    
    80
    -  image.fill(0);
    
    81
    -
    
    82
    -  bitmap.rows = static_cast<unsigned int>(height);
    
    83
    -  bitmap.width = static_cast<unsigned int>(width);
    
    84
    -  bitmap.buffer = image.bits();
    
    85
    -  bitmap.pitch = image.bytesPerLine();
    
    86
    -  bitmap.pixel_mode = pixelMode_;
    
    87
    -
    
    88
    -  FT_Error error = FT_Outline_Get_Bitmap(library_,
    
    89
    -                                         &transformed_,
    
    90
    -                                         &bitmap);
    
    91
    -  if (error)
    
    92
    -  {
    
    93
    -    // XXX error handling
    
    60
    +  if (!image_)
    
    94 61
         return;
    
    95
    -  }
    
    96
    -
    
    62
    +  
    
    97 63
       // `drawImage' doesn't work as expected:
    
    98 64
       // the larger the zoom, the more the pixel rectangle positions
    
    99 65
       // deviate from the grid lines
    
    ... ... @@ -102,16 +68,16 @@ GlyphBitmap::paint(QPainter* painter,
    102 68
                          image.convertToFormat(
    
    103 69
                            QImage::Format_ARGB32_Premultiplied));
    
    104 70
     #else
    
    105
    -  const qreal lod = option->levelOfDetailFromTransform(
    
    106
    -                              painter->worldTransform());
    
    71
    +  const qreal lod = QStyleOptionGraphicsItem::levelOfDetailFromTransform(
    
    72
    +    painter->worldTransform());
    
    107 73
     
    
    108 74
       painter->setPen(Qt::NoPen);
    
    109 75
     
    
    110
    -  for (int x = 0; x < image.width(); x++)
    
    111
    -    for (int y = 0; y < image.height(); y++)
    
    76
    +  for (int x = 0; x < image_->width(); x++)
    
    77
    +    for (int y = 0; y < image_->height(); y++)
    
    112 78
         {
    
    113 79
           // be careful not to lose the alpha channel
    
    114
    -      QRgb p = image.pixel(x, y);
    
    80
    +      QRgb p = image_->pixel(x, y);
    
    115 81
           painter->fillRect(QRectF(x + boundingRect_.left() - 1 / lod / 2,
    
    116 82
                                    y + boundingRect_.top() - 1 / lod / 2,
    
    117 83
                                    1 + 1 / lod,
    

  • src/ftinspect/glyphcomponents/glyphbitmap.hpp
    ... ... @@ -7,33 +7,34 @@
    7 7
     
    
    8 8
     #include <QGraphicsItem>
    
    9 9
     #include <QPen>
    
    10
    +#include <QPaintEvent>
    
    11
    +#include <QWidget>
    
    10 12
     
    
    11 13
     #include <ft2build.h>
    
    12 14
     #include <freetype/freetype.h>
    
    15
    +#include <freetype/ftglyph.h>
    
    13 16
     #include <freetype/ftoutln.h>
    
    14 17
     
    
    15 18
     
    
    19
    +class Engine;
    
    20
    +
    
    16 21
     class GlyphBitmap
    
    17 22
     : public QGraphicsItem
    
    18 23
     {
    
    19 24
     public:
    
    20
    -  GlyphBitmap(FT_Outline* outline,
    
    21
    -              FT_Library library,
    
    22
    -              FT_Pixel_Mode pixelMode,
    
    23
    -              const QVector<QRgb>& monoColorTable,
    
    24
    -              const QVector<QRgb>& grayColorTable);
    
    25
    -  ~GlyphBitmap();
    
    26
    -  QRectF boundingRect() const;
    
    25
    +  GlyphBitmap(QImage* image,
    
    26
    +              QRect rect);
    
    27
    +  GlyphBitmap(int glyphIndex,
    
    28
    +              FT_Glyph glyph,
    
    29
    +              Engine* engine);
    
    30
    +  ~GlyphBitmap() override;
    
    31
    +  QRectF boundingRect() const override;
    
    27 32
       void paint(QPainter* painter,
    
    28 33
                  const QStyleOptionGraphicsItem* option,
    
    29
    -             QWidget* widget);
    
    34
    +             QWidget* widget) override;
    
    30 35
     
    
    31 36
     private:
    
    32
    -  FT_Outline transformed_;
    
    33
    -  FT_Library library_;
    
    34
    -  unsigned char pixelMode_;
    
    35
    -  const QVector<QRgb>& monoColorTable_;
    
    36
    -  const QVector<QRgb>& grayColorTable_;
    
    37
    +  QImage* image_ = NULL;
    
    37 38
       QRectF boundingRect_;
    
    38 39
     };
    
    39 40
     
    

  • src/ftinspect/glyphcomponents/glyphoutline.cpp
    ... ... @@ -87,11 +87,17 @@ static FT_Outline_Funcs outlineFuncs =
    87 87
     } // extern "C"
    
    88 88
     
    
    89 89
     
    
    90
    -GlyphOutline::GlyphOutline(const QPen& outlineP,
    
    91
    -                           FT_Outline* outln)
    
    92
    -: outlinePen_(outlineP),
    
    93
    -  outline_(outln)
    
    90
    +GlyphOutline::GlyphOutline(const QPen& pen,
    
    91
    +                           FT_Glyph glyph)
    
    92
    +: outlinePen_(pen)
    
    94 93
     {
    
    94
    +  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    
    95
    +  {
    
    96
    +    outline_ = NULL;
    
    97
    +    return;
    
    98
    +  }
    
    99
    +  outline_ = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
    
    100
    +
    
    95 101
       FT_BBox cbox;
    
    96 102
     
    
    97 103
       qreal halfPenWidth = outlinePen_.widthF();
    
    ... ... @@ -117,6 +123,8 @@ GlyphOutline::paint(QPainter* painter,
    117 123
                         const QStyleOptionGraphicsItem*,
    
    118 124
                         QWidget*)
    
    119 125
     {
    
    126
    +  if (!outline_)
    
    127
    +    return;
    
    120 128
       painter->setPen(outlinePen_);
    
    121 129
     
    
    122 130
       QPainterPath path;
    

  • src/ftinspect/glyphcomponents/glyphoutline.hpp
    ... ... @@ -10,6 +10,7 @@
    10 10
     
    
    11 11
     #include <ft2build.h>
    
    12 12
     #include <freetype/freetype.h>
    
    13
    +#include <freetype/ftglyph.h>
    
    13 14
     #include <freetype/ftoutln.h>
    
    14 15
     
    
    15 16
     
    
    ... ... @@ -18,11 +19,11 @@ class GlyphOutline
    18 19
     {
    
    19 20
     public:
    
    20 21
       GlyphOutline(const QPen& pen,
    
    21
    -               FT_Outline* outline);
    
    22
    -  QRectF boundingRect() const;
    
    22
    +               FT_Glyph glyph);
    
    23
    +  QRectF boundingRect() const override;
    
    23 24
       void paint(QPainter* painter,
    
    24 25
                  const QStyleOptionGraphicsItem* option,
    
    25
    -             QWidget* widget);
    
    26
    +             QWidget* widget) override;
    
    26 27
     
    
    27 28
     private:
    
    28 29
       QPen outlinePen_;
    

  • src/ftinspect/glyphcomponents/glyphpointnumbers.cpp
    ... ... @@ -12,11 +12,17 @@
    12 12
     
    
    13 13
     GlyphPointNumbers::GlyphPointNumbers(const QPen& onP,
    
    14 14
                                          const QPen& offP,
    
    15
    -                                     FT_Outline* outln)
    
    15
    +                                     FT_Glyph glyph)
    
    16 16
     : onPen_(onP),
    
    17
    -  offPen_(offP),
    
    18
    -  outline_(outln)
    
    17
    +  offPen_(offP)
    
    19 18
     {
    
    19
    +  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    
    20
    +  {
    
    21
    +    outline_ = NULL;
    
    22
    +    return;
    
    23
    +  }
    
    24
    +  outline_ = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
    
    25
    +
    
    20 26
       FT_BBox cbox;
    
    21 27
     
    
    22 28
       FT_Outline_Get_CBox(outline_, &cbox);
    
    ... ... @@ -41,6 +47,8 @@ GlyphPointNumbers::paint(QPainter* painter,
    41 47
                              const QStyleOptionGraphicsItem* option,
    
    42 48
                              QWidget*)
    
    43 49
     {
    
    50
    +  if (!outline_)
    
    51
    +    return;
    
    44 52
       const qreal lod = option->levelOfDetailFromTransform(
    
    45 53
                                   painter->worldTransform());
    
    46 54
     
    

  • src/ftinspect/glyphcomponents/glyphpointnumbers.hpp
    ... ... @@ -10,6 +10,7 @@
    10 10
     
    
    11 11
     #include <ft2build.h>
    
    12 12
     #include <freetype/freetype.h>
    
    13
    +#include <freetype/ftglyph.h>
    
    13 14
     #include <freetype/ftoutln.h>
    
    14 15
     
    
    15 16
     
    
    ... ... @@ -19,11 +20,11 @@ class GlyphPointNumbers
    19 20
     public:
    
    20 21
       GlyphPointNumbers(const QPen& onPen,
    
    21 22
                         const QPen& offPen,
    
    22
    -                    FT_Outline* outline);
    
    23
    -  QRectF boundingRect() const;
    
    23
    +                    FT_Glyph glyph);
    
    24
    +  QRectF boundingRect() const override;
    
    24 25
       void paint(QPainter* painter,
    
    25 26
                  const QStyleOptionGraphicsItem* option,
    
    26
    -             QWidget* widget);
    
    27
    +             QWidget* widget) override;
    
    27 28
     
    
    28 29
     private:
    
    29 30
       QPen onPen_;
    

  • src/ftinspect/glyphcomponents/glyphpoints.cpp
    ... ... @@ -11,11 +11,17 @@
    11 11
     
    
    12 12
     GlyphPoints::GlyphPoints(const QPen& onP,
    
    13 13
                              const QPen& offP,
    
    14
    -                         FT_Outline* outln)
    
    14
    +                         FT_Glyph glyph)
    
    15 15
     : onPen_(onP),
    
    16
    -  offPen_(offP),
    
    17
    -  outline_(outln)
    
    16
    +  offPen_(offP)
    
    18 17
     {
    
    18
    +  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    
    19
    +  {
    
    20
    +    outline_ = NULL;
    
    21
    +    return;
    
    22
    +  }
    
    23
    +  outline_ = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
    
    24
    +
    
    19 25
       FT_BBox cbox;
    
    20 26
     
    
    21 27
       qreal halfPenWidth = qMax(onPen_.widthF(), offPen_.widthF()) / 2;
    
    ... ... @@ -41,6 +47,9 @@ GlyphPoints::paint(QPainter* painter,
    41 47
                        const QStyleOptionGraphicsItem* option,
    
    42 48
                        QWidget*)
    
    43 49
     {
    
    50
    +  if (!outline_)
    
    51
    +    return;
    
    52
    +
    
    44 53
       const qreal lod = option->levelOfDetailFromTransform(
    
    45 54
                                   painter->worldTransform());
    
    46 55
     
    

  • src/ftinspect/glyphcomponents/glyphpoints.hpp
    ... ... @@ -10,6 +10,7 @@
    10 10
     
    
    11 11
     #include <ft2build.h>
    
    12 12
     #include <freetype/freetype.h>
    
    13
    +#include <freetype/ftglyph.h>
    
    13 14
     #include <freetype/ftoutln.h>
    
    14 15
     
    
    15 16
     
    
    ... ... @@ -19,11 +20,11 @@ class GlyphPoints
    19 20
     public:
    
    20 21
       GlyphPoints(const QPen& onPen,
    
    21 22
                   const QPen& offPen,
    
    22
    -              FT_Outline* outline);
    
    23
    -  QRectF boundingRect() const;
    
    23
    +              FT_Glyph glyph);
    
    24
    +  QRectF boundingRect() const override;
    
    24 25
       void paint(QPainter* painter,
    
    25 26
                  const QStyleOptionGraphicsItem* option,
    
    26
    -             QWidget* widget);
    
    27
    +             QWidget* widget) override;
    
    27 28
     
    
    28 29
     private:
    
    29 30
       QPen onPen_;
    

  • src/ftinspect/glyphcomponents/graphicsdefault.cpp
    1
    +// graphicsdefault.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#include "graphicsdefault.hpp"
    
    6
    +
    
    7
    +GraphicsDefault* GraphicsDefault::instance_ = NULL;
    
    8
    +
    
    9
    +GraphicsDefault::GraphicsDefault()
    
    10
    +{
    
    11
    +  // XXX make this user-configurable
    
    12
    +
    
    13
    +  axisPen.setColor(Qt::black);
    
    14
    +  axisPen.setWidth(0);
    
    15
    +  blueZonePen.setColor(QColor(64, 64, 255, 64)); // light blue
    
    16
    +  blueZonePen.setWidth(0);
    
    17
    +  // Don't make this solid
    
    18
    +  gridPen.setColor(QColor(0, 0, 0, 255 - QColor(Qt::lightGray).red()));
    
    19
    +  gridPen.setWidth(0);
    
    20
    +  offPen.setColor(Qt::darkGreen);
    
    21
    +  offPen.setWidth(3);
    
    22
    +  onPen.setColor(Qt::red);
    
    23
    +  onPen.setWidth(3);
    
    24
    +  outlinePen.setColor(Qt::red);
    
    25
    +  outlinePen.setWidth(0);
    
    26
    +  segmentPen.setColor(QColor(64, 255, 128, 64)); // light green
    
    27
    +  segmentPen.setWidth(0);
    
    28
    +
    
    29
    +  advanceAuxPen.setColor(QColor(110, 52, 235)); // kind of blue
    
    30
    +  advanceAuxPen.setWidth(0);
    
    31
    +  ascDescAuxPen.setColor(QColor(255, 0, 0)); // red
    
    32
    +  ascDescAuxPen.setWidth(0);
    
    33
    +}
    
    34
    +
    
    35
    +
    
    36
    +GraphicsDefault*
    
    37
    +GraphicsDefault::deafultInstance()
    
    38
    +{
    
    39
    +  if (!instance_)
    
    40
    +    instance_ = new GraphicsDefault;
    
    41
    +
    
    42
    +  return instance_;
    
    43
    +}
    
    44
    +
    
    45
    +
    
    46
    +// end of graphicsdefault.cpp

  • src/ftinspect/glyphcomponents/graphicsdefault.hpp
    1
    +// graphicsdefault.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +#include <QVector>
    
    8
    +#include <QRgb>
    
    9
    +#include <QPen>
    
    10
    +
    
    11
    +// This is default graphics objects fed into render functions.
    
    12
    +struct GraphicsDefault
    
    13
    +{
    
    14
    +  QPen axisPen;
    
    15
    +  QPen blueZonePen;
    
    16
    +  QPen gridPen;
    
    17
    +  QPen offPen;
    
    18
    +  QPen onPen;
    
    19
    +  QPen outlinePen;
    
    20
    +  QPen segmentPen;
    
    21
    +
    
    22
    +  QPen advanceAuxPen;
    
    23
    +  QPen ascDescAuxPen;
    
    24
    +
    
    25
    +  GraphicsDefault();
    
    26
    +
    
    27
    +  static GraphicsDefault* deafultInstance();
    
    28
    +
    
    29
    +private:
    
    30
    +  static GraphicsDefault* instance_;
    
    31
    +};
    
    32
    +
    
    33
    +
    
    34
    +// end of graphicsdefault.hpp

  • src/ftinspect/glyphcomponents/grid.cpp
    ... ... @@ -5,88 +5,131 @@
    5 5
     
    
    6 6
     #include "grid.hpp"
    
    7 7
     
    
    8
    +#include "graphicsdefault.hpp"
    
    9
    +
    
    8 10
     #include <QPainter>
    
    9 11
     #include <QStyleOptionGraphicsItem>
    
    12
    +#include <QGraphicsWidget>
    
    13
    +#include <QGraphicsView>
    
    10 14
     
    
    11 15
     
    
    12
    -Grid::Grid(const QPen& gridP,
    
    13
    -           const QPen& axisP)
    
    14
    -: gridPen_(gridP),
    
    15
    -  axisPen_(axisP)
    
    16
    +Grid::Grid(QGraphicsView* parentView)
    
    17
    +:  parentView_(parentView)
    
    16 18
     {
    
    17 19
      // empty
    
    20
    +  updateRect();
    
    18 21
     }
    
    19 22
     
    
    20 23
     
    
    21 24
     QRectF
    
    22 25
     Grid::boundingRect() const
    
    23 26
     {
    
    24
    -  // XXX fix size
    
    27
    +  return rect_;
    
    28
    +}
    
    29
    +
    
    30
    +
    
    31
    +void
    
    32
    +Grid::updateRect()
    
    33
    +{
    
    34
    +  auto viewport = parentView_->mapToScene(parentView_->viewport()->geometry())
    
    35
    +                         .boundingRect()
    
    36
    +                         .toRect();
    
    37
    +  int minX = std::min(viewport.left() - 10, -100);
    
    38
    +  int minY = std::min(viewport.top() - 10, -100);
    
    39
    +  int maxX = std::max(viewport.right() + 10, 100);
    
    40
    +  int maxY = std::max(viewport.bottom() + 10, 100);
    
    41
    +
    
    42
    +  auto newSceneRect = QRectF(QPointF(minX - 20, minY - 20), 
    
    43
    +                             QPointF(maxX + 20, maxY + 20));
    
    44
    +  if (sceneRect_ != newSceneRect && scene())
    
    45
    +  {
    
    46
    +    scene()->setSceneRect(newSceneRect);
    
    47
    +    sceneRect_ = newSceneRect;
    
    48
    +  }
    
    25 49
     
    
    26 50
       // no need to take care of pen width
    
    27
    -  return QRectF(-100, -100,
    
    28
    -                200, 200);
    
    51
    +  rect_ = QRectF(QPointF(minX, minY), 
    
    52
    +                QPointF(maxX, maxY));
    
    29 53
     }
    
    30 54
     
    
    31 55
     
    
    32
    -// XXX call this in a `myQDraphicsView::drawBackground' derived method
    
    33
    -//     to always fill the complete viewport
    
    34
    -
    
    35 56
     void
    
    36 57
     Grid::paint(QPainter* painter,
    
    37 58
                 const QStyleOptionGraphicsItem* option,
    
    38
    -            QWidget*)
    
    59
    +            QWidget* widget)
    
    39 60
     {
    
    61
    +  auto gb = GraphicsDefault::deafultInstance();
    
    62
    +  auto br = boundingRect().toRect();
    
    63
    +  int minX = br.left();
    
    64
    +  int minY = br.top();
    
    65
    +  int maxX = br.right();
    
    66
    +  int maxY = br.bottom();
    
    67
    +
    
    40 68
       const qreal lod = option->levelOfDetailFromTransform(
    
    41 69
                                   painter->worldTransform());
    
    42
    -
    
    43
    -  painter->setPen(gridPen_);
    
    44
    -
    
    45
    -  // don't mark pixel center with a cross if magnification is too small
    
    46
    -  if (lod > 20)
    
    70
    +  if (showGrid_)
    
    47 71
       {
    
    48
    -    int halfLength = 1;
    
    49
    -
    
    50
    -    // cf. QSpinBoxx
    
    51
    -    if (lod > 640)
    
    52
    -      halfLength = 6;
    
    53
    -    else if (lod > 320)
    
    54
    -      halfLength = 5;
    
    55
    -    else if (lod > 160)
    
    56
    -      halfLength = 4;
    
    57
    -    else if (lod > 80)
    
    58
    -      halfLength = 3;
    
    59
    -    else if (lod > 40)
    
    60
    -      halfLength = 2;
    
    61
    -
    
    62
    -    for (qreal x = -100; x < 100; x++)
    
    63
    -      for (qreal y = -100; y < 100; y++)
    
    64
    -      {
    
    65
    -        painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
    
    66
    -                                 x + 0.5, y + 0.5 + halfLength / lod));
    
    67
    -        painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
    
    68
    -                                 x + 0.5 + halfLength / lod, y + 0.5));
    
    69
    -      }
    
    72
    +    painter->setPen(gb->gridPen);
    
    73
    +    
    
    74
    +    // don't mark pixel center with a cross if magnification is too small
    
    75
    +    if (lod > 20)
    
    76
    +    {
    
    77
    +      int halfLength = 1;
    
    78
    +    
    
    79
    +      // cf. QSpinBoxx
    
    80
    +      if (lod > 640)
    
    81
    +        halfLength = 6;
    
    82
    +      else if (lod > 320)
    
    83
    +        halfLength = 5;
    
    84
    +      else if (lod > 160)
    
    85
    +        halfLength = 4;
    
    86
    +      else if (lod > 80)
    
    87
    +        halfLength = 3;
    
    88
    +      else if (lod > 40)
    
    89
    +        halfLength = 2;
    
    90
    +    
    
    91
    +      for (qreal x = minX; x < maxX; x++)
    
    92
    +        for (qreal y = minY; y < maxY; y++)
    
    93
    +        {
    
    94
    +          painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
    
    95
    +                                   x + 0.5, y + 0.5 + halfLength / lod));
    
    96
    +          painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
    
    97
    +                                   x + 0.5 + halfLength / lod, y + 0.5));
    
    98
    +        }
    
    99
    +    }
    
    100
    +    
    
    101
    +    // don't draw grid if magnification is too small
    
    102
    +    if (lod >= 5)
    
    103
    +    {
    
    104
    +      for (int x = minX; x <= maxX; x++)
    
    105
    +        painter->drawLine(x, minY,
    
    106
    +                          x, maxY);
    
    107
    +      for (int y = minY; y <= maxY; y++)
    
    108
    +        painter->drawLine(minX, y,
    
    109
    +                          maxX, y);
    
    110
    +    }
    
    111
    +    
    
    112
    +    painter->setPen(gb->axisPen);
    
    113
    +    
    
    114
    +    painter->drawLine(0, minY,
    
    115
    +                      0, maxY);
    
    116
    +    painter->drawLine(minX, 0,
    
    117
    +                      maxX, 0);
    
    70 118
       }
    
    71 119
     
    
    72
    -  // don't draw grid if magnification is too small
    
    73
    -  if (lod >= 5)
    
    120
    +  if (showAuxLines_)
    
    74 121
       {
    
    75
    -    // XXX fix size
    
    76
    -    for (int x = -100; x <= 100; x++)
    
    77
    -      painter->drawLine(x, -100,
    
    78
    -                        x, 100);
    
    79
    -    for (int y = -100; y <= 100; y++)
    
    80
    -      painter->drawLine(-100, y,
    
    81
    -                        100, y);
    
    122
    +    // TODO: impl
    
    82 123
       }
    
    124
    +}
    
    83 125
     
    
    84
    -  painter->setPen(axisPen_);
    
    85 126
     
    
    86
    -  painter->drawLine(0, -100,
    
    87
    -                    0, 100);
    
    88
    -  painter->drawLine(-100, 0,
    
    89
    -                    100, 0);
    
    127
    +void
    
    128
    +Grid::setShowGrid(bool showGrid, bool showAuxLines)
    
    129
    +{
    
    130
    +  showGrid_ = showGrid;
    
    131
    +  showAuxLines_ = showAuxLines;
    
    132
    +  update();
    
    90 133
     }
    
    91 134
     
    
    92 135
     
    

  • src/ftinspect/glyphcomponents/grid.hpp
    ... ... @@ -6,23 +6,30 @@
    6 6
     #pragma once
    
    7 7
     
    
    8 8
     #include <QGraphicsItem>
    
    9
    +#include <QGraphicsView>
    
    9 10
     #include <QPen>
    
    10 11
     
    
    11
    -
    
    12 12
     class Grid
    
    13 13
     : public QGraphicsItem
    
    14 14
     {
    
    15 15
     public:
    
    16
    -  Grid(const QPen& gridPen,
    
    17
    -       const QPen& axisPen);
    
    18
    -  QRectF boundingRect() const;
    
    16
    +  Grid(QGraphicsView* parentView);
    
    17
    +  QRectF boundingRect() const override;
    
    19 18
       void paint(QPainter* painter,
    
    20 19
                  const QStyleOptionGraphicsItem* option,
    
    21
    -             QWidget* widget);
    
    20
    +             QWidget* widget) override;
    
    21
    +
    
    22
    +  void setShowGrid(bool showGrid, bool showAuxLines);
    
    23
    +
    
    24
    +  void updateRect(); // there's no signal/slots for QGraphicsItem.
    
    22 25
     
    
    23 26
     private:
    
    24
    -  QPen gridPen_;
    
    25
    -  QPen axisPen_;
    
    27
    +  QGraphicsView* parentView_;
    
    28
    +  QRectF rect_;
    
    29
    +  QRectF sceneRect_;
    
    30
    +
    
    31
    +  bool showGrid_ = true;
    
    32
    +  bool showAuxLines_ = false;
    
    26 33
     };
    
    27 34
     
    
    28 35
     
    

  • src/ftinspect/maingui.cpp
    1
    +// maingui.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2016-2022 by Werner Lemberg.
    
    4
    +
    
    5
    +
    
    6
    +#include "maingui.hpp"
    
    7
    +
    
    8
    +#include <QApplication>
    
    9
    +#include <QFileDialog>
    
    10
    +#include <QMessageBox>
    
    11
    +#include <QSettings>
    
    12
    +#include <QScrollBar>
    
    13
    +#include <QStatusBar>
    
    14
    +
    
    15
    +
    
    16
    +MainGUI::MainGUI(Engine* engine)
    
    17
    +: engine_(engine)
    
    18
    +{
    
    19
    +  createLayout();
    
    20
    +  createConnections();
    
    21
    +  createActions();
    
    22
    +  createMenus();
    
    23
    +
    
    24
    +  readSettings();
    
    25
    +  setUnifiedTitleAndToolBarOnMac(true);
    
    26
    +
    
    27
    +  show();
    
    28
    +}
    
    29
    +
    
    30
    +
    
    31
    +MainGUI::~MainGUI()
    
    32
    +{
    
    33
    +  // empty
    
    34
    +}
    
    35
    +
    
    36
    +
    
    37
    +// overloading
    
    38
    +
    
    39
    +void
    
    40
    +MainGUI::closeEvent(QCloseEvent* event)
    
    41
    +{
    
    42
    +  writeSettings();
    
    43
    +  event->accept();
    
    44
    +}
    
    45
    +
    
    46
    +
    
    47
    +void
    
    48
    +MainGUI::keyPressEvent(QKeyEvent* event)
    
    49
    +{
    
    50
    +  // Delegate key events to tabs
    
    51
    +  if (!tabWidget_->currentWidget()->eventFilter(this, event))
    
    52
    +    QMainWindow::keyPressEvent(event);
    
    53
    +}
    
    54
    +
    
    55
    +