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] Let cont


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-2] [ftinspect] Let continuous view support non-outline glyphs.
Date: Fri, 15 Jul 2022 10:39:57 +0000

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

Commits:

  • cd132d4b
    by Charlie Jiang at 2022-07-15T18:39:38+08:00
    [ftinspect] Let continuous view support non-outline glyphs.
    
    Integrate the rendering infrastructure we built previously into the
    `GlyphContinuous`.
    
    TODO: Optimize: Cache `QImage`s because they're expensive to create.
    
    * src/ftinspect/rendering/glyphcontinuous.cpp,
      src/ftinspect/rendering/glyphcontinuous.hpp:
      As described, integrate rendering infrastructures from `Engine`.
      Add better documentation for FreeType objects stored in the class.
      Removed `cloneOutline` since you should never clone an outline alone.
      Renamed some functions.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Split `convertBitmapToQImage` into `convertGlyphToQImage` and
      `convertBitmapToQImage`, add `computeGlyphOffset` and rename
      `glyphToBitmap` to follow the style `convertXXX`.
    
    * src/ftinspect/rendering/glyphbitmap.cpp: Update renamed function ref.
    
    * src/ftinspect/rendering/renderutils.cpp,
      src/ftinspect/rendering/renderutils.hpp: Add `cloneBitmap`.
    

7 changed files:

