203 if (!fontRuns.
atEnd()) {
209 SkUniqueCFRef<CFStringRef> textString(
210 CFStringCreateWithBytes(kCFAllocatorDefault, (
const uint8_t*)utf8, utf8Bytes,
211 kCFStringEncodingUTF8,
false));
213 UTF16ToUTF8IndicesMap utf8IndicesMap;
214 if (!utf8IndicesMap.setUTF8(utf8, utf8Bytes)) {
220 SkUniqueCFRef<CFMutableDictionaryRef> attr(
221 CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
222 &kCFTypeDictionaryKeyCallBacks,
223 &kCFTypeDictionaryValueCallBacks));
224 CFDictionaryAddValue(attr.get(), kCTFontAttributeName, ctfont.get());
231 SkUniqueCFRef<CFAttributedStringRef> attrString(
232 CFAttributedStringCreate(kCFAllocatorDefault, textString.get(), attr.get()));
234 SkUniqueCFRef<CTTypesetterRef> typesetter(
235 CTTypesetterCreateWithAttributedString(attrString.get()));
239 std::vector<SkFont> fontStorage;
240 std::vector<SkShaper::RunHandler::RunInfo> infos;
243 while (SkUniqueCFRef<CTLineRef> line = iter.
nextLine()) {
244 CFArrayRef run_array = CTLineGetGlyphRuns(line.get());
245 CFIndex runCount = CFArrayGetCount(run_array);
251 fontStorage.reserve(runCount);
253 for (CFIndex j = 0; j < runCount; ++j) {
254 CTRunRef
run = (CTRunRef)CFArrayGetValueAtIndex(run_array, j);
255 CFIndex runGlyphs = CTRunGetGlyphCount(
run);
257 SkASSERT(
sizeof(CGGlyph) ==
sizeof(uint16_t));
260 CTRunGetAdvances(
run, {0, runGlyphs}, advances.
data());
262 for (CFIndex k = 0; k < runGlyphs; ++k) {
263 adv += advances[k].width;
266 CFRange cfRange = CTRunGetStringRange(
run);
267 auto range = utf8IndicesMap.mapRange(cfRange.location, cfRange.length);
275 {range.first, range.second},
277 handler->
runInfo(infos.back());
283 for (CFIndex j = 0; j < runCount; ++j) {
284 const auto&
info = infos[j];
287 CTRunRef
run = (CTRunRef)CFArrayGetValueAtIndex(run_array, j);
288 CFIndex runGlyphs =
info.glyphCount;
291 CTRunGetGlyphs(
run, {0, runGlyphs},
buffer.glyphs);
294 CTRunGetPositions(
run, {0, runGlyphs}, positions.data());
297 indices.
reset(runGlyphs);
298 CTRunGetStringIndices(
run, {0, runGlyphs}, indices.
data());
301 for (CFIndex k = 0; k < runGlyphs; ++k) {
303 buffer.point.fX + SkScalarFromCGFloat(positions[k].
x) - lineAdvance,
307 buffer.offsets[k] = {0, 0};
310 buffer.clusters[k] = utf8IndicesMap.mapIndex(indices[k]);
314 lineAdvance +=
info.fAdvance.fX;
static void dict_add_double(CFMutableDictionaryRef d, const void *name, double value)
static SkUniqueCFRef< CTFontRef > create_ctfont_from_font(const SkFont &font)
const CFStringRef kCTTracking_AttributeName
static SkFont run_to_font(CTRunRef run, const SkFont &orig)
void shape(const char *utf8, size_t utf8Bytes, const SkFont &srcFont, bool leftToRight, SkScalar width, RunHandler *) const override
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static const uint8_t buffer[]