@@ -1224,6 +1224,116 @@ namespace winrt::Telegram::Native::implementation
1224
1224
return { metrics.left , metrics.top , metrics.width , metrics.height };
1225
1225
}
1226
1226
1227
+ MaxLinesMetrics PlaceholderImageHelper::MaxLines (hstring text, int32_t offset, int32_t length, IVector<TextEntity> entities, double fontSize, double width, bool rtl, int32_t maxLines)
1228
+ {
1229
+ std::lock_guard const guard (m_criticalSection);
1230
+ HRESULT result;
1231
+
1232
+ // ReturnIfFailed(result, CreateTextFormat(fontSize));
1233
+ // ReturnIfFailed(result, m_appleFormat->SetReadingDirection(rtl ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : DWRITE_READING_DIRECTION_LEFT_TO_RIGHT));
1234
+
1235
+ winrt::com_ptr<IDWriteTextFormat> textFormat;
1236
+ ReturnDefaultIfFailed (result, m_dwriteFactory->CreateTextFormat (
1237
+ L" Segoe UI Emoji" , // font family name
1238
+ m_fontCollection.get (), // system font collection
1239
+ DWRITE_FONT_WEIGHT_NORMAL, // font weight
1240
+ DWRITE_FONT_STYLE_NORMAL, // font style
1241
+ DWRITE_FONT_STRETCH_NORMAL, // default font stretch
1242
+ fontSize, // font size
1243
+ L" " , // locale name
1244
+ textFormat.put ()
1245
+ ));
1246
+ ReturnDefaultIfFailed (result, textFormat->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_LEADING));
1247
+ ReturnDefaultIfFailed (result, textFormat->SetParagraphAlignment (DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
1248
+ ReturnDefaultIfFailed (result, textFormat->SetReadingDirection (rtl ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : DWRITE_READING_DIRECTION_LEFT_TO_RIGHT));
1249
+
1250
+ winrt::com_ptr<IDWriteTextLayout> textLayout;
1251
+ ReturnDefaultIfFailed (result, m_dwriteFactory->CreateTextLayout (
1252
+ text.data (), // The string to be laid out and formatted.
1253
+ text.size (), // The length of the string.
1254
+ textFormat.get (), // The text format to apply to the string (contains font information, etc).
1255
+ width, // The width of the layout box.
1256
+ INFINITY, // The height of the layout box.
1257
+ textLayout.put () // The IDWriteTextLayout interface pointer.
1258
+ ));
1259
+
1260
+ for (const TextEntity& entity : entities)
1261
+ {
1262
+ UINT32 startPosition = entity.Offset ();
1263
+ UINT32 length = entity.Length ();
1264
+ auto name = winrt::get_class_name (entity.Type ());
1265
+
1266
+ if (name == winrt::name_of<TextEntityTypeBold>())
1267
+ {
1268
+ ReturnDefaultIfFailed (result, textLayout->SetFontWeight (DWRITE_FONT_WEIGHT_SEMI_BOLD, { startPosition, length }));
1269
+ }
1270
+ else if (name == winrt::name_of<TextEntityTypeItalic>())
1271
+ {
1272
+ ReturnDefaultIfFailed (result, textLayout->SetFontStyle (DWRITE_FONT_STYLE_ITALIC, { startPosition, length }));
1273
+ }
1274
+ else if (name == winrt::name_of<TextEntityTypeStrikethrough>())
1275
+ {
1276
+ ReturnDefaultIfFailed (result, textLayout->SetStrikethrough (TRUE , { startPosition, length }));
1277
+ }
1278
+ else if (name == winrt::name_of<TextEntityTypeUnderline>())
1279
+ {
1280
+ ReturnDefaultIfFailed (result, textLayout->SetUnderline (TRUE , { startPosition, length }));
1281
+ }
1282
+ // else if (name == winrt::name_of<TextEntityTypeCustomEmoji>())
1283
+ // {
1284
+ // textLayout->SetInlineObject(m_customEmoji.get(), { startPosition, length });
1285
+ // }
1286
+ else if (name == winrt::name_of<TextEntityTypeCode>() || name == winrt::name_of<TextEntityTypePre>() || name == winrt::name_of<TextEntityTypePreCode>())
1287
+ {
1288
+ ReturnDefaultIfFailed (result, textLayout->SetFontCollection (m_systemCollection.get (), { startPosition, length }));
1289
+ ReturnDefaultIfFailed (result, textLayout->SetFontFamilyName (L" Consolas" , { startPosition, length }));
1290
+ }
1291
+ }
1292
+
1293
+ DWRITE_TEXT_METRICS metrics;
1294
+ ReturnDefaultIfFailed (result, textLayout->GetMetrics (&metrics));
1295
+
1296
+ if (maxLines == 0 )
1297
+ {
1298
+ return { metrics.left , metrics.top , metrics.width , metrics.height , metrics.height , length };
1299
+ }
1300
+
1301
+ UINT32 actualLineCount;
1302
+ DWRITE_LINE_METRICS* ranges = new DWRITE_LINE_METRICS[metrics.lineCount ];
1303
+ result = textLayout->GetLineMetrics (ranges, metrics.lineCount , &actualLineCount);
1304
+
1305
+ if (result == E_NOT_SUFFICIENT_BUFFER)
1306
+ {
1307
+ delete[] ranges;
1308
+
1309
+ ranges = new DWRITE_LINE_METRICS[actualLineCount];
1310
+ result = textLayout->GetLineMetrics (ranges, actualLineCount, &actualLineCount);
1311
+ }
1312
+
1313
+ ReturnDefaultIfFailed (result, result);
1314
+
1315
+ float truncateHeight = 0 ;
1316
+ int32_t truncatePosition = 0 ;
1317
+
1318
+ // Calculate position where to truncate
1319
+ for (UINT32 i = 0 ; i < maxLines && i < actualLineCount; ++i)
1320
+ {
1321
+ truncateHeight += ranges[i].height ;
1322
+ truncatePosition += ranges[i].length ;
1323
+ }
1324
+
1325
+ // Remove trailing whitespace from last included line
1326
+ if (maxLines <= actualLineCount)
1327
+ {
1328
+ // truncateHeight += ranges[maxLines - 1].height;
1329
+ truncatePosition -= ranges[maxLines - 1 ].trailingWhitespaceLength ;
1330
+ truncatePosition -= ranges[maxLines - 1 ].newlineLength ;
1331
+ }
1332
+
1333
+ delete[] ranges;
1334
+ return { metrics.left , metrics.top , metrics.width , metrics.height , truncateHeight, truncatePosition };
1335
+ }
1336
+
1227
1337
HRESULT PlaceholderImageHelper::WriteBytes (IVector<byte> hash, IRandomAccessStream randomAccessStream) noexcept
1228
1338
{
1229
1339
HRESULT result;
0 commit comments