Changes:

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -453,7 +453,7 @@ Engine::loadGlyphWithoutUpdate(int glyphIndex)
    453 453
     
    
    454 454
     
    
    455 455
     bool
    
    456
    -Engine::glyphToBitmap(FT_Glyph src,
    
    456
    +Engine::convertGlyphToBitmapGlyph(FT_Glyph src,
    
    457 457
                           FT_Glyph* out)
    
    458 458
     {
    
    459 459
       if (src->format == FT_GLYPH_FORMAT_BITMAP)
    
    ... ... @@ -739,16 +739,11 @@ convertLCDVToARGB(FT_Bitmap& bitmap,
    739 739
     
    
    740 740
     
    
    741 741
     QImage*
    
    742
    -Engine::convertBitmapToQImage(FT_Glyph src,
    
    743
    -                              QRect* outRect)
    
    742
    +Engine::convertBitmapToQImage(FT_Bitmap* src)
    
    744 743
     {
    
    745 744
       QImage* result = NULL;
    
    746
    -  FT_BitmapGlyph bitmapGlyph;
    
    747
    -  bool ownBitmapGlyph
    
    748
    -    = glyphToBitmap(src, reinterpret_cast<FT_Glyph*>(&bitmapGlyph));
    
    749
    -  if (!bitmapGlyph)
    
    750
    -    return result;
    
    751
    -  auto& bmap = bitmapGlyph->bitmap;
    
    745
    +  
    
    746
    +  auto& bmap = *src;
    
    752 747
       bool ownBitmap = false;
    
    753 748
     
    
    754 749
       int width = bmap.width;
    
    ... ... @@ -769,14 +764,6 @@ Engine::convertBitmapToQImage(FT_Glyph src,
    769 764
       else if (bmap.pixel_mode == FT_PIXEL_MODE_LCD_V)
    
    770 765
         height /= 3;
    
    771 766
     
    
    772
    -  if (outRect)
    
    773
    -  {
    
    774
    -    outRect->setLeft(bitmapGlyph->left);
    
    775
    -    outRect->setTop(-bitmapGlyph->top);
    
    776
    -    outRect->setWidth(width);
    
    777
    -    outRect->setHeight(height);
    
    778
    -  }
    
    779
    -
    
    780 767
       switch (bmap.pixel_mode)
    
    781 768
       {
    
    782 769
       case FT_PIXEL_MODE_MONO:
    
    ... ... @@ -827,8 +814,6 @@ Engine::convertBitmapToQImage(FT_Glyph src,
    827 814
       }
    
    828 815
     
    
    829 816
     cleanup:
    
    830
    -  if (ownBitmapGlyph)
    
    831
    -    FT_Done_Glyph(reinterpret_cast<FT_Glyph>(bitmapGlyph));
    
    832 817
       if (ownBitmap)
    
    833 818
         FT_Bitmap_Done(library_, &bmap);
    
    834 819
     
    
    ... ... @@ -836,6 +821,57 @@ cleanup:
    836 821
     }
    
    837 822
     
    
    838 823
     
    
    824
    +QImage*
    
    825
    +Engine::convertGlyphToQImage(FT_Glyph src, QRect* outRect)
    
    826
    +{
    
    827
    +  FT_BitmapGlyph bitmapGlyph;
    
    828
    +  bool ownBitmapGlyph
    
    829
    +    = convertGlyphToBitmapGlyph(src, reinterpret_cast<FT_Glyph*>(&bitmapGlyph));
    
    830
    +  if (!bitmapGlyph)
    
    831
    +    return NULL;
    
    832
    +
    
    833
    +  auto result = convertBitmapToQImage(&bitmapGlyph->bitmap);
    
    834
    +
    
    835
    +  if (result && outRect)
    
    836
    +  {
    
    837
    +    outRect->setLeft(bitmapGlyph->left);
    
    838
    +    outRect->setTop(-bitmapGlyph->top);
    
    839
    +    outRect->setWidth(bitmapGlyph->bitmap.width);
    
    840
    +    outRect->setHeight(bitmapGlyph->bitmap.rows);
    
    841
    +  }
    
    842
    +
    
    843
    +  if (ownBitmapGlyph)
    
    844
    +    FT_Done_Glyph(reinterpret_cast<FT_Glyph>(bitmapGlyph));
    
    845
    +
    
    846
    +  return result;
    
    847
    +}
    
    848
    +
    
    849
    +
    
    850
    +QPoint
    
    851
    +Engine::computeGlyphOffset(FT_Glyph glyph)
    
    852
    +{
    
    853
    +  if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
    
    854
    +  {
    
    855
    +    FT_BBox cbox;
    
    856
    +    FT_Outline_Get_CBox(&reinterpret_cast<FT_OutlineGlyph>(glyph)->outline, 
    
    857
    +                        &cbox);
    
    858
    +    cbox.xMin &= ~63;
    
    859
    +    cbox.yMin &= ~63;
    
    860
    +    cbox.xMax = (cbox.xMax + 63) & ~63;
    
    861
    +    cbox.yMax = (cbox.yMax + 63) & ~63;
    
    862
    +    return { static_cast<int>(cbox.xMin) / 64,
    
    863
    +               static_cast<int>(-cbox.yMax / 64) };
    
    864
    +  }
    
    865
    +  if (glyph->format == FT_GLYPH_FORMAT_BITMAP)
    
    866
    +  {
    
    867
    +    auto bg = reinterpret_cast<FT_BitmapGlyph>(glyph);
    
    868
    +    return { bg->left, -bg->top };
    
    869
    +  }
    
    870
    +
    
    871
    +  return {};
    
    872
    +}
    
    873
    +
    
    874
    +
    
    839 875
     QHash<FT_Glyph_Format, QString> glyphFormatNamesCache;
    
    840 876
     QHash<FT_Glyph_Format, QString>&
    
    841 877
     glyphFormatNames()
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -105,9 +105,11 @@ public:
    105 105
     
    
    106 106
       // Return `true` if you need to free `out`
    
    107 107
       // `out` will be set to NULL in cases of error
    
    108
    -  bool glyphToBitmap(FT_Glyph src, FT_Glyph* out);
    
    108
    +  bool convertGlyphToBitmapGlyph(FT_Glyph src, FT_Glyph* out);
    
    109 109
       FT_Bitmap convertBitmapTo8Bpp(FT_Bitmap* bitmap);
    
    110
    -  QImage* convertBitmapToQImage(FT_Glyph src, QRect* outRect);
    
    110
    +  QImage* convertBitmapToQImage(FT_Bitmap* src);
    
    111
    +  QImage* convertGlyphToQImage(FT_Glyph src, QRect* outRect);
    
    112
    +  QPoint computeGlyphOffset(FT_Glyph glyph);
    
    111 113
     
    
    112 114
       // reload current triplet, but with updated settings, useful for updating
    
    113 115
       // `ftSize_` only
    

  • src/ftinspect/rendering/glyphbitmap.cpp
    ... ... @@ -18,7 +18,7 @@ GlyphBitmap::GlyphBitmap(FT_Glyph glyph,
    18 18
                              Engine* engine)
    
    19 19
     {
    
    20 20
       QRect bRect;
    
    21
    -  image_ = engine->convertBitmapToQImage(glyph, &bRect);
    
    21
    +  image_ = engine->convertGlyphToQImage(glyph, &bRect);
    
    22 22
       boundingRect_ = bRect; // QRectF to QRect
    
    23 23
     }
    
    24 24
     
    

  • src/ftinspect/rendering/glyphcontinuous.cpp
    ... ... @@ -11,13 +11,14 @@
    11 11
     #include <QPainter>
    
    12 12
     #include <QWheelEvent>
    
    13 13
     
    
    14
    +#include <freetype/ftbitmap.h>
    
    15
    +
    
    14 16
     
    
    15 17
     GlyphContinuous::GlyphContinuous(QWidget* parent, Engine* engine)
    
    16 18
     : QWidget(parent), engine_(engine)
    
    17 19
     {
    
    18 20
       setAcceptDrops(false);
    
    19 21
       setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    20
    -  graphicsDefault_ = GraphicsDefault::deafultInstance();
    
    21 22
     
    
    22 23
       FT_Stroker_New(engine_->ftLibrary(), &stroker_);
    
    23 24
     }
    
    ... ... @@ -99,10 +100,10 @@ GlyphContinuous::paintAG(QPainter* painter)
    99 100
         switch (mode_)
    
    100 101
         {
    
    101 102
         case M_Fancy:
    
    102
    -      transformGlyphAGFancy();
    
    103
    +      transformGlyphFancy();
    
    103 104
           break;
    
    104 105
         case M_Stroked:
    
    105
    -      transformGlyphAGStroked();
    
    106
    +      transformGlyphStroked();
    
    106 107
           break;
    
    107 108
         default:;
    
    108 109
         }
    
    ... ... @@ -118,7 +119,7 @@ GlyphContinuous::paintAG(QPainter* painter)
    118 119
     
    
    119 120
     
    
    120 121
     void
    
    121
    -GlyphContinuous::transformGlyphAGFancy()
    
    122
    +GlyphContinuous::transformGlyphFancy()
    
    122 123
     {
    
    123 124
       // adopted from ftview.c:289
    
    124 125
       /***************************************************************/
    
    ... ... @@ -146,41 +147,52 @@ GlyphContinuous::transformGlyphAGFancy()
    146 147
       xstr = (FT_Pos)(metrics_.y_ppem * 64 * boldX_);
    
    147 148
       ystr = (FT_Pos)(metrics_.y_ppem * 64 * boldY_);
    
    148 149
     
    
    149
    -  if (!isGlyphCloned_)
    
    150
    -    cloneGlyph();
    
    151
    -
    
    152
    -  if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    153
    -    return; // TODO suuport non-outline: code below all depend on `outline_`!
    
    154
    -
    
    155
    -  FT_Outline_Transform(&outline_, &shear);
    
    156
    -  FT_Outline_EmboldenXY(&outline_, xstr, ystr);
    
    150
    +  if (glyph_->format == FT_GLYPH_FORMAT_OUTLINE)
    
    151
    +  {
    
    152
    +    if (!isGlyphCloned_)
    
    153
    +      cloneGlyph();
    
    154
    +    FT_Outline_Transform(&outline_, &shear);
    
    155
    +    if (FT_Outline_EmboldenXY(&outline_, xstr, ystr))
    
    156
    +    {
    
    157
    +      // XXX error handling?
    
    158
    +      return;
    
    159
    +    }
    
    157 160
     
    
    158
    -  if (glyph_->advance.x)
    
    159
    -    glyph_->advance.x += xstr;
    
    161
    +    if (glyph_->advance.x)
    
    162
    +      glyph_->advance.x += xstr;
    
    160 163
     
    
    161
    -  if (glyph_->advance.y)
    
    162
    -    glyph_->advance.y += ystr;
    
    163
    -  
    
    164
    -  //glyph_->metrics.width += xstr;
    
    165
    -  //glyph_->metrics.height += ystr;
    
    166
    -  //glyph_->metrics.horiAdvance += xstr;
    
    167
    -  //glyph_->metrics.vertAdvance += ystr;
    
    164
    +    if (glyph_->advance.y)
    
    165
    +      glyph_->advance.y += ystr;
    
    166
    +  }
    
    167
    +  else if (glyph_->format == FT_GLYPH_FORMAT_BITMAP)
    
    168
    +  {
    
    169
    +    if (!isBitmapCloned_)
    
    170
    +      cloneBitmap();
    
    171
    +    xstr &= ~63;
    
    172
    +    ystr &= ~63;
    
    173
    +
    
    174
    +    // No shearing support for bitmap
    
    175
    +    FT_Bitmap_Embolden(engine_->ftLibrary(), &bitmap_, 
    
    176
    +                       xstr, ystr);
    
    177
    +  }
    
    178
    +  else
    
    179
    +    return; // XXX no support for SVG
    
    168 180
     }
    
    169 181
     
    
    170 182
     
    
    171 183
     void
    
    172
    -GlyphContinuous::transformGlyphAGStroked()
    
    184
    +GlyphContinuous::transformGlyphStroked()
    
    173 185
     {
    
    174
    -  //if (!isGlyphCloned_)
    
    175
    -    //cloneGlyph();
    
    176
    -  // Well, now here only outline glyph is supported.
    
    186
    +  // Well, here only outline glyph is supported.
    
    177 187
       if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    178 188
         return;
    
    189
    +  auto oldGlyph = glyph_;
    
    179 190
       auto error = FT_Glyph_Stroke(&glyph_, stroker_, 0);
    
    180 191
       if (!error)
    
    181 192
       {
    
    193
    +    if (isGlyphCloned_)
    
    194
    +      FT_Done_Glyph(oldGlyph);
    
    182 195
         isGlyphCloned_ = true;
    
    183
    -    isOutlineCloned_ = false;
    
    184 196
         outline_ = reinterpret_cast<FT_OutlineGlyph>(glyph_)->outline;
    
    185 197
       }
    
    186 198
     }
    
    ... ... @@ -228,61 +240,19 @@ GlyphContinuous::paintChar(QPainter* painter)
    228 240
       // XXX: this is different from what's being done in
    
    229 241
       // `ftcommon.c`:FTDemo_Draw_Slot: is this correct??
    
    230 242
     
    
    231
    -  // First translate the outline
    
    232
    -
    
    233
    -  if (glyph_->format != FT_GLYPH_FORMAT_OUTLINE)
    
    234
    -    return true; // XXX only outline is supported - need to impl others later
    
    235
    -
    
    236
    -  FT_BBox cbox;
    
    237
    -  // Don't forget to free this when returning
    
    238
    -  if (!isOutlineCloned_ && !isGlyphCloned_)
    
    239
    -    cloneOutline();
    
    243
    +  QImage* image;
    
    240 244
       
    
    241
    -  transformOutlineToOrigin(&outline_, &cbox);
    
    242
    -  
    
    243
    -  auto outlineWidth = (cbox.xMax - cbox.xMin) / 64;
    
    244
    -  auto outlineHeight = (cbox.yMax - cbox.yMin) / 64;
    
    245
    -
    
    246
    -  // Then convert to bitmap
    
    247
    -  FT_Bitmap bitmap;
    
    248
    -  QImage::Format format = QImage::Format_Indexed8;
    
    249
    -  auto aaEnabled = engine_->antiAliasingEnabled();
    
    250
    -
    
    251
    -  // TODO cover LCD and color
    
    252
    -  if (!aaEnabled)
    
    253
    -    format = QImage::Format_Mono;
    
    254
    -
    
    255
    -  // TODO optimization: reuse QImage?
    
    256
    -  QImage image(QSize(outlineWidth, outlineHeight), format);
    
    257
    -
    
    258
    -  if (!aaEnabled)
    
    259
    -    image.setColorTable(graphicsDefault_->monoColorTable);
    
    245
    +  if (bitmap_.buffer) // Always prefer `bitmap_` since it can be manipulated
    
    246
    +    image = engine_->convertBitmapToQImage(&bitmap_);
    
    260 247
       else
    
    261
    -    image.setColorTable(graphicsDefault_->grayColorTable);
    
    248
    +    image = engine_->convertGlyphToQImage(glyph_, NULL);
    
    249
    +  auto offset = engine_->computeGlyphOffset(glyph_);
    
    262 250
     
    
    263
    -  image.fill(0);
    
    264
    -
    
    265
    -  bitmap.rows = static_cast<unsigned int>(outlineHeight);
    
    266
    -  bitmap.width = static_cast<unsigned int>(outlineWidth);
    
    267
    -  bitmap.buffer = image.bits();
    
    268
    -  bitmap.pitch = image.bytesPerLine();
    
    269
    -  bitmap.pixel_mode = aaEnabled ? FT_PIXEL_MODE_GRAY : FT_PIXEL_MODE_MONO;
    
    270
    -
    
    271
    -  FT_Error error = FT_Outline_Get_Bitmap(engine_->ftLibrary(),
    
    272
    -                                         &outline_,
    
    273
    -                                         &bitmap);
    
    274
    -  if (error)
    
    275
    -  {
    
    276
    -    // XXX error handling
    
    277
    -    return true;
    
    278
    -  }
    
    279
    -
    
    280
    -  painter->drawImage(
    
    281
    -      QPoint(x_ + cbox.xMin / 64, y_ + (-cbox.yMax / 64)),
    
    282
    -      image.convertToFormat(QImage::Format_ARGB32_Premultiplied));
    
    251
    +  painter->drawImage(offset + QPoint(x_, y_),
    
    252
    +                     *image);
    
    253
    +  delete image;
    
    283 254
     
    
    284 255
       x_ += width;
    
    285
    -  
    
    286 256
       return true;
    
    287 257
     }
    
    288 258
     
    
    ... ... @@ -290,15 +260,13 @@ GlyphContinuous::paintChar(QPainter* painter)
    290 260
     bool
    
    291 261
     GlyphContinuous::loadGlyph(int index)
    
    292 262
     {
    
    263
    +  if (isGlyphCloned_)
    
    264
    +    FT_Done_Glyph(glyph_);
    
    293 265
       glyph_ = engine_->loadGlyphWithoutUpdate(index);
    
    294 266
       isGlyphCloned_ = false;
    
    295 267
       if (!glyph_)
    
    296 268
         return false;
    
    297
    -  if (glyph_->format == FT_GLYPH_FORMAT_OUTLINE)
    
    298
    -  {
    
    299
    -    isOutlineCloned_ = false;
    
    300
    -    outline_ = reinterpret_cast<FT_OutlineGlyph>(glyph_)->outline;
    
    301
    -  }
    
    269
    +  refreshOutlineOrBitmapFromGlyph();
    
    302 270
       return true;
    
    303 271
     }
    
    304 272
     
    
    ... ... @@ -306,16 +274,57 @@ GlyphContinuous::loadGlyph(int index)
    306 274
     void
    
    307 275
     GlyphContinuous::cloneGlyph()
    
    308 276
     {
    
    277
    +  if (isGlyphCloned_)
    
    278
    +    return;
    
    309 279
       glyph_ = ::cloneGlyph(glyph_);
    
    280
    +  refreshOutlineOrBitmapFromGlyph();
    
    310 281
       isGlyphCloned_ = true;
    
    311 282
     }
    
    312 283
     
    
    313 284
     
    
    314 285
     void
    
    315
    -GlyphContinuous::cloneOutline()
    
    286
    +GlyphContinuous::cloneBitmap()
    
    316 287
     {
    
    317
    -  outline_ = ::cloneOutline(engine_->ftLibrary(), &outline_);
    
    318
    -  isOutlineCloned_ = true;
    
    288
    +  if (isBitmapCloned_)
    
    289
    +    return;
    
    290
    +  bitmap_ = ::cloneBitmap(engine_->ftLibrary(), &bitmap_);
    
    291
    +  isBitmapCloned_ = true;
    
    292
    +}
    
    293
    +
    
    294
    +
    
    295
    +void
    
    296
    +GlyphContinuous::refreshOutlineOrBitmapFromGlyph()
    
    297
    +{
    
    298
    +  if (glyph_->format == FT_GLYPH_FORMAT_OUTLINE)
    
    299
    +  {
    
    300
    +    outline_ = reinterpret_cast<FT_OutlineGlyph>(glyph_)->outline;
    
    301
    +
    
    302
    +    // Make `bitmap_` invalid
    
    303
    +    if (isBitmapCloned_)
    
    304
    +      FT_Bitmap_Done(engine_->ftLibrary(), &bitmap_);
    
    305
    +    isBitmapCloned_ = false;
    
    306
    +    bitmap_.buffer = NULL;
    
    307
    +  }
    
    308
    +  else if (glyph_->format == FT_GLYPH_FORMAT_BITMAP)
    
    309
    +  {
    
    310
    +    // Initialize `bitmap_`
    
    311
    +    if (isBitmapCloned_)
    
    312
    +      FT_Bitmap_Done(engine_->ftLibrary(), &bitmap_);
    
    313
    +    isBitmapCloned_ = false;
    
    314
    +    bitmap_ = reinterpret_cast<FT_BitmapGlyph>(glyph_)->bitmap;
    
    315
    +
    
    316
    +    outline_.points = NULL;
    
    317
    +  }
    
    318
    +  else
    
    319
    +  {
    
    320
    +    // Both invalid.
    
    321
    +    outline_.points = NULL;
    
    322
    +
    
    323
    +    if (isBitmapCloned_)
    
    324
    +      FT_Bitmap_Done(engine_->ftLibrary(), &bitmap_);
    
    325
    +    isBitmapCloned_ = false;
    
    326
    +    bitmap_.buffer = NULL;
    
    327
    +  }
    
    319 328
     }
    
    320 329
     
    
    321 330
     
    
    ... ... @@ -324,13 +333,17 @@ GlyphContinuous::cleanCloned()
    324 333
     {
    
    325 334
       if (isGlyphCloned_)
    
    326 335
       {
    
    336
    +    if (glyph_->format == FT_GLYPH_FORMAT_BITMAP && !isBitmapCloned_)
    
    337
    +      bitmap_.buffer = NULL;
    
    338
    +
    
    327 339
         FT_Done_Glyph(glyph_);
    
    328 340
         isGlyphCloned_ = false;
    
    329 341
       }
    
    330
    -  if (isOutlineCloned_)
    
    342
    +  if (isBitmapCloned_)
    
    331 343
       {
    
    332
    -    FT_Outline_Done(engine_->ftLibrary(), &outline_);
    
    333
    -    isOutlineCloned_ = false;
    
    344
    +    FT_Bitmap_Done(engine_->ftLibrary(), &bitmap_);
    
    345
    +    bitmap_.buffer = NULL;
    
    346
    +    isBitmapCloned_ = false;
    
    334 347
       }
    
    335 348
     }
    
    336 349
     
    

  • src/ftinspect/rendering/glyphcontinuous.hpp
    ... ... @@ -70,7 +70,6 @@ protected:
    70 70
     
    
    71 71
     private:
    
    72 72
       Engine* engine_;
    
    73
    -  GraphicsDefault* graphicsDefault_;
    
    74 73
     
    
    75 74
       Source source_ = SRC_AllGlyphs;
    
    76 75
       Mode mode_ = M_Normal;
    
    ... ... @@ -88,23 +87,35 @@ private:
    88 87
       FT_Size_Metrics metrics_;
    
    89 88
       int x_ = 0, y_ = 0;
    
    90 89
       int stepY_ = 0;
    
    90
    +
    
    91
    +  // Pay especially attention to life cycles & ownerships of those objects:
    
    92
    +  // Note that outline and bitmap can be either invalid, owned by glyph or
    
    93
    +  // owned by `this`.
    
    94
    +  // If owned by `this`, then it's safe to do manipulation, and need to cleanup
    
    95
    +  // If owned by glyph, then must clone to do manipulation, and no cleanup
    
    96
    +  // In `loadGraph`, these 3 values will all be updated.
    
    97
    +  // Note that `glyph_` is a pointer, while `outline_` and `bitmap_` are structs
    
    91 98
       FT_Glyph glyph_;
    
    92
    -  FT_Outline outline_;
    
    99
    +  FT_Outline outline_; // Using outline_->points == NULL to determine validity
    
    100
    +  FT_Bitmap bitmap_; // Using bitmap_->buffer == NULL to determine validity
    
    93 101
       // when glyph is cloned, outline is factually also cloned
    
    94
    -  // but `isOutlineCloned` won't be set!
    
    95
    -  bool isGlyphCloned_ = false, isOutlineCloned_ = false;
    
    102
    +  // never manually clone your outline or you can't easily render it!
    
    103
    +  bool isGlyphCloned_ = false;
    
    104
    +  bool isBitmapCloned_ = false;
    
    96 105
     
    
    97 106
       FT_Stroker stroker_;
    
    98 107
     
    
    99 108
       void paintAG(QPainter* painter);
    
    100
    -  void transformGlyphAGFancy();
    
    101
    -  void transformGlyphAGStroked();
    
    109
    +  void transformGlyphFancy();
    
    110
    +  void transformGlyphStroked();
    
    102 111
       void prePaint();
    
    103 112
       // return if there's enough space to paint the current char
    
    104 113
       bool paintChar(QPainter* painter);
    
    105 114
       bool loadGlyph(int index);
    
    115
    +
    
    106 116
       void cloneGlyph();
    
    107
    -  void cloneOutline();
    
    117
    +  void cloneBitmap();
    
    118
    +  void refreshOutlineOrBitmapFromGlyph();
    
    108 119
       void cleanCloned();
    
    109 120
     
    
    110 121
       bool checkFitX(int x);
    

  • src/ftinspect/rendering/renderutils.cpp
    ... ... @@ -25,6 +25,19 @@ cloneGlyph(FT_Glyph src)
    25 25
     }
    
    26 26
     
    
    27 27
     
    
    28
    +FT_Bitmap
    
    29
    +cloneBitmap(FT_Library library,
    
    30
    +            FT_Bitmap* src)
    
    31
    +{
    
    32
    +  FT_Bitmap target = *src;
    
    33
    +  target.buffer = NULL;
    
    34
    +  target.palette = NULL;
    
    35
    +  FT_Bitmap_Init(&target);
    
    36
    +  FT_Bitmap_Copy(library, src, &target);
    
    37
    +  return target;
    
    38
    +}
    
    39
    +
    
    40
    +
    
    28 41
     void
    
    29 42
     transformOutlineToOrigin(FT_Outline* outline,
    
    30 43
                              FT_BBox* outControlBox)
    

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


  • reply via email to

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