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] [ftinspect] Support


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-2] [ftinspect] Support embedded bitmap, refactor rendering.
Date: Thu, 14 Jul 2022 07:59:46 +0000

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

Commits:

  • 8deff95b
    by Charlie Jiang at 2022-07-14T15:55:50+08:00
    [ftinspect] Support embedded bitmap, refactor rendering.
    
    This commit supported embedded bitmap and more FreeType font types. Singular
    rendering widgets are refactored so they're more flexible about glyph and
    bitmap types.
    
    Replace `loadOutline` in `Engine` to `loadGlyph` and add other glyph
    formats. Move the rasterization from `GlyphBitmap` to `Engine` to decouple
    rendering from specific widgets. Engine will produce `QImage` object so
    render widgets can be agnostic about glyph type.
    
    Added "Enable Embedded Bitmap" checkbox to the GUI, so one can still force
    disable embedded bitmap output. Outline, points and point numbers showing
    are hidden when the glyph format isn't outline.
    
    LCD rendering is not yet supported because `convertLCDToARGB` and
    `convertLCDVToARGB` are not implemented.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Replace `loadOutline` to `loadGlyph`, and enable non-outline glyph types.
      Add `glyphToBitmap`, `convertBitmapTo8Bpp` and `convertBitmapToQImage`.
      Add necessary setting properties.
      TODO: Move `glyphFormatToName` and CharMap related code out from
      `engine.[ch]pp`.
    
    * src/ftinspect/rendering/glyphbitmap.cpp,
      src/ftinspect/rendering/glyphbitmap.hpp:
      Remove detailed rasterizing code, and use `Engine` to generate `QImage`..
    
    * src/ftinspect/panels/singular.cpp: Use `loadGlyph` instead of
      `loadOutline`, and remove code about pixel mode.
    
    * src/ftinspect/models/ttsettingscomboboxmodel.cpp,
      src/ftinspect/models/ttsettingscomboboxmodel.hpp:
      Make `SimpleComboBoxModel` a template class because the Anti-Aliasing
      setting combo box maps to multiple fields (load flag, render mode and
      RGB/BGR).
      Because Qt disallows template class with Q_OBJECT, we have to use mixin
      instead of inheritance. The new base class is named
      `SimpleComboBoxModelImpl` and subclass delegate function calls to it.
      Those models may subject to refactoring later.
    
    * src/ftinspect/rendering/renderutils.cpp,
      src/ftinspect/rendering/renderutils.hpp:
      Split `computeTransformationToOrigin` out from `transformOutlineToOrigin`.
    
    * src/ftinspect/rendering/glyphoutline.cpp,
      src/ftinspect/rendering/glyphoutline.hpp,
      src/ftinspect/rendering/glyphpoints.cpp,
      src/ftinspect/rendering/glyphpoints.hpp,
      src/ftinspect/rendering/glyphpointnumbers.cpp,
      src/ftinspect/rendering/glyphpointnumbers.hpp:
      Receive `FT_Glyph` instead of `FT_Outline*` as input, but don't preceed if
      the glyph isn't outline-typed.
    

17 changed files:

