freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype-demos][gsoc-2022-chariri-3] 2 commits: * src/fti


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-3] 2 commits: * src/ftinspect/engine/engine.cpp: Support LCD rendering.
Date: Fri, 19 Aug 2022 14:38:37 +0000

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

Commits:

  • ef14bfd2
    by Charlie Jiang at 2022-08-19T16:54:23+08:00
    * src/ftinspect/engine/engine.cpp: Support LCD rendering.
    
    It was a great decision to refactor the color table part.
    
  • 6b689304
    by Charlie Jiang at 2022-08-19T22:38:19+08:00
    [ftinspect] Fix crashing on bitmap-only fonts.
    
    See #16. Unscalable fonts still can't be rendered properly, though.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `ftFallbackFace_`, and lookup the face before the size. All accessing
      to the face when not rendering (e.g. retrieving font info) is changed to
      use the fallback face in case the size is invalid due to non-scalable
      font.
      Add `renderReady` and `fontValid` to indicate if the size or the face is
      valid. Use those two getters instead of checking the current glyph count
      for validity.
    
    * src/ftinspect/engine/fontinfo.cpp, src/ftinspect/engine/mmgx.cpp,
      src/ftinspect/panels/info.cpp:
      Use fallback face instead of the size to retrieve font info.
    
    * src/ftinspect/engine/stringrenderer.cpp,
      src/ftinspect/rendering/glyphcontinuous.cpp,
      src/ftinspect/rendering/glyphcontinuous.hpp: Fix crash with `renderReady`.
    
    * src/ftinspect/widgets/tripletselector.cpp:
      Fix undesired infinite font reloading due to bad ppem value.
    

9 changed files:

Changes:

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -124,6 +124,7 @@ faceRequester(FTC_FaceID ftcFaceID,
    124 124
     Engine::Engine()
    
    125 125
     {
    
    126 126
       ftSize_ = NULL;
    
    127
    +  ftFallbackFace_ = NULL;
    
    127 128
       // we reserve value 0 for the `invalid face ID'
    
    128 129
       faceCounter_ = 1;
    
    129 130
     
    
    ... ... @@ -292,8 +293,18 @@ Engine::loadFont(int fontIndex,
    292 293
       if (scaler_.face_id)
    
    293 294
       {
    
    294 295
         // found
    
    295
    -    if (!FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    296
    -      numGlyphs = ftSize_->face->num_glyphs;
    
    296
    +    if (!FTC_Manager_LookupFace(cacheManager_, scaler_.face_id,
    
    297
    +                               &ftFallbackFace_))
    
    298
    +    {
    
    299
    +      numGlyphs = ftFallbackFace_->num_glyphs;
    
    300
    +      if (FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    301
    +        ftSize_ = NULL; // Good font, bad size.
    
    302
    +    }
    
    303
    +    else
    
    304
    +    {
    
    305
    +      ftFallbackFace_ = NULL;
    
    306
    +      ftSize_ = NULL;
    
    307
    +    }
    
    297 308
       }
    
    298 309
       else if (fontIndex >= 0)
    
    299 310
       {
    
    ... ... @@ -305,12 +316,19 @@ Engine::loadFont(int fontIndex,
    305 316
         scaler_.face_id = reinterpret_cast<FTC_FaceID>(faceCounter_);
    
    306 317
         faceIDMap_.insert(id, faceCounter_++);
    
    307 318
     
    
    308
    -    if (!FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    309
    -      numGlyphs = ftSize_->face->num_glyphs;
    
    319
    +    if (!FTC_Manager_LookupFace(cacheManager_, scaler_.face_id,
    
    320
    +                                &ftFallbackFace_))
    
    321
    +    {
    
    322
    +      numGlyphs = ftFallbackFace_->num_glyphs;
    
    323
    +      if (FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    324
    +        ftSize_ = NULL; // Good font, bad size.
    
    325
    +    }
    
    310 326
         else
    
    311 327
         {
    
    312 328
           faceIDMap_.remove(id);
    
    313 329
           faceCounter_--;
    
    330
    +      ftFallbackFace_ = NULL;
    
    331
    +      ftSize_ = NULL;
    
    314 332
         }
    
    315 333
       }
    
    316 334
     
    
    ... ... @@ -318,6 +336,7 @@ Engine::loadFont(int fontIndex,
    318 336
     
    
    319 337
       if (numGlyphs < 0)
    
    320 338
       {
    
    339
    +    ftFallbackFace_ = NULL;
    
    321 340
         ftSize_ = NULL;
    
    322 341
         curFamilyName_ = QString();
    
    323 342
         curStyleName_ = QString();
    
    ... ... @@ -328,11 +347,10 @@ Engine::loadFont(int fontIndex,
    328 347
       }
    
    329 348
       else
    
    330 349
       {
    
    331
    -    auto face = ftSize_->face;
    
    332
    -    curFamilyName_ = QString(face->family_name);
    
    333
    -    curStyleName_ = QString(face->style_name);
    
    350
    +    curFamilyName_ = QString(ftFallbackFace_->family_name);
    
    351
    +    curStyleName_ = QString(ftFallbackFace_->style_name);
    
    334 352
     
    
    335
    -    const char* moduleName = FT_FACE_DRIVER_NAME( face );
    
    353
    +    const char* moduleName = FT_FACE_DRIVER_NAME(ftFallbackFace_);
    
    336 354
     
    
    337 355
         // XXX cover all available modules
    
    338 356
         if (!strcmp(moduleName, "cff"))
    
    ... ... @@ -341,9 +359,9 @@ Engine::loadFont(int fontIndex,
    341 359
           fontType_ = FontType_TrueType;
    
    342 360
     
    
    343 361
         curCharMaps_.clear();
    
    344
    -    curCharMaps_.reserve(face->num_charmaps);
    
    345
    -    for (int i = 0; i < face->num_charmaps; i++)
    
    346
    -      curCharMaps_.emplace_back(i, face->charmaps[i]);
    
    362
    +    curCharMaps_.reserve(ftFallbackFace_->num_charmaps);
    
    363
    +    for (int i = 0; i < ftFallbackFace_->num_charmaps; i++)
    
    364
    +      curCharMaps_.emplace_back(i, ftFallbackFace_->charmaps[i]);
    
    347 365
     
    
    348 366
         SFNTName::get(this, curSFNTNames_);
    
    349 367
         loadPaletteInfos();
    
    ... ... @@ -362,6 +380,7 @@ Engine::reloadFont()
    362 380
       if (!scaler_.face_id)
    
    363 381
         return;
    
    364 382
       imageType_.face_id = scaler_.face_id;
    
    383
    +  FTC_Manager_LookupFace(cacheManager_, scaler_.face_id, &ftFallbackFace_);
    
    365 384
       FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_);
    
    366 385
     }
    
    367 386
     
    
    ... ... @@ -375,6 +394,9 @@ Engine::loadPalette()
    375 394
           || paletteData_.num_palettes <= paletteIndex_)
    
    376 395
         return;
    
    377 396
     
    
    397
    +  if (!ftSize_)
    
    398
    +    return;
    
    399
    +
    
    378 400
       FT_Palette_Select(ftSize_->face, 
    
    379 401
                         static_cast<FT_UShort>(paletteIndex_),
    
    380 402
                         &palette_);
    
    ... ... @@ -436,6 +458,9 @@ Engine::currentFaceSlot()
    436 458
     FT_Pos
    
    437 459
     Engine::currentFontTrackingKerning(int degree)
    
    438 460
     {
    
    461
    +  if (!ftSize_)
    
    462
    +    return 0;
    
    463
    +
    
    439 464
       FT_Pos result;
    
    440 465
       // this function needs and returns points, not pixels
    
    441 466
       if (!FT_Get_Track_Kerning(ftSize_->face,
    
    ... ... @@ -513,16 +538,14 @@ Engine::glyphName(int index)
    513 538
       if (index < 0)
    
    514 539
         throw std::runtime_error("Invalid glyph index");
    
    515 540
     
    
    516
    -  if (!ftSize_)
    
    517
    -    return "";
    
    518
    -  
    
    519
    -  if (!FTC_Manager_LookupSize(cacheManager_, &scaler_, &ftSize_))
    
    541
    +  FT_Face face = NULL;
    
    542
    +  if (FTC_Manager_LookupFace(cacheManager_, scaler_.face_id, &face))
    
    520 543
         return name;
    
    521 544
     
    
    522
    -  if (ftSize_ && FT_HAS_GLYPH_NAMES(ftSize_->face))
    
    545
    +  if (face && FT_HAS_GLYPH_NAMES(face))
    
    523 546
       {
    
    524 547
         char buffer[256];
    
    525
    -    if (!FT_Get_Glyph_Name(ftSize_->face,
    
    548
    +    if (!FT_Get_Glyph_Name(face,
    
    526 549
                                static_cast<unsigned int>(index),
    
    527 550
                                buffer,
    
    528 551
                                sizeof(buffer)))
    
    ... ... @@ -649,6 +672,20 @@ Engine::convertBitmapTo8Bpp(FT_Bitmap* bitmap)
    649 672
     }
    
    650 673
     
    
    651 674
     
    
    675
    +bool
    
    676
    +Engine::renderReady()
    
    677
    +{
    
    678
    +  return ftSize_ != NULL;
    
    679
    +}
    
    680
    +
    
    681
    +
    
    682
    +bool
    
    683
    +Engine::fontValid()
    
    684
    +{
    
    685
    +  return ftFallbackFace_ != NULL;
    
    686
    +}
    
    687
    +
    
    688
    +
    
    652 689
     int
    
    653 690
     Engine::numberOfOpenedFonts()
    
    654 691
     {
    
    ... ... @@ -709,6 +746,7 @@ Engine::setCFFHintingMode(int mode)
    709 746
       {
    
    710 747
         // reset the cache
    
    711 748
         FTC_Manager_Reset(cacheManager_);
    
    749
    +    ftFallbackFace_ = NULL;
    
    712 750
         ftSize_ = NULL;
    
    713 751
       }
    
    714 752
     }
    
    ... ... @@ -725,6 +763,7 @@ Engine::setTTInterpreterVersion(int version)
    725 763
       {
    
    726 764
         // reset the cache
    
    727 765
         FTC_Manager_Reset(cacheManager_);
    
    766
    +    ftFallbackFace_ = NULL;
    
    728 767
         ftSize_ = NULL;
    
    729 768
       }
    
    730 769
     }
    
    ... ... @@ -753,6 +792,7 @@ Engine::setStemDarkening(bool darkening)
    753 792
                       &noDarkening);
    
    754 793
       // reset the cache
    
    755 794
       FTC_Manager_Reset(cacheManager_);
    
    795
    +  ftFallbackFace_ = NULL;
    
    756 796
       ftSize_ = NULL;
    
    757 797
     }
    
    758 798
     
    
    ... ... @@ -931,7 +971,7 @@ Engine::loadPaletteInfos()
    931 971
     {
    
    932 972
       curPaletteInfos_.clear();
    
    933 973
     
    
    934
    -  if (FT_Palette_Data_Get(ftSize_->face, &paletteData_))
    
    974
    +  if (FT_Palette_Data_Get(ftFallbackFace_, &paletteData_))
    
    935 975
       {
    
    936 976
         // XXX Error handling
    
    937 977
         paletteData_.num_palettes = 0;
    
    ... ... @@ -941,7 +981,7 @@ Engine::loadPaletteInfos()
    941 981
       // size never exceeds max val of ushort.
    
    942 982
       curPaletteInfos_.reserve(paletteData_.num_palettes);
    
    943 983
       for (int i = 0; i < paletteData_.num_palettes; ++i)
    
    944
    -    curPaletteInfos_.emplace_back(ftSize_->face, paletteData_, i,
    
    984
    +    curPaletteInfos_.emplace_back(ftFallbackFace_, paletteData_, i,
    
    945 985
                                       &curSFNTNames_);
    
    946 986
     }
    
    947 987
     
    
    ... ... @@ -987,18 +1027,70 @@ Engine::calculateForegroundTable()
    987 1027
     void
    
    988 1028
     convertLCDToARGB(FT_Bitmap& bitmap,
    
    989 1029
                      QImage& image,
    
    990
    -                 bool isBGR)
    
    1030
    +                 bool isBGR,
    
    1031
    +                 QVector<QRgb>& colorTable)
    
    991 1032
     {
    
    992
    -  // TODO to be implemented
    
    1033
    +  int height = bitmap.rows;
    
    1034
    +  int width = bitmap.width / 3;
    
    1035
    +  int width3 = bitmap.width;
    
    1036
    +
    
    1037
    +  unsigned char* srcPtr = bitmap.buffer;
    
    1038
    +  unsigned* dstPtr = reinterpret_cast<unsigned*>(image.bits());
    
    1039
    +
    
    1040
    +  int offR = !isBGR ? 0 : 2;
    
    1041
    +  int offG = 1;
    
    1042
    +  int offB = isBGR ? 0 : 2;
    
    1043
    +  for (int i = 0; i < height; i++)
    
    1044
    +  {
    
    1045
    +    for (int j = 0; j < width3; j += 3)
    
    1046
    +    {
    
    1047
    +      unsigned char ar = srcPtr[j + offR];
    
    1048
    +      unsigned char ag = srcPtr[j + offG];
    
    1049
    +      unsigned char ab = srcPtr[j + offB];
    
    1050
    +      unsigned dr = colorTable[ar] & 0xFF;
    
    1051
    +      unsigned dg = colorTable[ag] & 0xFF;
    
    1052
    +      unsigned db = colorTable[ab] & 0xFF;
    
    1053
    +      *dstPtr = (0xFFu << 24) | (dr << 16) | (dg << 8) | db;
    
    1054
    +      dstPtr++;
    
    1055
    +    }
    
    1056
    +    srcPtr += bitmap.pitch;
    
    1057
    +    dstPtr += image.bytesPerLine() / 4 - width; // skip blank area
    
    1058
    +  }
    
    993 1059
     }
    
    994 1060
     
    
    995 1061
     
    
    996 1062
     void
    
    997 1063
     convertLCDVToARGB(FT_Bitmap& bitmap,
    
    998 1064
                       QImage& image,
    
    999
    -                  bool isBGR)
    
    1065
    +                  bool isBGR,
    
    1066
    +                  QVector<QRgb>& colorTable)
    
    1000 1067
     {
    
    1001
    -  // TODO to be implemented
    
    1068
    +  int height = bitmap.rows / 3;
    
    1069
    +  int width = bitmap.width;
    
    1070
    +  int srcPitch = bitmap.pitch;
    
    1071
    +
    
    1072
    +  unsigned char* srcPtr = bitmap.buffer;
    
    1073
    +  unsigned* dstPtr = reinterpret_cast<unsigned*>(image.bits());
    
    1074
    +
    
    1075
    +  int offR = !isBGR ? 0 : 2 * srcPitch;
    
    1076
    +  int offG = srcPitch;
    
    1077
    +  int offB = isBGR ? 0 : 2 * srcPitch;
    
    1078
    +  for (int i = 0; i < height; i++)
    
    1079
    +  {
    
    1080
    +    for (int j = 0; j < width; j++)
    
    1081
    +    {
    
    1082
    +      unsigned char ar = srcPtr[j + offR];
    
    1083
    +      unsigned char ag = srcPtr[j + offG];
    
    1084
    +      unsigned char ab = srcPtr[j + offB];
    
    1085
    +      unsigned dr = colorTable[ar] & 0xFF;
    
    1086
    +      unsigned dg = colorTable[ag] & 0xFF;
    
    1087
    +      unsigned db = colorTable[ab] & 0xFF;
    
    1088
    +      *dstPtr = (0xFFu << 24) | (dr << 16) | (dg << 8) | db;
    
    1089
    +      dstPtr++;
    
    1090
    +    }
    
    1091
    +    srcPtr += 3ull * srcPitch;                  // move 3 lines
    
    1092
    +    dstPtr += image.bytesPerLine() / 4 - width; // skip blank area
    
    1093
    +  }
    
    1002 1094
     }
    
    1003 1095
     
    
    1004 1096
     
    
    ... ... @@ -1076,11 +1168,11 @@ Engine::convertBitmapToQImage(FT_Bitmap* src)
    1076 1168
         break;
    
    1077 1169
       case FT_PIXEL_MODE_LCD:;
    
    1078 1170
         result = new QImage(width, height, format);
    
    1079
    -    convertLCDToARGB(bmap, *result, lcdUsesBGR_);
    
    1171
    +    convertLCDToARGB(bmap, *result, lcdUsesBGR_, foregroundTable_);
    
    1080 1172
         break;
    
    1081 1173
       case FT_PIXEL_MODE_LCD_V:;
    
    1082 1174
         result = new QImage(width, height, format);
    
    1083
    -    convertLCDVToARGB(bmap, *result, lcdUsesBGR_);
    
    1175
    +    convertLCDVToARGB(bmap, *result, lcdUsesBGR_, foregroundTable_);
    
    1084 1176
         break;
    
    1085 1177
       }
    
    1086 1178
     
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -131,9 +131,12 @@ public:
    131 131
       int dpi() { return dpi_; }
    
    132 132
       double pointSize() { return pointSize_; }
    
    133 133
     
    
    134
    +  bool renderReady();
    
    135
    +  bool fontValid();
    
    134 136
       int numberOfOpenedFonts();
    
    135 137
       int currentFontIndex() { return curFontIndex_; }
    
    136
    -  FT_Size currentFtSize() { return ftSize_; }
    
    138
    +  FT_Face currentFallbackFtFace() { return ftFallbackFace_; }
    
    139
    +  // FT_Size currentFtSize() { return ftSize_; }
    
    137 140
       int currentFontType() const { return fontType_; }
    
    138 141
       const QString& currentFamilyName() { return curFamilyName_; }
    
    139 142
       const QString& currentStyleName() { return curStyleName_; }
    
    ... ... @@ -247,6 +250,7 @@ private:
    247 250
     
    
    248 251
       FTC_ScalerRec scaler_ = {};
    
    249 252
       FTC_ImageTypeRec imageType_;
    
    253
    +  FT_Face ftFallbackFace_; // Never perform rendering or write to this!
    
    250 254
       FT_Size ftSize_;
    
    251 255
       FT_Palette_Data paletteData_ = {};
    
    252 256
       FT_Color* palette_ = NULL;
    

  • src/ftinspect/engine/fontinfo.cpp
    ... ... @@ -32,14 +32,13 @@ void
    32 32
     SFNTName::get(Engine* engine,
    
    33 33
                   std::vector<SFNTName>& list)
    
    34 34
     {
    
    35
    -  auto size = engine->currentFtSize();
    
    36
    -  if (!size || !FT_IS_SFNT(size->face))
    
    35
    +  auto face = engine->currentFallbackFtFace();
    
    36
    +  if (!face || !FT_IS_SFNT(face))
    
    37 37
       {
    
    38 38
         list.clear();
    
    39 39
         return;
    
    40 40
       }
    
    41
    -
    
    42
    -  auto face = size->face;
    
    41
    +  
    
    43 42
       auto newSize = FT_Get_Sfnt_Name_Count(face);
    
    44 43
       if (list.size() != static_cast<size_t>(newSize))
    
    45 44
         list.resize(newSize);
    
    ... ... @@ -184,11 +183,10 @@ FontBasicInfo::get(Engine* engine)
    184 183
       result.numFaces = engine->numberOfFaces(fontIndex);
    
    185 184
     
    
    186 185
       engine->reloadFont();
    
    187
    -  auto size = engine->currentFtSize();
    
    188
    -  if (!size)
    
    186
    +  auto face = engine->currentFallbackFtFace();
    
    187
    +  if (!face)
    
    189 188
         return result;
    
    190 189
     
    
    191
    -  auto face = size->face;
    
    192 190
       if (face->family_name)
    
    193 191
         result.familyName = QString(face->family_name);
    
    194 192
       if (face->style_name)
    
    ... ... @@ -228,12 +226,10 @@ FontTypeEntries
    228 226
     FontTypeEntries::get(Engine* engine)
    
    229 227
     {
    
    230 228
       engine->reloadFont();
    
    231
    -  auto size = engine->currentFtSize();
    
    232
    -  if (!size)
    
    229
    +  auto face = engine->currentFallbackFtFace();
    
    230
    +  if (!face)
    
    233 231
         return {};
    
    234
    -
    
    235
    -  auto face = size->face;
    
    236
    -
    
    232
    +  
    
    237 233
       FontTypeEntries result = {};
    
    238 234
       result.driverName = QString(FT_FACE_DRIVER_NAME(face));
    
    239 235
       result.sfnt = FT_IS_SFNT(face);
    
    ... ... @@ -332,8 +328,8 @@ FontFixedSize::get(Engine* engine,
    332 328
                        const std::function<void()>& onUpdateNeeded)
    
    333 329
     {
    
    334 330
       engine->reloadFont();
    
    335
    -  auto size = engine->currentFtSize();
    
    336
    -  if (!size)
    
    331
    +  auto face = engine->currentFallbackFtFace();
    
    332
    +  if (!face)
    
    337 333
       {
    
    338 334
         if (list.empty())
    
    339 335
           return false;
    
    ... ... @@ -342,8 +338,7 @@ FontFixedSize::get(Engine* engine,
    342 338
         list.clear();
    
    343 339
         return true;
    
    344 340
       }
    
    345
    -
    
    346
    -  auto face = size->face;
    
    341
    +  
    
    347 342
       auto changed = false;
    
    348 343
       if (list.size() != static_cast<size_t>(face->num_fixed_sizes))
    
    349 344
       {
    
    ... ... @@ -510,8 +505,8 @@ SFNTTableInfo::getForAll(Engine* engine,
    510 505
                              std::vector<SFNTTableInfo>& infos)
    
    511 506
     {
    
    512 507
       infos.clear();
    
    513
    -  auto size = engine->currentFtSize();
    
    514
    -  if (!size || !FT_IS_SFNT(size->face))
    
    508
    +  auto face = engine->currentFallbackFtFace();
    
    509
    +  if (!face || !FT_IS_SFNT(face))
    
    515 510
         return;
    
    516 511
     
    
    517 512
       auto index = engine->currentFontIndex();
    

  • src/ftinspect/engine/mmgx.cpp
    ... ... @@ -13,13 +13,12 @@ MMGXState
    13 13
     MMGXAxisInfo::get(Engine* engine,
    
    14 14
                       std::vector<MMGXAxisInfo>& infos)
    
    15 15
     {
    
    16
    -  auto size = engine->currentFtSize();
    
    17
    -  if (!size)
    
    16
    +  auto face = engine->currentFallbackFtFace();
    
    17
    +  if (!face)
    
    18 18
       {
    
    19 19
         infos.clear();
    
    20 20
         return MMGXState::NoMMGX;
    
    21 21
       }
    
    22
    -  auto face = size->face;
    
    23 22
     
    
    24 23
       if (!FT_HAS_MULTIPLE_MASTERS(face))
    
    25 24
       {
    

  • src/ftinspect/engine/stringrenderer.cpp
    ... ... @@ -150,6 +150,8 @@ void
    150 150
     StringRenderer::prepareRendering()
    
    151 151
     {
    
    152 152
       engine_->reloadFont();
    
    153
    +  if (!engine_->renderReady())
    
    154
    +    return;
    
    153 155
       engine_->loadPalette();
    
    154 156
       if (kerningDegree_ != KD_None)
    
    155 157
         trackingKerning_ = engine_->currentFontTrackingKerning(kerningDegree_);
    
    ... ... @@ -346,11 +348,13 @@ StringRenderer::render(int width,
    346 348
                            int height,
    
    347 349
                            int offset)
    
    348 350
     {
    
    351
    +  engine_->reloadFont();
    
    352
    +
    
    349 353
       if (usingString_)
    
    350 354
         offset = 0;
    
    351 355
       if (!usingString_ && limitIndex_ <= 0)
    
    352 356
         return 0;
    
    353
    -  if (engine_->currentFontNumberOfGlyphs() <= 0)
    
    357
    +  if (!engine_->fontValid())
    
    354 358
         return 0;
    
    355 359
     
    
    356 360
       // Separated into 3 modes:
    
    ... ... @@ -379,6 +383,8 @@ StringRenderer::render(int width,
    379 383
           // 64.0 is somewhat a magic reference number
    
    380 384
           engine_->setSizeByPoint(64.0);
    
    381 385
           engine_->reloadFont();
    
    386
    +      if (!engine_->renderReady())
    
    387
    +        return -1; // TODO: Handle bitmap-only fonts
    
    382 388
           auto pixelActual = engine_->currentFontMetrics().height >> 6;
    
    383 389
     
    
    384 390
           auto heightPt = height * 64.0 / pixelActual;
    
    ... ... @@ -441,6 +447,8 @@ StringRenderer::render(int width,
    441 447
         // Fill the whole canvas
    
    442 448
     
    
    443 449
         prepareRendering();
    
    450
    +    if (!engine_->renderReady())
    
    451
    +      return 0;
    
    444 452
         auto& metrics = engine_->currentFontMetrics();
    
    445 453
         auto y = 4 + static_cast<int>(metrics.ascender >> 6);
    
    446 454
         auto stepY = static_cast<int>(metrics.height >> 6) + 1;
    
    ... ... @@ -459,6 +467,9 @@ StringRenderer::render(int width,
    459 467
     
    
    460 468
       // Single string
    
    461 469
       prepareRendering();
    
    470
    +  if (!engine_->renderReady())
    
    471
    +    return 0;
    
    472
    +
    
    462 473
       auto& metrics = engine_->currentFontMetrics();
    
    463 474
       auto x = static_cast<int>(width * position_);
    
    464 475
       // Anchor at top-left in vertical mode, at the center in horizontal mode
    

  • src/ftinspect/panels/info.cpp
    ... ... @@ -414,8 +414,8 @@ void
    414 414
     SFNTInfoTab::reloadFont()
    
    415 415
     {
    
    416 416
       engine_->reloadFont();
    
    417
    -  auto size = engine_->currentFtSize();
    
    418
    -  if (!size || !FT_IS_SFNT(size->face))
    
    417
    +  auto face = engine_->currentFallbackFtFace();
    
    418
    +  if (!face || !FT_IS_SFNT(face))
    
    419 419
         setEnabled(false);
    
    420 420
     
    
    421 421
       if (engine_->currentFontSFNTNames() != sfntNamesModel_->storage())
    

  • src/ftinspect/rendering/glyphcontinuous.cpp
    ... ... @@ -252,27 +252,30 @@ GlyphContinuous::paintByRenderer()
    252 252
     void
    
    253 253
     GlyphContinuous::transformGlyphFancy(FT_Glyph glyph)
    
    254 254
     {
    
    255
    +  auto& metrics = engine_->currentFontMetrics();
    
    256
    +  auto emboldeningX = (FT_Pos)(metrics.y_ppem * 64 * boldX_);
    
    257
    +  auto emboldeningY = (FT_Pos)(metrics.y_ppem * 64 * boldY_);
    
    255 258
       // adopted from ftview.c:289
    
    256 259
       if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
    
    257 260
       {
    
    258 261
         auto outline = reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
    
    259 262
         FT_Glyph_Transform(glyph, &shearMatrix_, NULL);
    
    260
    -    if (FT_Outline_EmboldenXY(&outline, emboldeningX_, emboldeningY_))
    
    263
    +    if (FT_Outline_EmboldenXY(&outline, emboldeningX, emboldeningY))
    
    261 264
         {
    
    262 265
           // XXX error handling?
    
    263 266
           return;
    
    264 267
         }
    
    265 268
     
    
    266 269
         if (glyph->advance.x)
    
    267
    -      glyph->advance.x += emboldeningX_;
    
    270
    +      glyph->advance.x += emboldeningX;
    
    268 271
     
    
    269 272
         if (glyph->advance.y)
    
    270
    -      glyph->advance.y += emboldeningY_;
    
    273
    +      glyph->advance.y += emboldeningY;
    
    271 274
       }
    
    272 275
       else if (glyph->format == FT_GLYPH_FORMAT_BITMAP)
    
    273 276
       {
    
    274
    -    auto xstr = emboldeningX_ & ~63;
    
    275
    -    auto ystr = emboldeningY_ & ~63;
    
    277
    +    auto xstr = emboldeningX & ~63;
    
    278
    +    auto ystr = emboldeningY & ~63;
    
    276 279
     
    
    277 280
         auto bitmap = &reinterpret_cast<FT_BitmapGlyph>(glyph)->bitmap;
    
    278 281
         // No shearing support for bitmap
    
    ... ... @@ -326,13 +329,6 @@ void
    326 329
     GlyphContinuous::prePaint()
    
    327 330
     {
    
    328 331
       displayingCount_ = 0;
    
    329
    -  engine_->reloadFont();
    
    330
    -  if (engine_->currentFontNumberOfGlyphs() > 0)
    
    331
    -    metrics_ = engine_->currentFontMetrics();
    
    332
    -  x_ = 0;
    
    333
    -  // See ftview.c:42
    
    334
    -  y_ = ((metrics_.ascender - metrics_.descender + 63) >> 6) + 4;
    
    335
    -  stepY_ = ((metrics_.height + 63) >> 6) + 4;
    
    336 332
     
    
    337 333
       // Used by fancy:
    
    338 334
       // adopted from ftview.c:289
    
    ... ... @@ -355,18 +351,22 @@ GlyphContinuous::prePaint()
    355 351
       shearMatrix_.xy = static_cast<FT_Fixed>(slant_ * (1 << 16));
    
    356 352
       shearMatrix_.yx = 0;
    
    357 353
       shearMatrix_.yy = 1 << 16;
    
    354
    +}
    
    358 355
     
    
    359
    -  emboldeningX_ = (FT_Pos)(metrics_.y_ppem * 64 * boldX_);
    
    360
    -  emboldeningY_ = (FT_Pos)(metrics_.y_ppem * 64 * boldY_);
    
    361 356
     
    
    362
    -  if (mode_ == M_Stroked)
    
    363
    -  {
    
    364
    -    auto radius = static_cast<FT_Fixed>(metrics_.y_ppem * 64 * strokeRadius_);
    
    365
    -    FT_Stroker_Set(stroker_, radius,
    
    366
    -                   FT_STROKER_LINECAP_ROUND,
    
    367
    -                   FT_STROKER_LINEJOIN_ROUND,
    
    368
    -                   0);
    
    369
    -  }
    
    357
    +void
    
    358
    +GlyphContinuous::updateStroke()
    
    359
    +{
    
    360
    +  if (mode_ != M_Stroked || !engine_->renderReady())
    
    361
    +    return;
    
    362
    +
    
    363
    +  auto& metrics = engine_->currentFontMetrics();
    
    364
    +  auto radius = static_cast<FT_Fixed>(metrics.y_ppem * 64 * strokeRadius_);
    
    365
    +  strokeRadiusForSize_ = radius;
    
    366
    +  FT_Stroker_Set(stroker_, radius,
    
    367
    +                 FT_STROKER_LINECAP_ROUND,
    
    368
    +                 FT_STROKER_LINEJOIN_ROUND,
    
    369
    +                 0);
    
    370 370
     }
    
    371 371
     
    
    372 372
     
    
    ... ... @@ -452,6 +452,7 @@ GlyphContinuous::saveSingleGlyphImage(QImage* image,
    452 452
       entry.glyphIndex = gctx.glyphIndex;
    
    453 453
       entry.advance = advance;
    
    454 454
       entry.penPos = penPosPoint;
    
    455
    +  entry.yPpem = engine_->currentFontMetrics().y_ppem;
    
    455 456
     }
    
    456 457
     
    
    457 458
     
    
    ... ... @@ -486,7 +487,7 @@ GlyphContinuous::drawCacheGlyph(QPainter* painter,
    486 487
       // ftview.c:557
    
    487 488
       // Well, metrics is also part of the cache...
    
    488 489
       int width = entry.advance.x ? entry.advance.x >> 16
    
    489
    -                              : metrics_.y_ppem / 2;
    
    490
    +                              : entry.yPpem / 2;
    
    490 491
     
    
    491 492
       if (entry.advance.x == 0 && !stringRenderer_.isWaterfall())
    
    492 493
       {
    

  • src/ftinspect/rendering/glyphcontinuous.hpp
    ... ... @@ -26,6 +26,7 @@ struct GlyphCacheEntry
    26 26
       QPoint penPos = {};
    
    27 27
       int charCode = -1;
    
    28 28
       int glyphIndex = -1;
    
    29
    +  unsigned yPpem = 0;
    
    29 30
     
    
    30 31
       FT_Vector advance = {};
    
    31 32
     
    
    ... ... @@ -123,10 +124,7 @@ private:
    123 124
     
    
    124 125
       bool mouseOperationEnabled_ = true;
    
    125 126
       int displayingCount_ = 0;
    
    126
    -  FT_Size_Metrics metrics_;
    
    127
    -  int x_ = 0, y_ = 0;
    
    128
    -  int stepY_ = 0;
    
    129
    -  FT_Pos emboldeningX_, emboldeningY_;
    
    127
    +  FT_Fixed strokeRadiusForSize_ = 0;
    
    130 128
       FT_Matrix shearMatrix_;
    
    131 129
     
    
    132 130
       FT_Stroker stroker_;
    
    ... ... @@ -152,6 +150,7 @@ private:
    152 150
       void paintCache(QPainter* painter);
    
    153 151
       void fillCache();
    
    154 152
       void prePaint();
    
    153
    +  void updateStroke();
    
    155 154
       void updateRendererText();
    
    156 155
       void preprocessGlyph(FT_Glyph* glyphPtr);
    
    157 156
       void beginSaveLine(FT_Vector pos,
    

  • src/ftinspect/widgets/tripletselector.cpp
    ... ... @@ -436,8 +436,9 @@ TripletSelector::loadTriplet()
    436 436
       }
    
    437 437
     
    
    438 438
       auto number = engine_->loadFont(fontIndex, faceIndex, instanceIndex);
    
    439
    -
    
    440
    -  if (number < 0)
    
    439
    +  
    
    440
    +  // TODO: This may messes up with bitmap-only fonts.
    
    441
    +  if (!engine_->fontValid())
    
    441 442
       {
    
    442 443
         // there might be various reasons why the current
    
    443 444
         // (file, face, instance) triplet is invalid or missing;
    


  • reply via email to

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