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] 2 commits: [ftinspect]


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri] 2 commits: [ftinspect] Add Fancy submode to "Continuous View"
Date: Mon, 11 Jul 2022 09:11:47 +0000

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

Commits:

  • f2d927ec
    by Charlie Jiang at 2022-07-11T16:35:29+08:00
    [ftinspect] Add Fancy submode to "Continuous View"
    
    Fancy mode adds slanting and hori./vert. emboldening to the glyph.
    
    `GlyphContinuous::paintChar` is broken down to better support additional
    operations during rendering. Add proper cloning so the glyph and the
    outline which are stored in the `GlyphContinuous` class can be safely
    modified.
    
    * src/ftinspect/rendering/glyphcontinuous.cpp,
      src/ftinspect/rendering/glyphcontinuous.hpp: As described, refactored and
      supported Fancy mode.
    
    * src/ftinspect/rendering/glyphbitmap.cpp: Edited to match the new
      `renderutils.cpp`.
    
    * src/ftinspect/rendering/renderutils.cpp,
      src/ftinspect/rendering/renderutils.hpp: Broken down
      `transformOutlineToOrigin`, add `cloneOutline` and `cloneGlyph`.
    
    * src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      Add necessary GUI components and data passing to support fancy mode.
    
  • 274212df
    by Charlie Jiang at 2022-07-11T17:10:31+08:00
    [ftinspect] Support Stroked SubMode in "Continuous Mode"
    
    * src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      GUI update.
    
    * src/ftinspect/rendering/glyphcontinuous.cpp,
      src/ftinspect/rendering/glyphcontinuous.hpp: Add support.
    

7 changed files:

Changes:

  • src/ftinspect/panels/continuous.cpp
    ... ... @@ -130,6 +130,11 @@ ContinuousTab::updateFromCurrentSubTab()
    130 130
         canvas_->setBeginIndex(allGlyphsTab_->glyphBeginindex());
    
    131 131
         canvas_->setLimitIndex(allGlyphsTab_->glyphLimitIndex());
    
    132 132
         canvas_->setCharMapIndex(allGlyphsTab_->charMapIndex());
    
    133
    +
    
    134
    +    canvas_->setFancyParams(allGlyphsTab_->xEmboldening(),
    
    135
    +                            allGlyphsTab_->yEmboldening(),
    
    136
    +                            allGlyphsTab_->slanting());
    
    137
    +    canvas_->setStrokeRadius(allGlyphsTab_->strokeRadius());
    
    133 138
         break;
    
    134 139
       }
    
    135 140
     }
    
    ... ... @@ -143,6 +148,8 @@ ContinousAllGlyphsTab::ContinousAllGlyphsTab(QWidget* parent)
    143 148
       QVector<CharMapInfo> tempCharMaps;
    
    144 149
       setCharMaps(tempCharMaps); // pass in an empty one
    
    145 150
     
    
    151
    +  checkSubMode();
    
    152
    +  setDefaults();
    
    146 153
       createConnections();
    
    147 154
     }
    
    148 155
     
    
    ... ... @@ -169,6 +176,34 @@ ContinousAllGlyphsTab::subMode()
    169 176
     }
    
    170 177
     
    
    171 178
     
    
    179
    +double
    
    180
    +ContinousAllGlyphsTab::xEmboldening()
    
    181
    +{
    
    182
    +  return xEmboldeningSpinBox_->value();
    
    183
    +}
    
    184
    +
    
    185
    +
    
    186
    +double
    
    187
    +ContinousAllGlyphsTab::yEmboldening()
    
    188
    +{
    
    189
    +  return yEmboldeningSpinBox_->value();
    
    190
    +}
    
    191
    +
    
    192
    +
    
    193
    +double
    
    194
    +ContinousAllGlyphsTab::slanting()
    
    195
    +{
    
    196
    +  return slantSpinBox_->value();
    
    197
    +}
    
    198
    +
    
    199
    +
    
    200
    +double
    
    201
    +ContinousAllGlyphsTab::strokeRadius()
    
    202
    +{
    
    203
    +  return strokeRadiusSpinBox_->value();
    
    204
    +}
    
    205
    +
    
    206
    +
    
    172 207
     int
    
    173 208
     ContinousAllGlyphsTab::charMapIndex()
    
    174 209
     {
    
    ... ... @@ -263,6 +298,20 @@ ContinousAllGlyphsTab::updateLimitIndex()
    263 298
     }
    
    264 299
     
    
    265 300
     
    
    301
    +void
    
    302
    +ContinousAllGlyphsTab::checkSubMode()
    
    303
    +{
    
    304
    +  auto isFancy = subMode() == GlyphContinuous::AG_Fancy;
    
    305
    +  auto isStroked = subMode() == GlyphContinuous::AG_Stroked;
    
    306
    +  xEmboldeningSpinBox_->setEnabled(isFancy);
    
    307
    +  yEmboldeningSpinBox_->setEnabled(isFancy);
    
    308
    +  slantSpinBox_->setEnabled(isFancy);
    
    309
    +  strokeRadiusSpinBox_->setEnabled(isStroked);
    
    310
    +
    
    311
    +  emit changed();
    
    312
    +}
    
    313
    +
    
    314
    +
    
    266 315
     void
    
    267 316
     ContinousAllGlyphsTab::createLayout()
    
    268 317
     {
    
    ... ... @@ -276,13 +325,36 @@ ContinousAllGlyphsTab::createLayout()
    276 325
     
    
    277 326
       // Note: in sync with the enum!!
    
    278 327
       modeSelector_->insertItem(GlyphContinuous::AG_AllGlyphs, tr("All Glyphs"));
    
    279
    -  modeSelector_->insertItem(GlyphContinuous::AG_Fancy, tr("Fancy"));
    
    328
    +  modeSelector_->insertItem(GlyphContinuous::AG_Fancy, 
    
    329
    +                            tr("Fancy (Embolding & Slanting)"));
    
    280 330
       modeSelector_->insertItem(GlyphContinuous::AG_Stroked, tr("Stroked"));
    
    281 331
       modeSelector_->insertItem(GlyphContinuous::AG_Waterfall, tr("Waterfall"));
    
    282 332
       modeSelector_->setCurrentIndex(GlyphContinuous::AG_AllGlyphs);
    
    283 333
     
    
    284 334
       modeLabel_ = new QLabel(tr("Mode:"), this);
    
    285 335
       charMapLabel_ = new QLabel(tr("Char Map:"), this);
    
    336
    +  xEmboldeningLabel_ = new QLabel(tr("Hori. Embolding (for Fancy):"), this);
    
    337
    +  yEmboldeningLabel_ = new QLabel(tr("Vert. Embolding (for Fancy):"), this);
    
    338
    +  slantLabel_ = new QLabel(tr("Slanting (for Fancy):"), this);
    
    339
    +  strokeRadiusLabel_ = new QLabel(tr("Stroke Radius (for Stroked):"), this);
    
    340
    +
    
    341
    +  xEmboldeningSpinBox_ = new QDoubleSpinBox(this);
    
    342
    +  yEmboldeningSpinBox_ = new QDoubleSpinBox(this);
    
    343
    +  slantSpinBox_ = new QDoubleSpinBox(this);
    
    344
    +  strokeRadiusSpinBox_ = new QDoubleSpinBox(this);
    
    345
    +
    
    346
    +  xEmboldeningSpinBox_->setSingleStep(0.005);
    
    347
    +  xEmboldeningSpinBox_->setMinimum(-0.1);
    
    348
    +  xEmboldeningSpinBox_->setMaximum(0.1);
    
    349
    +  yEmboldeningSpinBox_->setSingleStep(0.005);
    
    350
    +  yEmboldeningSpinBox_->setMinimum(-0.1);
    
    351
    +  yEmboldeningSpinBox_->setMaximum(0.1);
    
    352
    +  slantSpinBox_->setSingleStep(0.02);
    
    353
    +  slantSpinBox_->setMinimum(-1);
    
    354
    +  slantSpinBox_->setMaximum(1);
    
    355
    +  strokeRadiusSpinBox_->setSingleStep(0.005);
    
    356
    +  strokeRadiusSpinBox_->setMinimum(0);
    
    357
    +  strokeRadiusSpinBox_->setMaximum(0.05);
    
    286 358
     
    
    287 359
       layout_ = new QGridLayout;
    
    288 360
       layout_->addWidget(indexSelector_, 0, 0, 1, 2);
    
    ... ... @@ -291,7 +363,17 @@ ContinousAllGlyphsTab::createLayout()
    291 363
       layout_->addWidget(modeSelector_, 1, 1);
    
    292 364
       layout_->addWidget(charMapSelector_, 2, 1);
    
    293 365
     
    
    366
    +  layout_->addWidget(xEmboldeningLabel_, 1, 2);
    
    367
    +  layout_->addWidget(yEmboldeningLabel_, 2, 2);
    
    368
    +  layout_->addWidget(slantLabel_, 3, 2);
    
    369
    +  layout_->addWidget(strokeRadiusLabel_, 3, 0);
    
    370
    +  layout_->addWidget(xEmboldeningSpinBox_, 1, 3);
    
    371
    +  layout_->addWidget(yEmboldeningSpinBox_, 2, 3);
    
    372
    +  layout_->addWidget(slantSpinBox_, 3, 3);
    
    373
    +  layout_->addWidget(strokeRadiusSpinBox_, 3, 1);
    
    374
    +
    
    294 375
       layout_->setColumnStretch(1, 1);
    
    376
    +  layout_->setColumnStretch(3, 1);
    
    295 377
     
    
    296 378
       setLayout(layout_);
    
    297 379
     }
    
    ... ... @@ -302,9 +384,22 @@ ContinousAllGlyphsTab::createConnections()
    302 384
       connect(indexSelector_, &GlyphIndexSelector::currentIndexChanged,
    
    303 385
               this, &ContinousAllGlyphsTab::changed);
    
    304 386
       connect(modeSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    305
    -          this, &ContinousAllGlyphsTab::changed);
    
    387
    +          this, &ContinousAllGlyphsTab::checkSubMode);
    
    306 388
       connect(charMapSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    307 389
               this, &ContinousAllGlyphsTab::charMapChanged);
    
    390
    +
    
    391
    +  connect(xEmboldeningSpinBox_, 
    
    392
    +          QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    393
    +          this, &ContinousAllGlyphsTab::changed);
    
    394
    +  connect(yEmboldeningSpinBox_, 
    
    395
    +          QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    396
    +          this, &ContinousAllGlyphsTab::changed);
    
    397
    +  connect(slantSpinBox_, 
    
    398
    +          QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    399
    +          this, &ContinousAllGlyphsTab::changed);
    
    400
    +  connect(strokeRadiusSpinBox_, 
    
    401
    +          QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    402
    +          this, &ContinousAllGlyphsTab::changed);
    
    308 403
     }
    
    309 404
     
    
    310 405
     
    
    ... ... @@ -339,4 +434,14 @@ ContinousAllGlyphsTab::charMapChanged()
    339 434
     }
    
    340 435
     
    
    341 436
     
    
    437
    +void
    
    438
    +ContinousAllGlyphsTab::setDefaults()
    
    439
    +{
    
    440
    +  xEmboldeningSpinBox_->setValue(0.04);
    
    441
    +  yEmboldeningSpinBox_->setValue(0.04);
    
    442
    +  slantSpinBox_->setValue(0.22);
    
    443
    +  strokeRadiusSpinBox_->setValue(0.02);
    
    444
    +}
    
    445
    +
    
    446
    +
    
    342 447
     // end of continuous.cpp

  • src/ftinspect/panels/continuous.hpp
    ... ... @@ -79,6 +79,10 @@ public:
    79 79
       int glyphBeginindex();
    
    80 80
       int glyphLimitIndex();
    
    81 81
       GlyphContinuous::SubModeAllGlyphs subMode();
    
    82
    +  double xEmboldening();
    
    83
    +  double yEmboldening();
    
    84
    +  double slanting();
    
    85
    +  double strokeRadius();
    
    82 86
     
    
    83 87
       // -1: Glyph order, otherwise the char map index in the original list
    
    84 88
       int charMapIndex();
    
    ... ... @@ -92,6 +96,8 @@ public:
    92 96
       // This doesn't trigger either.
    
    93 97
       void updateLimitIndex();
    
    94 98
     
    
    99
    +  void checkSubMode();
    
    100
    +
    
    95 101
     signals:
    
    96 102
       void changed();
    
    97 103
     
    
    ... ... @@ -106,6 +112,15 @@ private:
    106 112
     
    
    107 113
       QLabel* modeLabel_;
    
    108 114
       QLabel* charMapLabel_;
    
    115
    +  QLabel* xEmboldeningLabel_;
    
    116
    +  QLabel* yEmboldeningLabel_;
    
    117
    +  QLabel* slantLabel_;
    
    118
    +  QLabel* strokeRadiusLabel_;
    
    119
    +
    
    120
    +  QDoubleSpinBox* xEmboldeningSpinBox_;
    
    121
    +  QDoubleSpinBox* yEmboldeningSpinBox_;
    
    122
    +  QDoubleSpinBox* slantSpinBox_;
    
    123
    +  QDoubleSpinBox* strokeRadiusSpinBox_;
    
    109 124
     
    
    110 125
       QGridLayout* layout_;
    
    111 126
     
    
    ... ... @@ -116,6 +131,8 @@ private:
    116 131
     
    
    117 132
       QString formatIndex(int index);
    
    118 133
       void charMapChanged();
    
    134
    +
    
    135
    +  void setDefaults();
    
    119 136
     };
    
    120 137
     
    
    121 138
     
    

  • src/ftinspect/rendering/glyphbitmap.cpp
    ... ... @@ -24,7 +24,8 @@ GlyphBitmap::GlyphBitmap(FT_Outline* outline,
    24 24
     {
    
    25 25
       // make a copy of the outline since we are going to manipulate it
    
    26 26
       FT_BBox cbox;
    
    27
    -  transformed_ = transformOutlineToOrigin(lib, outline, &cbox);
    
    27
    +  transformed_ = cloneOutline(lib, outline);
    
    28
    +  transformOutlineToOrigin(&transformed_, &cbox);
    
    28 29
       boundingRect_.setCoords(cbox.xMin / 64, -cbox.yMax / 64,
    
    29 30
                       cbox.xMax / 64, -cbox.yMin / 64);
    
    30 31
     }
    

  • src/ftinspect/rendering/glyphcontinuous.cpp
    ... ... @@ -4,13 +4,13 @@
    4 4
     
    
    5 5
     #include "glyphcontinuous.hpp"
    
    6 6
     
    
    7
    +#include "../engine/engine.hpp"
    
    8
    +#include "../rendering/renderutils.hpp"
    
    9
    +
    
    7 10
     #include <cmath>
    
    8 11
     #include <QPainter>
    
    9 12
     #include <QWheelEvent>
    
    10 13
     
    
    11
    -#include "../engine/engine.hpp"
    
    12
    -#include "../rendering/renderutils.hpp"
    
    13
    -
    
    14 14
     
    
    15 15
     GlyphContinuous::GlyphContinuous(QWidget* parent, Engine* engine)
    
    16 16
     : QWidget(parent), engine_(engine)
    
    ... ... @@ -18,6 +18,15 @@ GlyphContinuous::GlyphContinuous(QWidget* parent, Engine* engine)
    18 18
       setAcceptDrops(false);
    
    19 19
       setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    20 20
       graphicsDefault_ = GraphicsDefault::deafultInstance();
    
    21
    +
    
    22
    +  FT_Stroker_New(engine_->ftLibrary(), &stroker_);
    
    23
    +}
    
    24
    +
    
    25
    +
    
    26
    +GlyphContinuous::~GlyphContinuous()
    
    27
    +{
    
    28
    +  cleanCloned();
    
    29
    +  FT_Stroker_Done(stroker_);
    
    21 30
     }
    
    22 31
     
    
    23 32
     
    
    ... ... @@ -38,12 +47,9 @@ GlyphContinuous::paintEvent(QPaintEvent* event)
    38 47
           switch (modeAG_)
    
    39 48
           {
    
    40 49
           case AG_AllGlyphs:
    
    41
    -        paintAGAllGlyphs(&painter);
    
    42
    -        break;
    
    43
    -        // TODO more modes
    
    44 50
           case AG_Fancy:
    
    45
    -        break;
    
    46 51
           case AG_Stroked:
    
    52
    +        paintAG(&painter);
    
    47 53
             break;
    
    48 54
           case AG_Waterfall:
    
    49 55
             break;
    
    ... ... @@ -71,19 +77,114 @@ GlyphContinuous::wheelEvent(QWheelEvent* event)
    71 77
     
    
    72 78
     
    
    73 79
     void
    
    74
    -GlyphContinuous::paintAGAllGlyphs(QPainter* painter)
    
    80
    +GlyphContinuous::paintAG(QPainter* painter)
    
    75 81
     {
    
    82
    +  if (modeAG_ == AG_Stroked)
    
    83
    +  {
    
    84
    +    auto radius = static_cast<FT_Fixed>(metrics_.y_ppem * 64 * strokeRadius_);
    
    85
    +    FT_Stroker_Set(stroker_, radius,
    
    86
    +                   FT_STROKER_LINECAP_ROUND,
    
    87
    +                   FT_STROKER_LINEJOIN_ROUND,
    
    88
    +                   0);
    
    89
    +  }
    
    90
    +
    
    76 91
       for (int i = beginIndex_; i < limitIndex_; i++)
    
    77 92
       {
    
    78 93
         unsigned index = i;
    
    79 94
         if (charMapIndex_ >= 0)
    
    80 95
           index = engine_->glyphIndexFromCharCode(i, charMapIndex_);
    
    81 96
     
    
    82
    -    if (!paintChar(painter, index))
    
    97
    +    if (!loadGlyph(index))
    
    98
    +      break;
    
    99
    +
    
    100
    +    // All Glyphs need no tranformation, and Waterfall isn't handled here.
    
    101
    +    switch (modeAG_)
    
    102
    +    {
    
    103
    +    case AG_Fancy:
    
    104
    +      transformGlyphAGFancy();
    
    105
    +      break;
    
    106
    +    case AG_Stroked:
    
    107
    +      transformGlyphAGStroked();
    
    83 108
           break;
    
    109
    +    default:;
    
    110
    +    }
    
    111
    +
    
    112
    +    if (!paintChar(painter))
    
    113
    +      break;
    
    114
    +    cleanCloned();
    
    84 115
     
    
    85 116
         displayingCount_++;
    
    86 117
       }
    
    118
    +  cleanCloned();
    
    119
    +}
    
    120
    +
    
    121
    +
    
    122
    +void
    
    123
    +GlyphContinuous::transformGlyphAGFancy()
    
    124
    +{
    
    125
    +  // adopted from ftview.c:289
    
    126
    +  /***************************************************************/
    
    127
    +  /*                                                             */
    
    128
    +  /*  2*2 affine transformation matrix, 16.16 fixed float format */
    
    129
    +  /*                                                             */
    
    130
    +  /*  Shear matrix:                                              */
    
    131
    +  /*                                                             */
    
    132
    +  /*         | x' |     | 1  k |   | x |          x' = x + ky    */
    
    133
    +  /*         |    |  =  |      | * |   |   <==>                  */
    
    134
    +  /*         | y' |     | 0  1 |   | y |          y' = y         */
    
    135
    +  /*                                                             */
    
    136
    +  /*        outline'     shear    outline                        */
    
    137
    +  /*                                                             */
    
    138
    +  /***************************************************************/
    
    139
    +
    
    140
    +  FT_Matrix shear;
    
    141
    +  FT_Pos xstr, ystr;
    
    142
    +
    
    143
    +  shear.xx = 1 << 16;
    
    144
    +  shear.xy = static_cast<FT_Fixed>(slant_ * (1 << 16));
    
    145
    +  shear.yx = 0;
    
    146
    +  shear.yy = 1 << 16;
    
    147
    +
    
    148
    +  xstr = (FT_Pos)(metrics_.y_ppem * 64 * boldX_);
    
    149
    +  ystr = (FT_Pos)(metrics_.y_ppem * 64 * boldY_);
    
    150
    +
    
    151
    +  if (!isGlyphCloned_)
    
    152
    +    cloneGlyph();
    
    153
    +
    
    154
    +  if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    155
    +    return; // TODO suuport non-outline: code below all depend on `outline_`!
    
    156
    +
    
    157
    +  FT_Outline_Transform(&outline_, &shear);
    
    158
    +  FT_Outline_EmboldenXY(&outline_, xstr, ystr);
    
    159
    +
    
    160
    +  if (glyph_->advance.x)
    
    161
    +    glyph_->advance.x += xstr;
    
    162
    +
    
    163
    +  if (glyph_->advance.y)
    
    164
    +    glyph_->advance.y += ystr;
    
    165
    +  
    
    166
    +  //glyph_->metrics.width += xstr;
    
    167
    +  //glyph_->metrics.height += ystr;
    
    168
    +  //glyph_->metrics.horiAdvance += xstr;
    
    169
    +  //glyph_->metrics.vertAdvance += ystr;
    
    170
    +}
    
    171
    +
    
    172
    +
    
    173
    +void
    
    174
    +GlyphContinuous::transformGlyphAGStroked()
    
    175
    +{
    
    176
    +  //if (!isGlyphCloned_)
    
    177
    +    //cloneGlyph();
    
    178
    +  // Well, now here only outline glyph is supported.
    
    179
    +  if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    180
    +    return;
    
    181
    +  auto error = FT_Glyph_Stroke(&glyph_, stroker_, 0);
    
    182
    +  if (!error)
    
    183
    +  {
    
    184
    +    isGlyphCloned_ = true;
    
    185
    +    isOutlineCloned_ = false;
    
    186
    +    outline_ = reinterpret_cast<FT_OutlineGlyph>(glyph_)->outline;
    
    187
    +  }
    
    87 188
     }
    
    88 189
     
    
    89 190
     
    
    ... ... @@ -101,16 +202,11 @@ GlyphContinuous::prePaint()
    101 202
     
    
    102 203
     
    
    103 204
     bool
    
    104
    -GlyphContinuous::paintChar(QPainter* painter,
    
    105
    -                           int index)
    
    205
    +GlyphContinuous::paintChar(QPainter* painter)
    
    106 206
     {
    
    107
    -  auto glyph = engine_->loadGlyphWithoutUpdate(index);
    
    108
    -  if (!glyph)
    
    109
    -    return false;
    
    110
    -
    
    111 207
       // ftview.c:557
    
    112
    -  int width = glyph->advance.x ? glyph->advance.x >> 16
    
    113
    -                               : metrics_.y_ppem / 2;
    
    208
    +  int width = glyph_->advance.x ? glyph_->advance.x >> 16
    
    209
    +                                : metrics_.y_ppem / 2;
    
    114 210
     
    
    115 211
       if (!checkFitX(x_ + width))
    
    116 212
       {
    
    ... ... @@ -122,7 +218,7 @@ GlyphContinuous::paintChar(QPainter* painter,
    122 218
       }
    
    123 219
     
    
    124 220
       x_++; // extra space
    
    125
    -  if (glyph->advance.x == 0)
    
    221
    +  if (glyph_->advance.x == 0)
    
    126 222
       {
    
    127 223
         // Draw a red square to indicate
    
    128 224
           painter->fillRect(x_, y_ - width, width, width,
    
    ... ... @@ -136,15 +232,15 @@ GlyphContinuous::paintChar(QPainter* painter,
    136 232
     
    
    137 233
       // First translate the outline
    
    138 234
     
    
    139
    -  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    
    235
    +  if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    140 236
         return true; // XXX only outline is supported - need to impl others later
    
    141 237
     
    
    142 238
       FT_BBox cbox;
    
    143 239
       // Don't forget to free this when returning
    
    144
    -  auto outline = transformOutlineToOrigin(
    
    145
    -                   engine_->ftLibrary(),
    
    146
    -                   &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline,
    
    147
    -                   &cbox);
    
    240
    +  if (!isOutlineCloned_ && !isGlyphCloned_)
    
    241
    +    cloneOutline();
    
    242
    +  
    
    243
    +  transformOutlineToOrigin(&outline_, &cbox);
    
    148 244
       
    
    149 245
       auto outlineWidth = (cbox.xMax - cbox.xMin) / 64;
    
    150 246
       auto outlineHeight = (cbox.yMax - cbox.yMin) / 64;
    
    ... ... @@ -175,12 +271,11 @@ GlyphContinuous::paintChar(QPainter* painter,
    175 271
       bitmap.pixel_mode = aaEnabled ? FT_PIXEL_MODE_GRAY : FT_PIXEL_MODE_MONO;
    
    176 272
     
    
    177 273
       FT_Error error = FT_Outline_Get_Bitmap(engine_->ftLibrary(),
    
    178
    -                                         &outline,
    
    274
    +                                         &outline_,
    
    179 275
                                              &bitmap);
    
    180 276
       if (error)
    
    181 277
       {
    
    182 278
         // XXX error handling
    
    183
    -    FT_Outline_Done(engine_->ftLibrary(), &outline);
    
    184 279
         return true;
    
    185 280
       }
    
    186 281
     
    
    ... ... @@ -189,12 +284,59 @@ GlyphContinuous::paintChar(QPainter* painter,
    189 284
           image.convertToFormat(QImage::Format_ARGB32_Premultiplied));
    
    190 285
     
    
    191 286
       x_ += width;
    
    287
    +  
    
    288
    +  return true;
    
    289
    +}
    
    290
    +
    
    192 291
     
    
    193
    -  FT_Outline_Done(engine_->ftLibrary(), &outline);
    
    292
    +bool
    
    293
    +GlyphContinuous::loadGlyph(int index)
    
    294
    +{
    
    295
    +  glyph_ = engine_->loadGlyphWithoutUpdate(index);
    
    296
    +  isGlyphCloned_ = false;
    
    297
    +  if (!glyph_)
    
    298
    +    return false;
    
    299
    +  if (glyph_->format == FT_GLYPH_FORMAT_OUTLINE)
    
    300
    +  {
    
    301
    +    isOutlineCloned_ = false;
    
    302
    +    outline_ = reinterpret_cast<FT_OutlineGlyph>(glyph_)->outline;
    
    303
    +  }
    
    194 304
       return true;
    
    195 305
     }
    
    196 306
     
    
    197 307
     
    
    308
    +void
    
    309
    +GlyphContinuous::cloneGlyph()
    
    310
    +{
    
    311
    +  glyph_ = ::cloneGlyph(glyph_);
    
    312
    +  isGlyphCloned_ = true;
    
    313
    +}
    
    314
    +
    
    315
    +
    
    316
    +void
    
    317
    +GlyphContinuous::cloneOutline()
    
    318
    +{
    
    319
    +  outline_ = ::cloneOutline(engine_->ftLibrary(), &outline_);
    
    320
    +  isOutlineCloned_ = true;
    
    321
    +}
    
    322
    +
    
    323
    +
    
    324
    +void
    
    325
    +GlyphContinuous::cleanCloned()
    
    326
    +{
    
    327
    +  if (isGlyphCloned_)
    
    328
    +  {
    
    329
    +    FT_Done_Glyph(glyph_);
    
    330
    +    isGlyphCloned_ = false;
    
    331
    +  }
    
    332
    +  if (isOutlineCloned_)
    
    333
    +  {
    
    334
    +    FT_Outline_Done(engine_->ftLibrary(), &outline_);
    
    335
    +    isOutlineCloned_ = false;
    
    336
    +  }
    
    337
    +}
    
    338
    +
    
    339
    +
    
    198 340
     bool
    
    199 341
     GlyphContinuous::checkFitX(int x)
    
    200 342
     {
    

  • src/ftinspect/rendering/glyphcontinuous.hpp
    ... ... @@ -7,6 +7,9 @@
    7 7
     #include "graphicsdefault.hpp"
    
    8 8
     #include <QWidget>
    
    9 9
     #include <freetype/freetype.h>
    
    10
    +#include <freetype/ftglyph.h>
    
    11
    +#include <freetype/ftoutln.h>
    
    12
    +#include <freetype/ftstroke.h>
    
    10 13
     
    
    11 14
     class Engine;
    
    12 15
     class GlyphContinuous
    
    ... ... @@ -15,7 +18,7 @@ class GlyphContinuous
    15 18
       Q_OBJECT
    
    16 19
     public:
    
    17 20
       GlyphContinuous(QWidget* parent, Engine* engine);
    
    18
    -  ~GlyphContinuous() override = default;
    
    21
    +  ~GlyphContinuous() override;
    
    19 22
     
    
    20 23
       enum Mode : int
    
    21 24
       {
    
    ... ... @@ -39,6 +42,13 @@ public:
    39 42
       void setCharMapIndex(int index) { charMapIndex_ = index; }
    
    40 43
       void setMode(Mode mode) { mode_ = mode; }
    
    41 44
       void setSubModeAllGlyphs(SubModeAllGlyphs modeAg) { modeAG_ = modeAg; }
    
    45
    +  void setFancyParams(double boldX, double boldY, double slant)
    
    46
    +  {
    
    47
    +    boldX_ = boldX;
    
    48
    +    boldY_ = boldY;
    
    49
    +    slant_ = slant;
    
    50
    +  }
    
    51
    +  void setStrokeRadius(double radius) { strokeRadius_ = radius; }
    
    42 52
     
    
    43 53
     signals:
    
    44 54
       void wheelNavigate(int steps);
    
    ... ... @@ -53,21 +63,36 @@ private:
    53 63
       Engine* engine_;
    
    54 64
       GraphicsDefault* graphicsDefault_;
    
    55 65
     
    
    66
    +  Mode mode_ = AllGlyphs;
    
    67
    +  SubModeAllGlyphs modeAG_ = AG_AllGlyphs;
    
    56 68
       int beginIndex_;
    
    57 69
       int limitIndex_;
    
    58 70
       int charMapIndex_;
    
    59
    -  Mode mode_ = AllGlyphs;
    
    60
    -  SubModeAllGlyphs modeAG_ = AG_AllGlyphs;
    
    71
    +  double boldX_, boldY_, slant_;
    
    72
    +  double strokeRadius_;
    
    61 73
     
    
    62 74
       int displayingCount_ = 0;
    
    63 75
       FT_Size_Metrics metrics_;
    
    64 76
       int x_ = 0, y_ = 0;
    
    65 77
       int stepY_ = 0;
    
    78
    +  FT_Glyph glyph_;
    
    79
    +  FT_Outline outline_;
    
    80
    +  // when glyph is cloned, outline is factually also cloned
    
    81
    +  // but `isOutlineCloned` won't be set!
    
    82
    +  bool isGlyphCloned_ = false, isOutlineCloned_ = false;
    
    83
    +
    
    84
    +  FT_Stroker stroker_;
    
    66 85
     
    
    67
    -  void paintAGAllGlyphs(QPainter* painter);
    
    86
    +  void paintAG(QPainter* painter);
    
    87
    +  void transformGlyphAGFancy();
    
    88
    +  void transformGlyphAGStroked();
    
    68 89
       void prePaint();
    
    69 90
       // return if there's enough space to paint the current char
    
    70
    -  bool paintChar(QPainter* painter, int index);
    
    91
    +  bool paintChar(QPainter* painter);
    
    92
    +  bool loadGlyph(int index);
    
    93
    +  void cloneGlyph();
    
    94
    +  void cloneOutline();
    
    95
    +  void cleanCloned();
    
    71 96
     
    
    72 97
       bool checkFitX(int x);
    
    73 98
       bool checkFitY(int y);
    

  • src/ftinspect/rendering/renderutils.cpp
    ... ... @@ -5,16 +5,30 @@
    5 5
     #include "renderutils.hpp"
    
    6 6
     
    
    7 7
     FT_Outline
    
    8
    -transformOutlineToOrigin(FT_Library library, 
    
    9
    -                         FT_Outline* outline,
    
    10
    -                         FT_BBox* outControlBox)
    
    8
    +cloneOutline(FT_Library library, 
    
    9
    +             FT_Outline* src)
    
    11 10
     {
    
    12 11
       FT_Outline transformed;
    
    13
    -  FT_Outline_New(library,
    
    14
    -                 static_cast<unsigned int>(outline->n_points),
    
    15
    -                 outline->n_contours, &transformed);
    
    16
    -  FT_Outline_Copy(outline, &transformed);
    
    12
    +  FT_Outline_New(library, static_cast<unsigned int>(src->n_points),
    
    13
    +                 src->n_contours, &transformed);
    
    14
    +  FT_Outline_Copy(src, &transformed);
    
    15
    +  return transformed;
    
    16
    +}
    
    17 17
     
    
    18
    +
    
    19
    +FT_Glyph
    
    20
    +cloneGlyph(FT_Glyph src)
    
    21
    +{
    
    22
    +  FT_Glyph target = NULL;
    
    23
    +  FT_Glyph_Copy(src, &target);
    
    24
    +  return target;
    
    25
    +}
    
    26
    +
    
    27
    +
    
    28
    +void
    
    29
    +transformOutlineToOrigin(FT_Outline* outline,
    
    30
    +                         FT_BBox* outControlBox)
    
    31
    +{
    
    18 32
       FT_BBox cbox;
    
    19 33
       FT_Outline_Get_CBox(outline, &cbox);
    
    20 34
     
    
    ... ... @@ -23,11 +37,10 @@ transformOutlineToOrigin(FT_Library library,
    23 37
       cbox.xMax = (cbox.xMax + 63) & ~63;
    
    24 38
       cbox.yMax = (cbox.yMax + 63) & ~63;
    
    25 39
       // we shift the outline to the origin for rendering later on
    
    26
    -  FT_Outline_Translate(&transformed, -cbox.xMin, -cbox.yMin);
    
    40
    +  FT_Outline_Translate(outline, -cbox.xMin, -cbox.yMin);
    
    27 41
     
    
    28 42
       if (outControlBox)
    
    29 43
         *outControlBox = cbox;
    
    30
    -  return transformed;
    
    31 44
     }
    
    32 45
     
    
    33 46
     
    

  • src/ftinspect/rendering/renderutils.hpp
    ... ... @@ -4,12 +4,15 @@
    4 4
     
    
    5 5
     #pragma once
    
    6 6
     
    
    7
    +#include <freetype/ftglyph.h>
    
    7 8
     #include <freetype/ftoutln.h>
    
    8 9
     
    
    9 10
     // The constructed `outline` must be freed by the caller
    
    10
    -FT_Outline transformOutlineToOrigin(FT_Library library, 
    
    11
    -                                    FT_Outline* outline,
    
    12
    -                                    FT_BBox* outControlBox);
    
    11
    +FT_Outline cloneOutline(FT_Library library, FT_Outline* src);
    
    12
    +FT_Glyph cloneGlyph(FT_Glyph src);
    
    13
    +
    
    14
    +void transformOutlineToOrigin(FT_Outline* outline,
    
    15
    +                              FT_BBox* outControlBox);
    
    13 16
     
    
    14 17
     
    
    15 18
     // end of renderutils.hpp


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]