Changes:

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -5,12 +5,16 @@
    5 5
     
    
    6 6
     #include "engine.hpp"
    
    7 7
     
    
    8
    +#include "../rendering/renderutils.hpp"
    
    9
    +#include "../rendering/graphicsdefault.hpp"
    
    10
    +
    
    8 11
     #include <stdexcept>
    
    9 12
     #include <stdint.h>
    
    10 13
     
    
    11 14
     #include <freetype/ftmodapi.h>
    
    12 15
     #include <freetype/ftdriver.h>
    
    13 16
     #include <freetype/ftlcdfil.h>
    
    17
    +#include <freetype/ftbitmap.h>
    
    14 18
     
    
    15 19
     
    
    16 20
     /////////////////////////////////////////////////////////////////////////////
    
    ... ... @@ -153,7 +157,7 @@ Engine::Engine()
    153 157
       {
    
    154 158
         // XXX error handling
    
    155 159
       }
    
    156
    -
    
    160
    +  
    
    157 161
       queryEngine();
    
    158 162
     }
    
    159 163
     
    
    ... ... @@ -397,8 +401,8 @@ Engine::glyphName(int index)
    397 401
     }
    
    398 402
     
    
    399 403
     
    
    400
    -FT_Outline*
    
    401
    -Engine::loadOutline(int glyphIndex)
    
    404
    +FT_Glyph
    
    405
    +Engine::loadGlyph(int glyphIndex)
    
    402 406
     {
    
    403 407
       update();
    
    404 408
     
    
    ... ... @@ -407,13 +411,11 @@ Engine::loadOutline(int glyphIndex)
    407 411
     
    
    408 412
       FT_Glyph glyph;
    
    409 413
     
    
    410
    -  // XXX handle bitmap fonts
    
    411
    -
    
    412 414
       // the `scaler' object is set up by the
    
    413 415
       // `update' and `loadFont' methods
    
    414 416
       if (FTC_ImageCache_LookupScaler(imageCache_,
    
    415 417
                                       &scaler_,
    
    416
    -                                  loadFlags_ | FT_LOAD_NO_BITMAP,
    
    418
    +                                  loadFlags_,
    
    417 419
                                       static_cast<unsigned int>(glyphIndex),
    
    418 420
                                       &glyph,
    
    419 421
                                       NULL))
    
    ... ... @@ -422,21 +424,14 @@ Engine::loadOutline(int glyphIndex)
    422 424
         return NULL;
    
    423 425
       }
    
    424 426
     
    
    425
    -  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    
    426
    -    return NULL;
    
    427
    -
    
    428
    -  FT_OutlineGlyph outlineGlyph = reinterpret_cast<FT_OutlineGlyph>(glyph);
    
    429
    -
    
    430
    -  return &outlineGlyph->outline;
    
    427
    +  return glyph;
    
    431 428
     }
    
    432 429
     
    
    433 430
     
    
    434 431
     FT_Glyph
    
    435 432
     Engine::loadGlyphWithoutUpdate(int glyphIndex)
    
    436 433
     {
    
    437
    -  // TODO bitmap fonts? color layered fonts?
    
    438 434
       FT_Glyph glyph;
    
    439
    -  imageType_.flags |= FT_LOAD_NO_BITMAP;
    
    440 435
       if (FTC_ImageCache_Lookup(imageCache_,
    
    441 436
                                 &imageType_,
    
    442 437
                                 glyphIndex,
    
    ... ... @@ -451,6 +446,57 @@ Engine::loadGlyphWithoutUpdate(int glyphIndex)
    451 446
     }
    
    452 447
     
    
    453 448
     
    
    449
    +bool
    
    450
    +Engine::glyphToBitmap(FT_Glyph src,
    
    451
    +                      FT_Glyph* out)
    
    452
    +{
    
    453
    +  if (src->format == FT_GLYPH_FORMAT_BITMAP)
    
    454
    +  {
    
    455
    +    *out = src;
    
    456
    +    return false;
    
    457
    +  }
    
    458
    +  if (src->format != FT_GLYPH_FORMAT_OUTLINE)
    
    459
    +  {
    
    460
    +    *out = NULL;
    
    461
    +    return false;
    
    462
    +    // TODO support SVG
    
    463
    +  }
    
    464
    +
    
    465
    +  if (src->format == FT_GLYPH_FORMAT_OUTLINE)
    
    466
    +  {
    
    467
    +    FT_Glyph out2 = src;
    
    468
    +    auto error = FT_Glyph_To_Bitmap(&out2, 
    
    469
    +                                    static_cast<FT_Render_Mode>(renderMode_),
    
    470
    +                                    nullptr,
    
    471
    +                                    false);
    
    472
    +    if (error)
    
    473
    +    {
    
    474
    +      *out = NULL;
    
    475
    +      return false;
    
    476
    +    }
    
    477
    +    *out = out2;
    
    478
    +    return true;
    
    479
    +  }
    
    480
    +
    
    481
    +  *out = NULL;
    
    482
    +  return false;
    
    483
    +}
    
    484
    +
    
    485
    +
    
    486
    +FT_Bitmap
    
    487
    +Engine::convertBitmapTo8Bpp(FT_Bitmap* bitmap)
    
    488
    +{
    
    489
    +  FT_Bitmap out;
    
    490
    +  out.buffer = NULL;
    
    491
    +  auto error = FT_Bitmap_Convert(library_, bitmap, &out, 1);
    
    492
    +  if (error)
    
    493
    +  {
    
    494
    +    // XXX handling?
    
    495
    +  }
    
    496
    +  return out;
    
    497
    +}
    
    498
    +
    
    499
    +
    
    454 500
     int
    
    455 501
     Engine::numberOfOpenedFonts()
    
    456 502
     {
    
    ... ... @@ -527,19 +573,19 @@ Engine::update()
    527 573
       loadFlags_ = FT_LOAD_DEFAULT;
    
    528 574
       if (doAutoHinting_)
    
    529 575
         loadFlags_ |= FT_LOAD_FORCE_AUTOHINT;
    
    530
    -  loadFlags_ |= FT_LOAD_NO_BITMAP; // XXX handle bitmap fonts also
    
    576
    +
    
    577
    +  if (!embeddedBitmap_)
    
    578
    +    loadFlags_ |= FT_LOAD_NO_BITMAP;
    
    531 579
     
    
    532 580
       if (doHinting_)
    
    533 581
       {
    
    534
    -    // TODO Differentiate RGB/BGR here?
    
    535
    -    unsigned long target = antiAliasingTarget_;
    
    536
    -    loadFlags_ |= target;
    
    582
    +    loadFlags_ |= antiAliasingTarget_;
    
    537 583
       }
    
    538 584
       else
    
    539 585
       {
    
    540 586
         loadFlags_ |= FT_LOAD_NO_HINTING;
    
    541 587
     
    
    542
    -    if (!antiAliasingEnabled_) // XXX does this hold?
    
    588
    +    if (!antiAliasingEnabled_)
    
    543 589
           loadFlags_ |= FT_LOAD_MONOCHROME;
    
    544 590
       }
    
    545 591
     
    
    ... ... @@ -561,7 +607,7 @@ Engine::update()
    561 607
         scaler_.x_res = dpi_;
    
    562 608
         scaler_.y_res = dpi_;
    
    563 609
       }
    
    564
    -  
    
    610
    +
    
    565 611
       imageType_.width = static_cast<unsigned int>(pixelSize_);
    
    566 612
       imageType_.height = static_cast<unsigned int>(pixelSize_);
    
    567 613
       imageType_.flags = static_cast<int>(loadFlags_);
    
    ... ... @@ -668,6 +714,149 @@ Engine::queryEngine()
    668 714
     }
    
    669 715
     
    
    670 716
     
    
    717
    +void
    
    718
    +convertLCDToARGB(FT_Bitmap& bitmap,
    
    719
    +                 QImage& image,
    
    720
    +                 bool isBGR)
    
    721
    +{
    
    722
    +  // TODO to be implemented
    
    723
    +}
    
    724
    +
    
    725
    +
    
    726
    +void
    
    727
    +convertLCDVToARGB(FT_Bitmap& bitmap,
    
    728
    +                  QImage& image,
    
    729
    +                  bool isBGR)
    
    730
    +{
    
    731
    +  // TODO to be implemented
    
    732
    +}
    
    733
    +
    
    734
    +
    
    735
    +QImage*
    
    736
    +Engine::convertBitmapToQImage(FT_Glyph src,
    
    737
    +                              QRect* outRect)
    
    738
    +{
    
    739
    +  QImage* result = NULL;
    
    740
    +  FT_BitmapGlyph bitmapGlyph;
    
    741
    +  bool ownBitmapGlyph
    
    742
    +    = glyphToBitmap(src, reinterpret_cast<FT_Glyph*>(&bitmapGlyph));
    
    743
    +  if (!bitmapGlyph)
    
    744
    +    return result;
    
    745
    +  auto& bmap = bitmapGlyph->bitmap;
    
    746
    +  bool ownBitmap = false;
    
    747
    +
    
    748
    +  int width = bmap.width;
    
    749
    +  int height = bmap.rows;
    
    750
    +  QImage::Format format = QImage::Format_Indexed8; // goto crossing init
    
    751
    +
    
    752
    +  if (bmap.pixel_mode == FT_PIXEL_MODE_GRAY2
    
    753
    +      || bmap.pixel_mode == FT_PIXEL_MODE_GRAY4)
    
    754
    +  {
    
    755
    +    bmap = convertBitmapTo8Bpp(&bmap);
    
    756
    +    if (!bmap.buffer)
    
    757
    +      goto cleanup;
    
    758
    +    ownBitmap = true;
    
    759
    +  }
    
    760
    +
    
    761
    +  if (bmap.pixel_mode == FT_PIXEL_MODE_LCD)
    
    762
    +    width /= 3;
    
    763
    +  else if (bmap.pixel_mode == FT_PIXEL_MODE_LCD_V)
    
    764
    +    height /= 3;
    
    765
    +
    
    766
    +  if (outRect)
    
    767
    +  {
    
    768
    +    outRect->setLeft(bitmapGlyph->left);
    
    769
    +    outRect->setTop(-bitmapGlyph->top);
    
    770
    +    outRect->setWidth(width);
    
    771
    +    outRect->setHeight(height);
    
    772
    +  }
    
    773
    +
    
    774
    +  switch (bmap.pixel_mode)
    
    775
    +  {
    
    776
    +  case FT_PIXEL_MODE_MONO:
    
    777
    +    format = QImage::Format_Mono;
    
    778
    +    break;
    
    779
    +  case FT_PIXEL_MODE_GRAY:
    
    780
    +    format = QImage::Format_Indexed8;
    
    781
    +    break;
    
    782
    +  case FT_PIXEL_MODE_BGRA:
    
    783
    +    // XXX "ARGB" here means BGRA due to endianness - may be problematic
    
    784
    +    // on big-endian machines
    
    785
    +    format = QImage::Format_ARGB32_Premultiplied;
    
    786
    +    break;
    
    787
    +  case FT_PIXEL_MODE_LCD:
    
    788
    +  case FT_PIXEL_MODE_LCD_V:
    
    789
    +    format = QImage::Format_ARGB32;
    
    790
    +    break;
    
    791
    +  default:
    
    792
    +    goto cleanup;
    
    793
    +  }
    
    794
    +
    
    795
    +  switch (bmap.pixel_mode) 
    
    796
    +  {
    
    797
    +  case FT_PIXEL_MODE_MONO:
    
    798
    +  case FT_PIXEL_MODE_GRAY:
    
    799
    +  case FT_PIXEL_MODE_BGRA:
    
    800
    +    {
    
    801
    +      QImage image(bmap.buffer, 
    
    802
    +                   width, height, 
    
    803
    +                   bmap.pitch, 
    
    804
    +                   format);
    
    805
    +      if (bmap.pixel_mode == FT_PIXEL_MODE_GRAY)
    
    806
    +        image.setColorTable(GraphicsDefault::deafultInstance()->grayColorTable);
    
    807
    +      else if (bmap.pixel_mode == FT_PIXEL_MODE_MONO)
    
    808
    +        image.setColorTable(GraphicsDefault::deafultInstance()->monoColorTable);
    
    809
    +      result = new QImage(image.copy());
    
    810
    +      // Don't directly use `image` since we're destroying the image
    
    811
    +    }
    
    812
    +    break;
    
    813
    +  case FT_PIXEL_MODE_LCD:;
    
    814
    +    result = new QImage(width, height, format);
    
    815
    +    convertLCDToARGB(bmap, *result, lcdUsesBGR_);
    
    816
    +    break;
    
    817
    +  case FT_PIXEL_MODE_LCD_V:;
    
    818
    +    result = new QImage(width, height, format);
    
    819
    +    convertLCDVToARGB(bmap, *result, lcdUsesBGR_);
    
    820
    +    break;
    
    821
    +  }
    
    822
    +
    
    823
    +cleanup:
    
    824
    +  if (ownBitmapGlyph)
    
    825
    +    FT_Done_Glyph(reinterpret_cast<FT_Glyph>(bitmapGlyph));
    
    826
    +  if (ownBitmap)
    
    827
    +    FT_Bitmap_Done(library_, &bmap);
    
    828
    +
    
    829
    +  return result;
    
    830
    +}
    
    831
    +
    
    832
    +
    
    833
    +QHash<FT_Glyph_Format, QString> glyphFormatNamesCache;
    
    834
    +QHash<FT_Glyph_Format, QString>&
    
    835
    +glyphFormatNames()
    
    836
    +{
    
    837
    +  if (glyphFormatNamesCache.empty())
    
    838
    +  {
    
    839
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_NONE] = "None/Unknown";
    
    840
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_COMPOSITE] = "Composite";
    
    841
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_BITMAP] = "Bitmap";
    
    842
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_OUTLINE] = "Outline";
    
    843
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_PLOTTER] = "Plotter";
    
    844
    +    glyphFormatNamesCache[FT_GLYPH_FORMAT_SVG] = "SVG";
    
    845
    +  }
    
    846
    +  return glyphFormatNamesCache;
    
    847
    +}
    
    848
    +
    
    849
    +QString*
    
    850
    +glyphFormatToName(FT_Glyph_Format format)
    
    851
    +{
    
    852
    +  auto& names = glyphFormatNames();
    
    853
    +  auto it = names.find(format);
    
    854
    +  if (it == names.end())
    
    855
    +    return &names[FT_GLYPH_FORMAT_NONE];
    
    856
    +  return &it.value();
    
    857
    +}
    
    858
    +
    
    859
    +
    
    671 860
     QHash<FT_Encoding, QString> encodingNamesCache;
    
    672 861
     QHash<FT_Encoding, QString>&
    
    673 862
     encodingNames()
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -10,6 +10,8 @@
    10 10
     #include <vector>
    
    11 11
     #include <QString>
    
    12 12
     #include <QMap>
    
    13
    +#include <QRect>
    
    14
    +#include <QImage>
    
    13 15
     
    
    14 16
     #include <ft2build.h>
    
    15 17
     #include <freetype/freetype.h>
    
    ... ... @@ -60,6 +62,10 @@ private:
    60 62
       static int maxIndexForFaceAndCharMap(FT_CharMap charMap, unsigned max);
    
    61 63
     };
    
    62 64
     
    
    65
    +// Some helper functions.
    
    66
    +
    
    67
    +QString* glyphFormatToName(FT_Glyph_Format format);
    
    68
    +
    
    63 69
     // FreeType specific data.
    
    64 70
     
    
    65 71
     class Engine
    
    ... ... @@ -92,11 +98,17 @@ public:
    92 98
       int loadFont(int fontIndex,
    
    93 99
                    long faceIndex,
    
    94 100
                    int namedInstanceIndex); // return number of glyphs
    
    95
    -  FT_Outline* loadOutline(int glyphIndex);
    
    101
    +  FT_Glyph loadGlyph(int glyphIndex);
    
    96 102
     
    
    97 103
       // Sometimes the engine is already updated, and we want to be faster
    
    98 104
       FT_Glyph loadGlyphWithoutUpdate(int glyphIndex);
    
    99 105
     
    
    106
    +  // Return `true` if you need to free `out`
    
    107
    +  // `out` will be set to NULL in cases of error
    
    108
    +  bool glyphToBitmap(FT_Glyph src, FT_Glyph* out);
    
    109
    +  FT_Bitmap convertBitmapTo8Bpp(FT_Bitmap* bitmap);
    
    110
    +  QImage* convertBitmapToQImage(FT_Glyph src, QRect* outRect);
    
    111
    +
    
    100 112
       // reload current triplet, but with updated settings, useful for updating
    
    101 113
       // `ftSize_` only
    
    102 114
       void reloadFont(); 
    
    ... ... @@ -126,7 +138,7 @@ public:
    126 138
       FontFileManager& fontFileManager() { return fontFileManager_; }
    
    127 139
       EngineDefaultValues& engineDefaults() { return engineDefaults_; }
    
    128 140
       bool antiAliasingEnabled() { return antiAliasingEnabled_; }
    
    129
    -
    
    141
    +  bool embeddedBitmapEnabled() { return embeddedBitmap_; }
    
    130 142
     
    
    131 143
       //////// Setters (direct or indirect)
    
    132 144
     
    
    ... ... @@ -150,7 +162,10 @@ public:
    150 162
       void setShowSegments(bool showSegments) { showSegments_ = showSegments; }
    
    151 163
       void setGamma(double gamma) { gamma_ = gamma; }
    
    152 164
       void setAntiAliasingTarget(int target) { antiAliasingTarget_ = target; }
    
    165
    +  void setRenderMode(int mode) { renderMode_ = mode; }
    
    153 166
       void setAntiAliasingEnabled(bool enabled) { antiAliasingEnabled_ = enabled; }
    
    167
    +  void setEmbeddedBitmap(bool force) { embeddedBitmap_ = force; }
    
    168
    +  void setLCDUsesBGR(bool isBGR) { lcdUsesBGR_ = isBGR; }
    
    154 169
     
    
    155 170
       // Note: These 3 functions now takes actual mode/version from FreeType,
    
    156 171
       // instead of values from enum in MainGUI!
    
    ... ... @@ -203,10 +218,12 @@ private:
    203 218
       bool doVerticalHinting_;
    
    204 219
       bool doBlueZoneHinting_;
    
    205 220
       bool showSegments_;
    
    221
    +  bool embeddedBitmap_;
    
    206 222
       int antiAliasingTarget_;
    
    223
    +  bool lcdUsesBGR_;
    
    224
    +  int renderMode_;
    
    207 225
     
    
    208 226
       double gamma_;
    
    209
    -
    
    210 227
       unsigned long loadFlags_;
    
    211 228
     
    
    212 229
       void queryEngine();
    

  • src/ftinspect/models/ttsettingscomboboxmodel.cpp
    ... ... @@ -190,48 +190,6 @@ HintingModeComboBoxModel::setCurrentEngineType(HintingEngineType type)
    190 190
     }
    
    191 191
     
    
    192 192
     
    
    193
    -/////////////////////////////////////////////////////////////////////////////
    
    194
    -//
    
    195
    -// SimpleComboBoxModel
    
    196
    -//
    
    197
    -/////////////////////////////////////////////////////////////////////////////
    
    198
    -
    
    199
    -
    
    200
    -SimpleComboBoxModel::SimpleComboBoxModel(QObject* parent)
    
    201
    -: QAbstractListModel(parent)
    
    202
    -{
    
    203
    -}
    
    204
    -
    
    205
    -
    
    206
    -int
    
    207
    -SimpleComboBoxModel::rowCount(const QModelIndex& parent) const
    
    208
    -{
    
    209
    -  return items_.size();
    
    210
    -}
    
    211
    -
    
    212
    -
    
    213
    -QVariant
    
    214
    -SimpleComboBoxModel::data(const QModelIndex& index, int role) const
    
    215
    -{
    
    216
    -  if (role != Qt::DisplayRole)
    
    217
    -    return QVariant {};
    
    218
    -
    
    219
    -  int r = index.row();
    
    220
    -  if (r < 0 || r >= items_.size())
    
    221
    -    return QVariant {};
    
    222
    -  return items_[r].displayName;
    
    223
    -}
    
    224
    -
    
    225
    -
    
    226
    -int
    
    227
    -SimpleComboBoxModel::indexToValue(int index)
    
    228
    -{
    
    229
    -  if (index < 0 || index >= items_.size())
    
    230
    -    return -1;
    
    231
    -  return items_[index].value;
    
    232
    -}
    
    233
    -
    
    234
    -
    
    235 193
     /////////////////////////////////////////////////////////////////////////////
    
    236 194
     //
    
    237 195
     // LCDFilterComboBoxModel
    
    ... ... @@ -240,7 +198,7 @@ SimpleComboBoxModel::indexToValue(int index)
    240 198
     
    
    241 199
     
    
    242 200
     LCDFilterComboBoxModel::LCDFilterComboBoxModel(QObject* parent)
    
    243
    -: SimpleComboBoxModel(parent)
    
    201
    +: QAbstractListModel(parent)
    
    244 202
     {
    
    245 203
       items_[LCDFilter_Default] = {
    
    246 204
         FT_LCD_FILTER_DEFAULT,
    
    ... ... @@ -269,34 +227,34 @@ LCDFilterComboBoxModel::LCDFilterComboBoxModel(QObject* parent)
    269 227
     
    
    270 228
     
    
    271 229
     AntiAliasingComboBoxModel::AntiAliasingComboBoxModel(QObject* parent)
    
    272
    -: SimpleComboBoxModel(parent)
    
    230
    +: QAbstractListModel(parent)
    
    273 231
     {
    
    274 232
       items_[AntiAliasing_None] = {
    
    275
    -    FT_LOAD_TARGET_MONO,
    
    233
    +    {FT_LOAD_TARGET_MONO, FT_RENDER_MODE_MONO, false},
    
    276 234
         "None"
    
    277 235
       };
    
    278 236
       items_[AntiAliasing_Normal] = {
    
    279
    -    FT_LOAD_TARGET_NORMAL,
    
    237
    +    {FT_LOAD_TARGET_NORMAL, FT_RENDER_MODE_NORMAL, false},
    
    280 238
         "Normal"
    
    281 239
       };
    
    282 240
       items_[AntiAliasing_Light] = {
    
    283
    -    FT_LOAD_TARGET_LIGHT,
    
    241
    +    {FT_LOAD_TARGET_LIGHT, FT_RENDER_MODE_LIGHT, false},
    
    284 242
         "Light"
    
    285 243
       };
    
    286 244
       items_[AntiAliasing_LCD] = {
    
    287
    -    FT_LOAD_TARGET_LCD,
    
    245
    +    {FT_LOAD_TARGET_LCD, FT_RENDER_MODE_LCD, false},
    
    288 246
         "LCD (RGB)"
    
    289 247
       };
    
    290 248
       items_[AntiAliasing_LCD_BGR] = {
    
    291
    -    FT_LOAD_TARGET_LCD,
    
    249
    +    {FT_LOAD_TARGET_LCD, FT_RENDER_MODE_LCD, true},
    
    292 250
         "LCD (BGR)"
    
    293 251
       };
    
    294 252
       items_[AntiAliasing_LCD_Vertical] = {
    
    295
    -    FT_LOAD_TARGET_LCD_V,
    
    253
    +    {FT_LOAD_TARGET_LCD_V, FT_RENDER_MODE_LCD_V, false},
    
    296 254
         "LCD (vert. RGB)"
    
    297 255
       };
    
    298 256
       items_[AntiAliasing_LCD_Vertical_BGR] = {
    
    299
    -    FT_LOAD_TARGET_LCD_V, // XXX Bug: No difference between RGB and BGR?
    
    257
    +    {FT_LOAD_TARGET_LCD_V, FT_RENDER_MODE_LCD_V, true},
    
    300 258
         "LCD (vert. BGR)"
    
    301 259
       };
    
    302 260
     
    
    ... ... @@ -312,7 +270,7 @@ AntiAliasingComboBoxModel::data(const QModelIndex& index,
    312 270
         if (index.row() == AntiAliasing_Light && !lightAntiAliasingEnabled_)
    
    313 271
           return QApplication::palette().color(QPalette::Disabled, 
    
    314 272
                                                QPalette::Text);
    
    315
    -  return SimpleComboBoxModel::data(index, role);
    
    273
    +  return SimpleComboBoxModelImpl::data(index, role);
    
    316 274
     }
    
    317 275
     
    
    318 276
     
    

  • src/ftinspect/models/ttsettingscomboboxmodel.hpp
    ... ... @@ -71,25 +71,47 @@ public:
    71 71
     
    
    72 72
     
    
    73 73
     // A simple key-displayName-value model for QComboBox.
    
    74
    -class SimpleComboBoxModel
    
    75
    -: public QAbstractListModel
    
    74
    +template <class T>
    
    75
    +class SimpleComboBoxModelImpl
    
    76 76
     {
    
    77
    -  Q_OBJECT
    
    78 77
     public:
    
    79 78
       struct ComboBoxItem
    
    80 79
       {
    
    81
    -    int value;
    
    80
    +    T value;
    
    82 81
         QString displayName;
    
    83 82
       };
    
    84 83
     
    
    85
    -  explicit SimpleComboBoxModel(QObject* parent);
    
    86
    -  ~SimpleComboBoxModel() override = default;
    
    84
    +  SimpleComboBoxModelImpl() {}
    
    85
    +  virtual ~SimpleComboBoxModelImpl() = default;
    
    87 86
     
    
    88
    -  int rowCount(const QModelIndex& parent) const;
    
    89
    -  QVariant data(const QModelIndex& index,
    
    90
    -                int role) const;
    
    87
    +  virtual int
    
    88
    +  rowCount(const QModelIndex& parent) const
    
    89
    +  {
    
    90
    +    return items_.size();
    
    91
    +  }
    
    91 92
     
    
    92
    -  int indexToValue(int index);
    
    93
    +
    
    94
    +  virtual QVariant
    
    95
    +  data(const QModelIndex& index,
    
    96
    +                int role) const
    
    97
    +  {
    
    98
    +    if (role != Qt::DisplayRole)
    
    99
    +      return QVariant{};
    
    100
    +
    
    101
    +    int r = index.row();
    
    102
    +    if (r < 0 || r >= items_.size())
    
    103
    +      return QVariant{};
    
    104
    +    return items_[r].displayName;
    
    105
    +  }
    
    106
    +
    
    107
    +
    
    108
    +  virtual T
    
    109
    +  indexToValue(int index)
    
    110
    +  {
    
    111
    +    if (index < 0 || index >= items_.size())
    
    112
    +      return T();
    
    113
    +    return items_[index].value;
    
    114
    +  }
    
    93 115
     
    
    94 116
     protected:
    
    95 117
       QHash<int, ComboBoxItem> items_;
    
    ... ... @@ -97,7 +119,8 @@ protected:
    97 119
     
    
    98 120
     
    
    99 121
     class LCDFilterComboBoxModel
    
    100
    -: public SimpleComboBoxModel
    
    122
    +: public QAbstractListModel,
    
    123
    +  public SimpleComboBoxModelImpl<int>
    
    101 124
     {
    
    102 125
       Q_OBJECT
    
    103 126
     public:
    
    ... ... @@ -108,9 +131,24 @@ public:
    108 131
         QString displayName;
    
    109 132
       };
    
    110 133
     
    
    134
    +
    
    111 135
       explicit LCDFilterComboBoxModel(QObject* parent);
    
    112 136
       virtual ~LCDFilterComboBoxModel() = default;
    
    113 137
     
    
    138
    +
    
    139
    +  int rowCount(const QModelIndex& parent) const override
    
    140
    +  {
    
    141
    +    return SimpleComboBoxModelImpl::rowCount(parent);
    
    142
    +  }
    
    143
    +
    
    144
    +
    
    145
    +  QVariant
    
    146
    +  data(const QModelIndex& index,
    
    147
    +       int role) const override
    
    148
    +  {
    
    149
    +    return SimpleComboBoxModelImpl::data(index, role);
    
    150
    +  }
    
    151
    +
    
    114 152
     public:
    
    115 153
       enum LCDFilter : int
    
    116 154
       {
    
    ... ... @@ -122,8 +160,18 @@ public:
    122 160
     };
    
    123 161
     
    
    124 162
     
    
    163
    +struct AASetting
    
    164
    +{
    
    165
    +  // No default value for braced init - No C++14, what a pain!
    
    166
    +  int loadFlag;
    
    167
    +  int renderMode;
    
    168
    +  bool isBGR;
    
    169
    +};
    
    170
    +
    
    171
    +
    
    125 172
     class AntiAliasingComboBoxModel
    
    126
    -: public SimpleComboBoxModel
    
    173
    +: public QAbstractListModel,
    
    174
    +  public SimpleComboBoxModelImpl<AASetting>
    
    127 175
     {
    
    128 176
       Q_OBJECT
    
    129 177
     public:
    
    ... ... @@ -136,6 +184,13 @@ public:
    136 184
                     int role) const;
    
    137 185
       Qt::ItemFlags flags(const QModelIndex& index) const;
    
    138 186
     
    
    187
    +
    
    188
    +  int rowCount(const QModelIndex& parent) const override
    
    189
    +  {
    
    190
    +    return SimpleComboBoxModelImpl::rowCount(parent);
    
    191
    +  }
    
    192
    +
    
    193
    +
    
    139 194
       void setLightAntiAliasingEnabled(bool enabled)
    
    140 195
       {
    
    141 196
         lightAntiAliasingEnabled_ = enabled;
    

  • src/ftinspect/panels/settingpanel.cpp
    ... ... @@ -172,8 +172,12 @@ SettingPanel::syncSettings()
    172 172
       engine_->setLcdFilter(
    
    173 173
         static_cast<FT_LcdFilter>(lcdFilterComboboxModel_->indexToValue(
    
    174 174
           lcdFilterComboBox_->currentIndex())));
    
    175
    -  engine_->setAntiAliasingTarget(antiAliasingComboBoxModel_->indexToValue(
    
    176
    -    antiAliasingComboBox_->currentIndex()));
    
    175
    +
    
    176
    +  auto aaSettings = antiAliasingComboBoxModel_->indexToValue(
    
    177
    +    antiAliasingComboBox_->currentIndex());
    
    178
    +  engine_->setAntiAliasingTarget(aaSettings.loadFlag);
    
    179
    +  engine_->setRenderMode(aaSettings.renderMode);
    
    180
    +
    
    177 181
       engine_->setAntiAliasingEnabled(antiAliasingComboBox_->currentIndex()
    
    178 182
         != AntiAliasingComboBoxModel::AntiAliasing_None);
    
    179 183
       engine_->setHinting(hintingCheckBox_->isChecked());
    
    ... ... @@ -184,6 +188,9 @@ SettingPanel::syncSettings()
    184 188
       engine_->setShowSegments(segmentDrawingCheckBox_->isChecked());
    
    185 189
     
    
    186 190
       engine_->setGamma(gammaSlider_->value());
    
    191
    +
    
    192
    +  engine_->setEmbeddedBitmap(embeddedBitmapCheckBox_->isChecked());
    
    193
    +  engine_->setLCDUsesBGR(aaSettings.isBGR);
    
    187 194
     }
    
    188 195
     
    
    189 196
     
    
    ... ... @@ -218,6 +225,8 @@ SettingPanel::createConnections()
    218 225
     
    
    219 226
       connect(autoHintingCheckBox_, &QCheckBox::clicked,
    
    220 227
               this, &SettingPanel::checkAutoHinting);
    
    228
    +  connect(embeddedBitmapCheckBox_, &QCheckBox::clicked,
    
    229
    +          this, &SettingPanel::repaintNeeded);
    
    221 230
     }
    
    222 231
     
    
    223 232
     
    
    ... ... @@ -239,6 +248,7 @@ SettingPanel::createLayout()
    239 248
       verticalHintingCheckBox_ = new QCheckBox(tr("Vertical Hinting"), this);
    
    240 249
       blueZoneHintingCheckBox_ = new QCheckBox(tr("Blue-Zone Hinting"), this);
    
    241 250
       segmentDrawingCheckBox_ = new QCheckBox(tr("Segment Drawing"), this);
    
    251
    +  embeddedBitmapCheckBox_ = new QCheckBox(tr("Enable Embedded Bitmap"), this);
    
    242 252
     
    
    243 253
       antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"), this);
    
    244 254
       antiAliasingLabel_->setAlignment(Qt::AlignRight);
    
    ... ... @@ -329,6 +339,7 @@ SettingPanel::createLayout()
    329 339
       generalTabLayout_->addSpacing(20); // XXX px
    
    330 340
       generalTabLayout_->addStretch(1);
    
    331 341
       generalTabLayout_->addLayout(gammaLayout_);
    
    342
    +  generalTabLayout_->addWidget(embeddedBitmapCheckBox_);
    
    332 343
       generalTabLayout_->addSpacing(20); // XXX px
    
    333 344
       generalTabLayout_->addStretch(1);
    
    334 345
     
    
    ... ... @@ -376,6 +387,7 @@ SettingPanel::setDefaults()
    376 387
       horizontalHintingCheckBox_->setChecked(true);
    
    377 388
       verticalHintingCheckBox_->setChecked(true);
    
    378 389
       blueZoneHintingCheckBox_->setChecked(true);
    
    390
    +  embeddedBitmapCheckBox_->setChecked(false);
    
    379 391
     
    
    380 392
       gammaSlider_->setValue(18); // 1.8
    
    381 393
     }
    

  • src/ftinspect/panels/settingpanel.hpp
    ... ... @@ -63,6 +63,7 @@ private:
    63 63
       QCheckBox* blueZoneHintingCheckBox_;
    
    64 64
       QCheckBox* segmentDrawingCheckBox_;
    
    65 65
       QCheckBox* autoHintingCheckBox_;
    
    66
    +  QCheckBox* embeddedBitmapCheckBox_;
    
    66 67
     
    
    67 68
       AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
    
    68 69
       HintingModeComboBoxModel* hintingModeComboBoxModel_;
    

  • src/ftinspect/panels/singular.cpp
    ... ... @@ -87,29 +87,21 @@ SingularTab::drawGlyph()
    87 87
       }
    
    88 88
     
    
    89 89
       syncSettings();
    
    90
    -  FT_Outline* outline = engine_->loadOutline(currentGlyphIndex_);
    
    91
    -  if (outline)
    
    90
    +  FT_Glyph glyph = engine_->loadGlyph(currentGlyphIndex_);
    
    91
    +  if (glyph)
    
    92 92
       {
    
    93 93
         if (showBitmapCheckBox_->isChecked())
    
    94 94
         {
    
    95
    -      // XXX support LCD
    
    96
    -      FT_Pixel_Mode pixelMode = FT_PIXEL_MODE_GRAY;
    
    97
    -      if (!engine_->antiAliasingEnabled())
    
    98
    -        pixelMode = FT_PIXEL_MODE_MONO;
    
    99
    -
    
    100 95
           currentGlyphBitmapItem_
    
    101
    -        = new GlyphBitmap(outline,
    
    102
    -          engine_->ftLibrary(),
    
    103
    -          pixelMode,
    
    104
    -          graphicsDefault_->monoColorTable,
    
    105
    -          graphicsDefault_->grayColorTable);
    
    96
    +        = new GlyphBitmap(glyph,
    
    97
    +                          engine_);
    
    106 98
           glyphScene_->addItem(currentGlyphBitmapItem_);
    
    107 99
         }
    
    108 100
     
    
    109 101
         if (showOutlinesCheckBox_->isChecked())
    
    110 102
         {
    
    111 103
           currentGlyphOutlineItem_ = new GlyphOutline(graphicsDefault_->outlinePen, 
    
    112
    -                                                  outline);
    
    104
    +                                                  glyph);
    
    113 105
           glyphScene_->addItem(currentGlyphOutlineItem_);
    
    114 106
         }
    
    115 107
     
    
    ... ... @@ -117,7 +109,7 @@ SingularTab::drawGlyph()
    117 109
         {
    
    118 110
           currentGlyphPointsItem_ = new GlyphPoints(graphicsDefault_->onPen,
    
    119 111
                                                     graphicsDefault_->offPen,
    
    120
    -                                                outline);
    
    112
    +                                                glyph);
    
    121 113
           glyphScene_->addItem(currentGlyphPointsItem_);
    
    122 114
     
    
    123 115
           if (showPointNumbersCheckBox_->isChecked())
    
    ... ... @@ -125,7 +117,7 @@ SingularTab::drawGlyph()
    125 117
             currentGlyphPointNumbersItem_
    
    126 118
               = new GlyphPointNumbers(graphicsDefault_->onPen,
    
    127 119
                                       graphicsDefault_->offPen,
    
    128
    -                                  outline);
    
    120
    +                                  glyph);
    
    129 121
             glyphScene_->addItem(currentGlyphPointNumbersItem_);
    
    130 122
           }
    
    131 123
         }
    

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

  • src/ftinspect/rendering/glyphbitmap.hpp
    ... ... @@ -10,18 +10,18 @@
    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
     
    
    17
    +class Engine;
    
    18
    +
    
    16 19
     class GlyphBitmap
    
    17 20
     : public QGraphicsItem
    
    18 21
     {
    
    19 22
     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);
    
    23
    +  GlyphBitmap(FT_Glyph glyph,
    
    24
    +              Engine* engine);
    
    25 25
       ~GlyphBitmap() override;
    
    26 26
       QRectF boundingRect() const override;
    
    27 27
       void paint(QPainter* painter,
    
    ... ... @@ -29,11 +29,7 @@ public:
    29 29
                  QWidget* widget) override;
    
    30 30
     
    
    31 31
     private:
    
    32
    -  FT_Outline transformed_;
    
    33
    -  FT_Library library_;
    
    34
    -  unsigned char pixelMode_;
    
    35
    -  const QVector<QRgb>& monoColorTable_;
    
    36
    -  const QVector<QRgb>& grayColorTable_;
    
    32
    +  QImage* image_ = NULL;
    
    37 33
       QRectF boundingRect_;
    
    38 34
     };
    
    39 35
     
    

  • src/ftinspect/rendering/glyphoutline.cpp
    ... ... @@ -88,10 +88,16 @@ static FT_Outline_Funcs outlineFuncs =
    88 88
     
    
    89 89
     
    
    90 90
     GlyphOutline::GlyphOutline(const QPen& pen,
    
    91
    -                           FT_Outline* outline)
    
    92
    -: outlinePen_(pen),
    
    93
    -  outline_(outline)
    
    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/rendering/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,7 +19,7 @@ class GlyphOutline
    18 19
     {
    
    19 20
     public:
    
    20 21
       GlyphOutline(const QPen& pen,
    
    21
    -               FT_Outline* outline);
    
    22
    +               FT_Glyph glyph);
    
    22 23
       QRectF boundingRect() const override;
    
    23 24
       void paint(QPainter* painter,
    
    24 25
                  const QStyleOptionGraphicsItem* option,
    

  • src/ftinspect/rendering/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/rendering/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,7 +20,7 @@ class GlyphPointNumbers
    19 20
     public:
    
    20 21
       GlyphPointNumbers(const QPen& onPen,
    
    21 22
                         const QPen& offPen,
    
    22
    -                    FT_Outline* outline);
    
    23
    +                    FT_Glyph glyph);
    
    23 24
       QRectF boundingRect() const override;
    
    24 25
       void paint(QPainter* painter,
    
    25 26
                  const QStyleOptionGraphicsItem* option,
    

  • src/ftinspect/rendering/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/rendering/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,7 +20,7 @@ class GlyphPoints
    19 20
     public:
    
    20 21
       GlyphPoints(const QPen& onPen,
    
    21 22
                   const QPen& offPen,
    
    22
    -              FT_Outline* outline);
    
    23
    +              FT_Glyph glyph);
    
    23 24
       QRectF boundingRect() const override;
    
    24 25
       void paint(QPainter* painter,
    
    25 26
                  const QStyleOptionGraphicsItem* option,
    

  • src/ftinspect/rendering/renderutils.cpp
    ... ... @@ -28,6 +28,19 @@ cloneGlyph(FT_Glyph src)
    28 28
     void
    
    29 29
     transformOutlineToOrigin(FT_Outline* outline,
    
    30 30
                              FT_BBox* outControlBox)
    
    31
    +{
    
    32
    +  FT_Pos x, y;
    
    33
    +  computeTransformationToOrigin(outline,
    
    34
    +                                &x, &y,
    
    35
    +                                outControlBox);
    
    36
    +  FT_Outline_Translate(outline, x, y);
    
    37
    +}
    
    38
    +
    
    39
    +
    
    40
    +void computeTransformationToOrigin(FT_Outline* outline,
    
    41
    +                                   FT_Pos* outXOffset,
    
    42
    +                                   FT_Pos* outYOffset,
    
    43
    +                                   FT_BBox* outControlBox)
    
    31 44
     {
    
    32 45
       FT_BBox cbox;
    
    33 46
       FT_Outline_Get_CBox(outline, &cbox);
    
    ... ... @@ -37,8 +50,10 @@ transformOutlineToOrigin(FT_Outline* outline,
    37 50
       cbox.xMax = (cbox.xMax + 63) & ~63;
    
    38 51
       cbox.yMax = (cbox.yMax + 63) & ~63;
    
    39 52
       // we shift the outline to the origin for rendering later on
    
    40
    -  FT_Outline_Translate(outline, -cbox.xMin, -cbox.yMin);
    
    41
    -
    
    53
    +  if (outXOffset)
    
    54
    +    *outXOffset = -cbox.xMin;
    
    55
    +  if (outYOffset)
    
    56
    +    *outYOffset = -cbox.yMin;
    
    42 57
       if (outControlBox)
    
    43 58
         *outControlBox = cbox;
    
    44 59
     }
    

  • src/ftinspect/rendering/renderutils.hpp
    ... ... @@ -14,5 +14,10 @@ FT_Glyph cloneGlyph(FT_Glyph src);
    14 14
     void transformOutlineToOrigin(FT_Outline* outline,
    
    15 15
                                   FT_BBox* outControlBox);
    
    16 16
     
    
    17
    +void computeTransformationToOrigin(FT_Outline* outline,
    
    18
    +                                   FT_Pos* outXOffset,
    
    19
    +                                   FT_Pos* outYOffset,
    
    20
    +                                   FT_BBox* outControlBox);
    
    21
    +
    
    17 22
     
    
    18 23
     // end of renderutils.hpp


  • reply via email to

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