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] [ftinspect] Add tran


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-3] [ftinspect] Add transformation and scaling info to the composite glyph view.
Date: Sun, 11 Sep 2022 17:37:35 +0000

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

Commits:

  • 7cf77639
    by Charlie Jiang at 2022-09-12T01:37:18+08:00
    [ftinspect] Add transformation and scaling info to the composite glyph view.
    
    Note: Untested since no font with non-1.0 scale subglyphs is found.
    
    * src/ftinspect/engine/fontinfo.cpp, src/ftinspect/engine/fontinfo.hpp:
      Fetch transformation and scaling info from the font.
    
    * src/ftinspect/models/fontinfomodels.cpp,
      src/ftinspect/models/fontinfomodels.hpp:
      Change the "Position" column to "Position and Transformation".
      Display the transformation info.
    

4 changed files:

Changes:

  • src/ftinspect/engine/fontinfo.cpp
    ... ... @@ -571,6 +571,21 @@ SFNTTableInfo::getForAll(Engine* engine,
    571 571
     }
    
    572 572
     
    
    573 573
     
    
    574
    +
    
    575
    +FT_UInt16
    
    576
    +readUInt16(void* ptr)
    
    577
    +{
    
    578
    +  return bigEndianToNative(*static_cast<uint16_t*>(ptr));
    
    579
    +}
    
    580
    +
    
    581
    +
    
    582
    +double
    
    583
    +readF2Dot14(void* ptr)
    
    584
    +{
    
    585
    +  return static_cast<int16_t>(readUInt16(ptr)) / 16384.0;
    
    586
    +}
    
    587
    +
    
    588
    +
    
    574 589
     void
    
    575 590
     CompositeGlyphInfo::get(Engine* engine, 
    
    576 591
                             std::vector<CompositeGlyphInfo>& list)
    
    ... ... @@ -641,7 +656,7 @@ CompositeGlyphInfo::get(Engine* engine,
    641 656
         if (loc + 16 > end)
    
    642 657
           continue;
    
    643 658
     
    
    644
    -    auto len = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
    
    659
    +    auto len = static_cast<FT_Int16>(readUInt16(buffer + loc));
    
    645 660
         loc += 10;  // skip header
    
    646 661
         if (len >= 0) // not a composite one
    
    647 662
           continue;
    
    ... ... @@ -652,18 +667,18 @@ CompositeGlyphInfo::get(Engine* engine,
    652 667
         {
    
    653 668
           if (loc + 6 > end)
    
    654 669
             break;
    
    655
    -      auto flags = static_cast<FT_UInt16>(buffer[loc] << 8 | buffer[loc + 1]);
    
    670
    +      auto flags = readUInt16(buffer + loc);
    
    656 671
           loc += 2;
    
    657
    -      auto index = static_cast<FT_UInt16>(buffer[loc] << 8 | buffer[loc + 1]);
    
    672
    +      auto index = readUInt16(buffer + loc);
    
    658 673
           loc += 2;
    
    659 674
           FT_Int16 arg1, arg2;
    
    660 675
     
    
    661 676
           // https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description
    
    662 677
           if (flags & 0x0001)
    
    663 678
           {
    
    664
    -        arg1 = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
    
    679
    +        arg1 = static_cast<FT_Int16>(readUInt16(buffer + loc));
    
    665 680
             loc += 2;
    
    666
    -        arg2 = static_cast<FT_Int16>(buffer[loc] << 8 | buffer[loc + 1]);
    
    681
    +        arg2 = static_cast<FT_Int16>(readUInt16(buffer + loc));
    
    667 682
             loc += 2;
    
    668 683
           }
    
    669 684
           else
    
    ... ... @@ -672,17 +687,43 @@ CompositeGlyphInfo::get(Engine* engine,
    672 687
             arg2 = buffer[loc + 1];
    
    673 688
             loc += 2;
    
    674 689
           }
    
    690
    +
    
    691
    +      subglyphs.emplace_back(index, flags,
    
    692
    +                             flags & 0x0002 ? SubGlyph::PT_Offset
    
    693
    +                                            : SubGlyph::PT_Align,
    
    694
    +                             std::pair<short, short>(arg1, arg2),
    
    695
    +                             (flags & 0x0800) != 0);
    
    696
    +      // TODO: Use "Default behavior" when neither SCALED_COMPONENT_OFFSET
    
    697
    +      //       and UNSCALED_COMPONENT_OFFSET are set.
    
    698
    +
    
    699
    +      auto& glyph = subglyphs.back();
    
    675 700
           if (flags & 0x0008)
    
    701
    +      {
    
    702
    +        glyph.transformationType = SubGlyph::TT_UniformScale;
    
    703
    +        glyph.transformation[0] = readF2Dot14(buffer + loc);
    
    676 704
             loc += 2;
    
    705
    +      }
    
    677 706
           else if (flags & 0x0040)
    
    707
    +      {
    
    708
    +        glyph.transformationType = SubGlyph::TT_XYScale;
    
    709
    +        glyph.transformation[0] = readF2Dot14(buffer + loc);
    
    710
    +        glyph.transformation[1] = readF2Dot14(buffer + loc + 2);
    
    678 711
             loc += 4;
    
    712
    +      }
    
    679 713
           else if (flags & 0x0080)
    
    714
    +      {
    
    715
    +        glyph.transformationType = SubGlyph::TT_Matrix;
    
    716
    +        glyph.transformation[0] = readF2Dot14(buffer + loc);
    
    717
    +        glyph.transformation[1] = readF2Dot14(buffer + loc + 2);
    
    718
    +        glyph.transformation[2] = readF2Dot14(buffer + loc + 4);
    
    719
    +        glyph.transformation[3] = readF2Dot14(buffer + loc + 6);
    
    680 720
             loc += 8;
    
    681
    -
    
    682
    -      subglyphs.emplace_back(index, flags,
    
    683
    -                             flags & 0x0002 ? SubGlyph::PT_Offset
    
    684
    -                                            : SubGlyph::PT_Align,
    
    685
    -                             std::pair<short, short>(arg1, arg2));
    
    721
    +      }
    
    722
    +      else
    
    723
    +      {
    
    724
    +        glyph.transformationType = SubGlyph::TT_UniformScale;
    
    725
    +        glyph.transformation[0] = 1.0;
    
    726
    +      }
    
    686 727
     
    
    687 728
           if (!(flags & 0x0020))
    
    688 729
             break;
    

  • src/ftinspect/engine/fontinfo.hpp
    ... ... @@ -5,6 +5,7 @@
    5 5
     #pragma once
    
    6 6
     
    
    7 7
     #include <set>
    
    8
    +#include <cstring>
    
    8 9
     #include <QDateTime>
    
    9 10
     #include <QByteArray>
    
    10 11
     #include <QString>
    
    ... ... @@ -248,27 +249,44 @@ struct CompositeGlyphInfo
    248 249
     {
    
    249 250
       struct SubGlyph
    
    250 251
       {
    
    251
    -    enum PositionType
    
    252
    +    enum PositionType : uint8_t
    
    252 253
         {
    
    253 254
           PT_Offset, // Child's points are added with a xy-offset
    
    254 255
           PT_Align // One point of the child is aligned with one point of the parent
    
    255 256
         };
    
    257
    +    enum TransformationType : uint8_t
    
    258
    +    {
    
    259
    +      TT_UniformScale, // uniform scale for x- and y-axis
    
    260
    +      TT_XYScale, // separate scale for x- and y-axis
    
    261
    +      TT_Matrix // 2x2 matrix
    
    262
    +    };
    
    256 263
         unsigned short index;
    
    257 264
         unsigned short flag;
    
    258 265
         PositionType positionType;
    
    259 266
         // For PT_Offset: <deltaX, deltaY>
    
    260 267
         // For PT_Align:  <childPoint, parentPoint>
    
    261 268
         std::pair<short, short> position;
    
    269
    +    bool positionScaled;
    
    270
    +    TransformationType transformationType;
    
    271
    +    // For TT_UniformScale: transformation[0] is the scale
    
    272
    +    // For TT_XYScale: transformation[0]: x-scale; transformation[1]: y-scale
    
    273
    +    // For TT_Matrix: transformation is layouted as
    
    274
    +    //                [xscale, scale01, scale10, yscale]
    
    275
    +    double transformation[4];
    
    276
    +
    
    262 277
     
    
    263 278
         SubGlyph(unsigned short index,
    
    264 279
                  unsigned short flag,
    
    265 280
                  PositionType positionType,
    
    266
    -             std::pair<short, short> position)
    
    281
    +             std::pair<short, short> position,
    
    282
    +             bool positionScaled)
    
    267 283
         : index(index),
    
    268 284
           flag(flag),
    
    269 285
           positionType(positionType),
    
    270
    -      position(std::move(position))
    
    271
    -    { }
    
    286
    +      position(std::move(position)),
    
    287
    +      positionScaled(positionScaled)
    
    288
    +    {
    
    289
    +    }
    
    272 290
     
    
    273 291
     
    
    274 292
         friend bool
    
    ... ... @@ -278,7 +296,11 @@ struct CompositeGlyphInfo
    278 296
           return lhs.index == rhs.index
    
    279 297
             && lhs.flag == rhs.flag
    
    280 298
             && lhs.positionType == rhs.positionType
    
    281
    -        && lhs.position == rhs.position;
    
    299
    +        && lhs.position == rhs.position
    
    300
    +        && lhs.positionScaled == rhs.positionScaled
    
    301
    +        && lhs.transformationType == rhs.transformationType
    
    302
    +        && !std::memcmp(lhs.transformation, rhs.transformation,
    
    303
    +                        4 * sizeof(double));
    
    282 304
         }
    
    283 305
     
    
    284 306
     
    

  • src/ftinspect/models/fontinfomodels.cpp
    ... ... @@ -571,6 +571,53 @@ CompositeGlyphsInfoModel::parent(const QModelIndex& child) const
    571 571
     }
    
    572 572
     
    
    573 573
     
    
    574
    +QString
    
    575
    +generatePositionTransformationText(CompositeGlyphInfo::SubGlyph const& info)
    
    576
    +{
    
    577
    +  QString result;
    
    578
    +  switch (info.transformationType)
    
    579
    +  {
    
    580
    +  case CompositeGlyphInfo::SubGlyph::TT_UniformScale:
    
    581
    +    result += QString("scale: %1, ")
    
    582
    +                .arg(QString::number(info.transformation[0]));
    
    583
    +    break;
    
    584
    +  case CompositeGlyphInfo::SubGlyph::TT_XYScale: 
    
    585
    +    result += QString("xy scale: (%1, %2), ")
    
    586
    +                .arg(QString::number(info.transformation[0]),
    
    587
    +                     QString::number(info.transformation[1]));
    
    588
    +    break;
    
    589
    +  case CompositeGlyphInfo::SubGlyph::TT_Matrix:
    
    590
    +    result += QString("2x2 scale: [%1, %2; %3, %4], ")
    
    591
    +                .arg(QString::number(info.transformation[0]),
    
    592
    +                     QString::number(info.transformation[1]),
    
    593
    +                     QString::number(info.transformation[2]),
    
    594
    +                     QString::number(info.transformation[3]));
    
    595
    +    break;
    
    596
    +  }
    
    597
    +
    
    598
    +  auto pos = info.position;
    
    599
    +  switch (info.positionType)
    
    600
    +  {
    
    601
    +  case CompositeGlyphInfo::SubGlyph::PT_Offset:
    
    602
    +    if (info.positionScaled)
    
    603
    +      result += QString("scaled offset: (%1, %2)")
    
    604
    +                  .arg(QString::number(info.position.first),
    
    605
    +                       QString::number(info.position.second));
    
    606
    +    else
    
    607
    +      result += QString("offset: (%1, %2)")
    
    608
    +                  .arg(QString::number(info.position.first),
    
    609
    +                       QString::number(info.position.second));
    
    610
    +    break;
    
    611
    +  case CompositeGlyphInfo::SubGlyph::PT_Align:
    
    612
    +      result += QString("anchor points: %1 (parent) <- %2 (this glyph)")
    
    613
    +                  .arg(QString::number(info.position.first),
    
    614
    +                       QString::number(info.position.second));
    
    615
    +    break;
    
    616
    +  }
    
    617
    +  return result;
    
    618
    +}
    
    619
    +
    
    620
    +
    
    574 621
     QVariant
    
    575 622
     CompositeGlyphsInfoModel::data(const QModelIndex& index,
    
    576 623
                                    int role) const
    
    ... ... @@ -584,25 +631,6 @@ CompositeGlyphsInfoModel::data(const QModelIndex& index,
    584 631
       auto& n = nodes_[id];
    
    585 632
       auto glyphIdx = n.glyphIndex;
    
    586 633
     
    
    587
    -  if (role == Qt::ToolTipRole && index.column() == CGIM_Position)
    
    588
    -  {
    
    589
    -    if (!n.subGlyphInfo)
    
    590
    -      return {};
    
    591
    -    auto pos = n.subGlyphInfo->position;
    
    592
    -    switch (n.subGlyphInfo->positionType)
    
    593
    -    {
    
    594
    -    case CompositeGlyphInfo::SubGlyph::PT_Offset:
    
    595
    -      return QString("Add a offset (%1, %2) to the subglyph's points")
    
    596
    -          .arg(pos.first)
    
    597
    -          .arg(pos.second);
    
    598
    -    case CompositeGlyphInfo::SubGlyph::PT_Align:
    
    599
    -      return QString("Align parent's point %1 to subglyph's point %2")
    
    600
    -          .arg(pos.first)
    
    601
    -          .arg(pos.second);
    
    602
    -    }
    
    603
    -    return {};
    
    604
    -  }
    
    605
    -
    
    606 634
       if (role == Qt::DecorationRole && index.column() == CGIM_Glyph)
    
    607 635
       {
    
    608 636
         auto glyphIndex = n.glyphIndex;
    
    ... ... @@ -628,19 +656,12 @@ CompositeGlyphsInfoModel::data(const QModelIndex& index,
    628 656
       case CGIM_Flag:
    
    629 657
         if (!n.subGlyphInfo)
    
    630 658
           return {};
    
    631
    -    return QString::number(n.subGlyphInfo->flag, 16).rightJustified(4, '0');
    
    632
    -  case CGIM_Position:
    
    659
    +    return QString("0x%1").arg(n.subGlyphInfo->flag, 4, 16, QLatin1Char('0'));
    
    660
    +  case CGIM_PositionTransformation:
    
    633 661
       {
    
    634 662
         if (!n.subGlyphInfo)
    
    635 663
           return {};
    
    636
    -    auto pos = n.subGlyphInfo->position;
    
    637
    -    switch (n.subGlyphInfo->positionType)
    
    638
    -    {
    
    639
    -    case CompositeGlyphInfo::SubGlyph::PT_Offset:
    
    640
    -      return QString("Offset (%1, %2)").arg(pos.first).arg(pos.second);
    
    641
    -    case CompositeGlyphInfo::SubGlyph::PT_Align:
    
    642
    -      return QString("Align %1 -> %2").arg(pos.first).arg(pos.second);
    
    643
    -    }
    
    664
    +    return generatePositionTransformationText(*n.subGlyphInfo);
    
    644 665
       }
    
    645 666
       default:;
    
    646 667
       }
    
    ... ... @@ -665,8 +686,8 @@ CompositeGlyphsInfoModel::headerData(int section,
    665 686
         return tr("Glyph");
    
    666 687
       case CGIM_Flag:
    
    667 688
         return tr("Flags");
    
    668
    -  case CGIM_Position:
    
    669
    -    return tr("Position");
    
    689
    +  case CGIM_PositionTransformation:
    
    690
    +    return tr("Position and Transformation");
    
    670 691
       default:;
    
    671 692
       }
    
    672 693
       return {};
    

  • src/ftinspect/models/fontinfomodels.hpp
    ... ... @@ -259,9 +259,9 @@ public:
    259 259
     
    
    260 260
       enum Columns : int
    
    261 261
       {
    
    262
    -    CGIM_Glyph = 0, // TODO: transformation, scale? consider more flags?
    
    262
    +    CGIM_Glyph = 0,
    
    263 263
         CGIM_Flag = 1,
    
    264
    -    CGIM_Position = 2,
    
    264
    +    CGIM_PositionTransformation = 2,
    
    265 265
         CGIM_Max
    
    266 266
       };
    
    267 267
     
    


  • reply via email to

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