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


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-3] 2 commits: [ftinspect] Properly support bitmap-only fonts.
Date: Mon, 22 Aug 2022 16:02:30 +0000

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

Commits:

  • 2747cd47
    by Charlie Jiang at 2022-08-22T23:44:24+08:00
    [ftinspect] Properly support bitmap-only fonts.
    
    Fixes #16.
    
    Now the size selector will only accept available sizes if the font is
    bitmap-only.
    
    * src/ftinspect/widgets/fontsizeselector.cpp,
      src/ftinspect/widgets/fontsizeselector.hpp:
      Add limits to the font selector so it only accepts sizes provided by the
      font if it's not scalable. Now it will jump to next available size when
      adjusted. But when edit with the keyboard, it functions weird.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Fix minor bugs with `reloadFont` and `glyphName`.
      Add `currentFontBitmapOnly` and `currentFontFixedSizes` functions.
    
    * src/ftinspect/panels/settingpanel.cpp: Force "Enable embedded bitmap" for
      bitmap-only fonts.
    
    * src/ftinspect/panels/comparator.cpp, src/ftinspect/panels/continuous.cpp,
      src/ftinspect/panels/singular.cpp:
      Update the size selector when font changes.
    
  • bd50cb4b
    by Charlie Jiang at 2022-08-23T00:00:11+08:00
    [ftinspect] Properly support waterfall for unscalable fonts.
    
    Now the waterfall will show all available sizes when the font is not
    scalable.
    
    * src/ftinspect/engine/stringrenderer.cpp: Add special handling to
      unscalable fonts.
    
    * src/ftinspect/panels/continuous.cpp:
      Disable "WF Config" button when the font is not scalable.
    
    * src/ftinspect/rendering/glyphcontinuous.cpp:
      Show sizes in pixels when the font is not scalable.
    
    * src/ftinspect/panels/settingpanel.cpp: Fix bug.
    

10 changed files:

Changes:

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -381,8 +381,15 @@ Engine::reloadFont()
    381 381
       if (!scaler_.face_id)
    
    382 382
         return;
    
    383 383
       imageType_.face_id = scaler_.face_id;
    
    384
    -  FTC_Manager_LookupFace(cacheManager_, scaler_.face_id, &ftFallbackFace_);
    
    385
    -  FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_);
    
    384
    +  
    
    385
    +  if (FTC_Manager_LookupFace(cacheManager_, scaler_.face_id, &ftFallbackFace_))
    
    386
    +  {
    
    387
    +    ftFallbackFace_ = NULL;
    
    388
    +    ftSize_ = NULL;
    
    389
    +    return;
    
    390
    +  }
    
    391
    +  if (FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    392
    +    ftSize_ = NULL; // Good font, bad size.
    
    386 393
     }
    
    387 394
     
    
    388 395
     
    
    ... ... @@ -531,6 +538,29 @@ Engine::currentFontSFNTTableInfo()
    531 538
     }
    
    532 539
     
    
    533 540
     
    
    541
    +bool
    
    542
    +Engine::currentFontBitmapOnly()
    
    543
    +{
    
    544
    +  if (!ftFallbackFace_)
    
    545
    +    return false;
    
    546
    +  return !FT_IS_SCALABLE(ftFallbackFace_);
    
    547
    +}
    
    548
    +
    
    549
    +
    
    550
    +std::vector<int>
    
    551
    +Engine::currentFontFixedSizes()
    
    552
    +{
    
    553
    +  if (!ftFallbackFace_ || !FT_HAS_FIXED_SIZES(ftFallbackFace_)
    
    554
    +      || !ftFallbackFace_->available_sizes)
    
    555
    +    return {};
    
    556
    +  std::vector<int> result;
    
    557
    +  result.resize(ftFallbackFace_->num_fixed_sizes);
    
    558
    +  for (int i = 0; i < ftFallbackFace_->num_fixed_sizes; i++)
    
    559
    +    result[i] = ftFallbackFace_->available_sizes[i].size >> 6; // XXX: ????
    
    560
    +  return result;
    
    561
    +}
    
    562
    +
    
    563
    +
    
    534 564
     QString
    
    535 565
     Engine::glyphName(int index)
    
    536 566
     {
    
    ... ... @@ -539,14 +569,11 @@ Engine::glyphName(int index)
    539 569
       if (index < 0)
    
    540 570
         throw std::runtime_error("Invalid glyph index");
    
    541 571
     
    
    542
    -  FT_Face face = NULL;
    
    543
    -  if (FTC_Manager_LookupFace(cacheManager_, scaler_.face_id, &face))
    
    544
    -    return name;
    
    545
    -
    
    546
    -  if (face && FT_HAS_GLYPH_NAMES(face))
    
    572
    +  reloadFont();
    
    573
    +  if (ftFallbackFace_ && FT_HAS_GLYPH_NAMES(ftFallbackFace_))
    
    547 574
       {
    
    548 575
         char buffer[256];
    
    549
    -    if (!FT_Get_Glyph_Name(face,
    
    576
    +    if (!FT_Get_Glyph_Name(ftFallbackFace_,
    
    550 577
                                static_cast<unsigned int>(index),
    
    551 578
                                buffer,
    
    552 579
                                sizeof(buffer)))
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -166,6 +166,8 @@ public:
    166 166
       MMGXState currentFontMMGXState() { return curMMGXState_; }
    
    167 167
       std::vector<MMGXAxisInfo>& currentFontMMGXAxes() { return curMMGXAxes_; }
    
    168 168
       std::vector<SFNTTableInfo>& currentFontSFNTTableInfo();
    
    169
    +  bool currentFontBitmapOnly();
    
    170
    +  std::vector<int> currentFontFixedSizes();
    
    169 171
       FontFileManager& fontFileManager() { return fontFileManager_; }
    
    170 172
       EngineDefaultValues& engineDefaults() { return engineDefaults_; }
    
    171 173
       bool antiAliasingEnabled() { return antiAliasingEnabled_; }
    

  • src/ftinspect/engine/stringrenderer.cpp
    ... ... @@ -364,10 +364,16 @@ StringRenderer::render(int width,
    364 364
         // Waterfall
    
    365 365
     
    
    366 366
         vertical_ = false;
    
    367
    +    // They're only effective for non-bitmap-only (scalable) fonts!
    
    367 368
         auto originalSize = static_cast<int>(engine_->pointSize() * 64);
    
    368 369
         auto ptSize = originalSize;
    
    369 370
         auto ptHeight = 64 * 72 * height / engine_->dpi();
    
    370
    -    int step;
    
    371
    +    int step = 0;
    
    372
    +
    
    373
    +    auto bitmapOnly = engine_->currentFontBitmapOnly();
    
    374
    +    auto fixedSizes = engine_->currentFontFixedSizes();
    
    375
    +    std::sort(fixedSizes.begin(), fixedSizes.end());
    
    376
    +    auto fixedSizesIter = fixedSizes.begin();
    
    371 377
     
    
    372 378
         if (waterfallStart_ <= 0)
    
    373 379
         {
    
    ... ... @@ -376,7 +382,7 @@ StringRenderer::render(int width,
    376 382
           ptSize = ptSize - step * (ptSize / step); // modulo
    
    377 383
           ptSize += step;
    
    378 384
         }
    
    379
    -    else
    
    385
    +    else if (!bitmapOnly)
    
    380 386
         {
    
    381 387
           ptSize = static_cast<int>(waterfallStart_ * 64.0) & ~31;
    
    382 388
           // we first get a ratio since height & ppem are near proportional...
    
    ... ... @@ -384,7 +390,7 @@ StringRenderer::render(int width,
    384 390
           engine_->setSizeByPoint(64.0);
    
    385 391
           engine_->reloadFont();
    
    386 392
           if (!engine_->renderReady())
    
    387
    -        return -1; // TODO: Handle bitmap-only fonts
    
    393
    +        return -1;
    
    388 394
           auto pixelActual = engine_->currentFontMetrics().height >> 6;
    
    389 395
     
    
    390 396
           auto heightPt = height * 64.0 / pixelActual;
    
    ... ... @@ -407,7 +413,14 @@ StringRenderer::render(int width,
    407 413
     
    
    408 414
         while (true)
    
    409 415
         {
    
    410
    -      engine_->setSizeByPoint(ptSize / 64.0);
    
    416
    +      if (!bitmapOnly)
    
    417
    +        engine_->setSizeByPoint(ptSize / 64.0);
    
    418
    +      else
    
    419
    +      {
    
    420
    +        if (fixedSizesIter == fixedSizes.end())
    
    421
    +          break;
    
    422
    +        engine_->setSizeByPixel(*fixedSizesIter);
    
    423
    +      }
    
    411 424
           clearActive(true);
    
    412 425
           prepareRendering(); // set size/face for engine, so metrics are valid
    
    413 426
           auto& metrics = engine_->currentFontMetrics();
    
    ... ... @@ -419,7 +432,7 @@ StringRenderer::render(int width,
    419 432
           
    
    420 433
           y += static_cast<int>(metrics.height >> 6) + 1;
    
    421 434
     
    
    422
    -      if (y >= height)
    
    435
    +      if (y >= height && !bitmapOnly)
    
    423 436
             break;
    
    424 437
     
    
    425 438
           if (ptSize == originalSize)
    
    ... ... @@ -433,9 +446,14 @@ StringRenderer::render(int width,
    433 446
                                    offset);
    
    434 447
           count = std::max(count, lcount);
    
    435 448
     
    
    436
    -      if (step == 0)
    
    437
    -        break;
    
    438
    -      ptSize += step;
    
    449
    +      if (!bitmapOnly)
    
    450
    +      {
    
    451
    +        if (step == 0)
    
    452
    +          break;
    
    453
    +        ptSize += step;
    
    454
    +      }
    
    455
    +      else
    
    456
    +        ++fixedSizesIter;
    
    439 457
         }
    
    440 458
         engine_->setSizeByPoint(originalSize / 64.0);
    
    441 459
     
    

  • src/ftinspect/panels/comparator.cpp
    ... ... @@ -49,6 +49,7 @@ ComperatorTab::repaintGlyph()
    49 49
     void
    
    50 50
     ComperatorTab::reloadFont()
    
    51 51
     {
    
    52
    +  sizeSelector_->reloadFromFont(engine_);
    
    52 53
       charMapSelector_->repopulate();
    
    53 54
       for (auto panel : settingPanels_)
    
    54 55
         panel->onFontChanged();
    

  • src/ftinspect/panels/continuous.cpp
    ... ... @@ -47,7 +47,10 @@ void
    47 47
     ContinuousTab::reloadFont()
    
    48 48
     {
    
    49 49
       currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
    
    50
    +  sizeSelector_->reloadFromFont(engine_);
    
    50 51
       setGlyphCount(qBound(0, currentGlyphCount_, INT_MAX));
    
    52
    +  checkModeSource();
    
    53
    +
    
    51 54
       charMapSelector_->repopulate();
    
    52 55
       canvas_->stringRenderer().reloadAll();
    
    53 56
       canvas_->purgeCache();
    
    ... ... @@ -163,7 +166,8 @@ ContinuousTab::checkModeSource()
    163 166
         waterfallCheckBox_->setEnabled(!vert);
    
    164 167
       }
    
    165 168
     
    
    166
    -  waterfallConfigButton_->setEnabled(waterfallCheckBox_->isChecked());
    
    169
    +  waterfallConfigButton_->setEnabled(waterfallCheckBox_->isChecked()
    
    170
    +                                     && !engine_->currentFontBitmapOnly());
    
    167 171
     
    
    168 172
       repaintGlyph();
    
    169 173
     }
    

  • src/ftinspect/panels/settingpanel.cpp
    ... ... @@ -113,6 +113,12 @@ SettingPanel::onFontChanged()
    113 113
       populatePalettes();
    
    114 114
       mmgxPanel_->reloadFont();
    
    115 115
       blockSignals(blockState);
    
    116
    +
    
    117
    +  // Place this after `blockSignals` to let the signals emitted normally
    
    118
    +  engine_->reloadFont();
    
    119
    +  embeddedBitmapCheckBox_->setEnabled(!engine_->currentFontBitmapOnly());
    
    120
    +  if (engine_->currentFontBitmapOnly())
    
    121
    +    embeddedBitmapCheckBox_->setChecked(true);
    
    116 122
     }
    
    117 123
     
    
    118 124
     
    

  • src/ftinspect/panels/singular.cpp
    ... ... @@ -409,6 +409,7 @@ SingularTab::reloadFont()
    409 409
     {
    
    410 410
       currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
    
    411 411
       indexSelector_->setMinMax(0, currentGlyphCount_);
    
    412
    +  sizeSelector_->reloadFromFont(engine_);
    
    412 413
       drawGlyph();
    
    413 414
     }
    
    414 415
     
    

  • src/ftinspect/rendering/glyphcontinuous.cpp
    ... ... @@ -472,7 +472,10 @@ GlyphContinuous::beginDrawCacheLine(QPainter* painter,
    472 472
       painter->setFont(oldFont);
    
    473 473
       auto metrics = painter->fontMetrics();
    
    474 474
     
    
    475
    -  auto sizePrefix = QString("%1: ").arg(line.sizePoint);
    
    475
    +  auto printSize = line.sizePoint;
    
    476
    +  if (engine_->currentFontBitmapOnly())
    
    477
    +    printSize = printSize * engine_->dpi() / 72.0; // convert back
    
    478
    +  auto sizePrefix = QString("%1: ").arg(printSize);
    
    476 479
       painter->drawText(line.basePosition, sizePrefix);
    
    477 480
     
    
    478 481
       sizeIndicatorOffset_ = metrics.horizontalAdvance(sizePrefix);
    

  • src/ftinspect/widgets/fontsizeselector.cpp
    ... ... @@ -6,6 +6,8 @@
    6 6
     
    
    7 7
     #include "../engine/engine.hpp"
    
    8 8
     
    
    9
    +#include <algorithm>
    
    10
    +
    
    9 11
     FontSizeSelector::FontSizeSelector(QWidget* parent)
    
    10 12
     : QWidget(parent)
    
    11 13
     {
    
    ... ... @@ -45,6 +47,25 @@ FontSizeSelector::setSizePoint(double sizePoint)
    45 47
     }
    
    46 48
     
    
    47 49
     
    
    50
    +void
    
    51
    +FontSizeSelector::reloadFromFont(Engine* engine)
    
    52
    +{
    
    53
    +  bitmapOnly_ = engine->currentFontBitmapOnly();
    
    54
    +  fixedSizes_ = engine->currentFontFixedSizes();
    
    55
    +  std::sort(fixedSizes_.begin(), fixedSizes_.end());
    
    56
    +  if (fixedSizes_.empty())
    
    57
    +    bitmapOnly_ = false; // Well this won't work...
    
    58
    +
    
    59
    +  unitsComboBox_->setEnabled(!bitmapOnly_);
    
    60
    +
    
    61
    +  {
    
    62
    +    QSignalBlocker blocker(this);
    
    63
    +    unitsComboBox_->setCurrentIndex(Units_px);
    
    64
    +  }
    
    65
    +  checkFixedSizeAndEmit();
    
    66
    +}
    
    67
    +
    
    68
    +
    
    48 69
     void
    
    49 70
     FontSizeSelector::applyToEngine(Engine* engine)
    
    50 71
     {
    
    ... ... @@ -193,18 +214,19 @@ void
    193 214
     FontSizeSelector::createConnections()
    
    194 215
     {
    
    195 216
       connect(sizeDoubleSpinBox_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    196
    -          this, &FontSizeSelector::valueChanged);
    
    217
    +          this, &FontSizeSelector::checkFixedSizeAndEmit);
    
    197 218
       connect(unitsComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    198 219
               this, &FontSizeSelector::checkUnits);
    
    199 220
       connect(dpiSpinBox_, QOverload<int>::of(&QSpinBox::valueChanged),
    
    200
    -          this, &FontSizeSelector::valueChanged);
    
    221
    +          this, &FontSizeSelector::checkFixedSizeAndEmit);
    
    201 222
     }
    
    202 223
     
    
    203 224
     
    
    204 225
     void
    
    205 226
     FontSizeSelector::setDefaults(bool sizeOnly)
    
    206 227
     {
    
    207
    -  sizeDoubleSpinBox_->setValue(20);
    
    228
    +  lastValue_ = 20;
    
    229
    +  sizeDoubleSpinBox_->setValue(lastValue_);
    
    208 230
       if (sizeOnly)
    
    209 231
         return;
    
    210 232
       dpiSpinBox_->setValue(96);
    
    ... ... @@ -212,4 +234,51 @@ FontSizeSelector::setDefaults(bool sizeOnly)
    212 234
     }
    
    213 235
     
    
    214 236
     
    
    237
    +void
    
    238
    +FontSizeSelector::checkFixedSizeAndEmit()
    
    239
    +{
    
    240
    +  if (bitmapOnly_ && !fixedSizes_.empty())
    
    241
    +  {
    
    242
    +    auto newValue = sizeDoubleSpinBox_->value();
    
    243
    +    auto intNewValue = static_cast<int>(newValue);
    
    244
    +    if (newValue != static_cast<double>(intNewValue))
    
    245
    +    {
    
    246
    +      sizeDoubleSpinBox_->setValue(intNewValue);
    
    247
    +      return; // Don't emit.
    
    248
    +    }
    
    249
    +
    
    250
    +    if (!std::binary_search(fixedSizes_.begin(), fixedSizes_.end(), newValue))
    
    251
    +    {
    
    252
    +      // Value not available, find next value.
    
    253
    +      if (intNewValue > lastValue_)
    
    254
    +      {
    
    255
    +        // find next larger value...
    
    256
    +        auto it = std::upper_bound(fixedSizes_.begin(), fixedSizes_.end(),
    
    257
    +                                   lastValue_);
    
    258
    +        if (it == fixedSizes_.end())
    
    259
    +          sizeDoubleSpinBox_->setValue(lastValue_);
    
    260
    +        else
    
    261
    +          sizeDoubleSpinBox_->setValue(*it);
    
    262
    +      }
    
    263
    +      else
    
    264
    +      {
    
    265
    +        // find next smaller value...
    
    266
    +        auto it = std::lower_bound(fixedSizes_.begin(), fixedSizes_.end(),
    
    267
    +                                   lastValue_);
    
    268
    +
    
    269
    +        // there's no element >= lastValue => all elements < last value
    
    270
    +        if (it == fixedSizes_.begin())
    
    271
    +          sizeDoubleSpinBox_->setValue(fixedSizes_.front());
    
    272
    +        else
    
    273
    +          sizeDoubleSpinBox_->setValue(*(it - 1));
    
    274
    +      }
    
    275
    +      return;
    
    276
    +    }
    
    277
    +  }
    
    278
    +
    
    279
    +  lastValue_ = sizeDoubleSpinBox_->value();
    
    280
    +  emit valueChanged();
    
    281
    +}
    
    282
    +
    
    283
    +
    
    215 284
     // end of fontsizeselector.cpp

  • src/ftinspect/widgets/fontsizeselector.hpp
    ... ... @@ -31,6 +31,7 @@ public:
    31 31
       void setSizePixel(int sizePixel);
    
    32 32
       void setSizePoint(double sizePoint);
    
    33 33
     
    
    34
    +  void reloadFromFont(Engine* engine);
    
    34 35
       void applyToEngine(Engine* engine);
    
    35 36
       void handleWheelResizeBySteps(int steps);
    
    36 37
       void handleWheelResizeFromGrid(QWheelEvent* event);
    
    ... ... @@ -56,9 +57,15 @@ private:
    56 57
     
    
    57 58
       QHBoxLayout* layout_;
    
    58 59
     
    
    60
    +  double lastValue_;
    
    61
    +  bool bitmapOnly_ = false;
    
    62
    +  std::vector<int> fixedSizes_;
    
    63
    +
    
    59 64
       void createLayout();
    
    60 65
       void createConnections();
    
    61 66
       void setDefaults(bool sizeOnly = false);
    
    67
    +
    
    68
    +  void checkFixedSizeAndEmit();
    
    62 69
     };
    
    63 70
     
    
    64 71
     
    


  • reply via email to

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