void quartz_draw_layout(void *layout, CGContextRef context, CGPoint position) { CGContextSetTextPosition(context, position.x, position.y); CFArrayRef runs = CTLineGetGlyphRuns((CTLineRef)layout); CFIndex run_count = CFArrayGetCount(runs); CFIndex run_index; for (run_index = 0; run_index < run_count; ++run_index) { CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, run_index); CTFontRef run_font = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName); CGFontRef glyph_font = CTFontCopyGraphicsFont(run_font, NULL); CFIndex glyph_count = CTRunGetGlyphCount(run); CGGlyph glyphs[glyph_count]; CGPoint positions[glyph_count]; CFRange everything = CFRangeMake(0, 0); CTRunGetGlyphs(run, everything, glyphs); CTRunGetPositions(run, everything, positions); CGContextSetFont(context, glyph_font); CGContextSetFontSize(context, CTFontGetSize(run_font)); CGContextShowGlyphsAtPositions(context, glyphs, positions, glyph_count); CGFontRelease(glyph_font); } }
static CGFontRef typefaceToCGFont(const SkTypeface* face) { if (NULL == face) { return 0; } CTFontRef ct = SkTypeface_GetCTFontRef(face); return CTFontCopyGraphicsFont(ct, NULL); }
CGFontRef FontPlatformData::cgFont() const { CGFontRef cgFont = 0; #ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT cgFont = CTFontCopyGraphicsFont((CTFontRef)m_font->font()->OSXGetCTFont(), 0); #else ATSFontRef fontRef; fontRef = FMGetATSFontRefFromFont(m_atsuFontID); if (fontRef) cgFont = CGFontCreateWithPlatformFont((void*)&fontRef); #endif return cgFont; }
static cairo_font_face_t * pango_cairo_core_text_font_create_font_face (PangoCairoFont *font) { PangoCoreTextFont *ctfont = (PangoCoreTextFont *) (font); CTFontRef font_id; CGFontRef cgfont; cairo_font_face_t *cairo_face; font_id = pango_core_text_font_get_ctfont (ctfont); cgfont = CTFontCopyGraphicsFont (font_id, NULL); cairo_face = cairo_quartz_font_face_create_for_cgfont (cgfont); CFRelease (cgfont); return cairo_face; }
bool sdl_osd_interface::font_get_bitmap(osd_font font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) { UniChar uni_char; CGGlyph glyph; CTFontRef ct_font = (CTFontRef)font; const CFIndex count = 1; CGRect bounding_rect, success_rect; CGContextRef context_ref; if( chnum == ' ' ) { uni_char = 'n'; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); uni_char = chnum; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); } else { uni_char = chnum; CTFontGetGlyphsForCharacters( ct_font, &uni_char, &glyph, count ); success_rect = CTFontGetBoundingRectsForGlyphs( ct_font, kCTFontDefaultOrientation, &glyph, &bounding_rect, count ); } if( CGRectEqualToRect( success_rect, CGRectNull ) == false ) { size_t bitmap_width; size_t bitmap_height; bitmap_width = ceilf(bounding_rect.size.width * EXTRA_WIDTH); bitmap_width = bitmap_width == 0 ? 1 : bitmap_width; bitmap_height = ceilf( (CTFontGetAscent(ct_font) + CTFontGetDescent(ct_font) + CTFontGetLeading(ct_font)) * EXTRA_HEIGHT); xoffs = yoffs = 0; width = bitmap_width; size_t bits_per_component; CGColorSpaceRef color_space; CGBitmapInfo bitmap_info = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst; color_space = CGColorSpaceCreateDeviceRGB(); bits_per_component = 8; bitmap.allocate(bitmap_width, bitmap_height); context_ref = CGBitmapContextCreate( bitmap.raw_pixptr(0), bitmap_width, bitmap_height, bits_per_component, bitmap.rowpixels()*4, color_space, bitmap_info ); if( context_ref != NULL ) { CGFontRef font_ref; font_ref = CTFontCopyGraphicsFont( ct_font, NULL ); CGContextSetTextPosition(context_ref, -bounding_rect.origin.x*EXTRA_WIDTH, CTFontGetDescent(ct_font)+CTFontGetLeading(ct_font) ); CGContextSetRGBFillColor(context_ref, 1.0, 1.0, 1.0, 1.0); CGContextSetFont( context_ref, font_ref ); CGContextSetFontSize( context_ref, POINT_SIZE ); CGContextShowGlyphs( context_ref, &glyph, count ); CGFontRelease( font_ref ); CGContextRelease( context_ref ); } CGColorSpaceRelease( color_space ); } return bitmap.valid(); }
void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) { graphicsContext->save(); wxGCDC* dc = static_cast<wxGCDC*>(graphicsContext->platformContext()); wxFont* wxfont = font->getWxFont(); graphicsContext->setFillColor(graphicsContext->fillColor(), DeviceColorSpace); CGContextRef cgContext = static_cast<CGContextRef>(dc->GetGraphicsContext()->GetNativeContext()); CGFontRef cgFont; #ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT cgFont = CTFontCopyGraphicsFont((CTFontRef)wxfont->OSXGetCTFont(), NULL); #else ATSFontRef fontRef; fontRef = FMGetATSFontRefFromFont(wxfont->MacGetATSUFontID()); if (fontRef) cgFont = CGFontCreateWithPlatformFont((void*)&fontRef); #endif CGContextSetFont(cgContext, cgFont); CGContextSetFontSize(cgContext, wxfont->GetPointSize()); CGFloat red, green, blue, alpha; graphicsContext->fillColor().getRGBA(red, green, blue, alpha); CGContextSetRGBFillColor(cgContext, red, green, blue, alpha); CGAffineTransform matrix = CGAffineTransformIdentity; matrix.b = -matrix.b; matrix.d = -matrix.d; CGContextSetTextMatrix(cgContext, matrix); CGContextSetTextPosition(cgContext, point.x(), point.y()); const FloatSize* advanceSizes = static_cast<const FloatSize*>(glyphBuffer.advances(from)); int size = glyphBuffer.size() - from; CGSize sizes[size]; CGGlyph glyphs[numGlyphs]; // if the function doesn't exist, we're probably on tiger and need to grab the // function under its old name, CGFontGetGlyphsForUnicodes if (!CGFontGetGlyphsForUnichars) CGFontGetGlyphsForUnichars = (CGFontGetGlyphsForUnicharsPtr)dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes"); // Let's make sure we got the function under one name or another! ASSERT(CGFontGetGlyphsForUnichars); CGFontGetGlyphsForUnichars(cgFont, glyphBuffer.glyphs(from), glyphs, numGlyphs); for (int i = 0; i < size; i++) { FloatSize fsize = advanceSizes[i]; sizes[i] = CGSizeMake(fsize.width(), fsize.height()); } CGContextShowGlyphsWithAdvances(cgContext, glyphs, sizes, numGlyphs); if (cgFont) CGFontRelease(cgFont); graphicsContext->restore(); }
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { bool haveGlyphs = false; Vector<CGGlyph, 512> glyphs(bufferLength); if (!shouldUseCoreText(buffer, bufferLength, fontData)) { // We pass in either 256 or 512 UTF-16 characters: 256 for U+FFFF and less, 512 (double character surrogates) // for U+10000 and above. It is indeed possible to get back 512 glyphs back from the API, so the glyph buffer // we pass in must be 512. If we get back more than 256 glyphs though we'll ignore all the ones after 256, // this should not happen as the only time we pass in 512 characters is when they are surrogates. CGFontGetGlyphsForUnichars(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); for (unsigned i = 0; i < length; ++i) { if (!glyphs[i]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i], fontData); haveGlyphs = true; } } } else if (!fontData->platformData().isCompositeFontReference() && ((fontData->platformData().widthVariant() == RegularWidth) ? wkGetVerticalGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength) : CTFontGetGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength))) { // When buffer consists of surrogate pairs, wkGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters // place the glyphs at indices corresponding to the first character of each pair. unsigned glyphStep = bufferLength / length; for (unsigned i = 0; i < length; ++i) { if (!glyphs[i * glyphStep]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i * glyphStep], fontData); haveGlyphs = true; } } } else { // We ask CoreText for possible vertical variant glyphs RetainPtr<CFStringRef> string = adoptCF(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); RetainPtr<CFAttributedStringRef> attributedString = adoptCF(CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0, fontData->hasVerticalGlyphs() ? Vertical : Horizontal))); RetainPtr<CTLineRef> line = adoptCF(CTLineCreateWithAttributedString(attributedString.get())); CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); CFIndex runCount = CFArrayGetCount(runArray); // Initialize glyph entries for (unsigned index = 0; index < length; ++index) setGlyphDataForIndex(offset + index, 0, 0); Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may // be non-CFEqual to fontData->platformData().cgFont(). RetainPtr<CGFontRef> cgFont = adoptCF(CTFontCopyGraphicsFont(fontData->platformData().ctFont(), 0)); for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); CFDictionaryRef attributes = CTRunGetAttributes(ctRun); CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont = adoptCF(CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. bool gotBaseFont = CFEqual(cgFont.get(), runCGFont.get()); if (gotBaseFont || fontData->platformData().isCompositeFontReference()) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); if (!glyphs) { glyphVector.resize(glyphCount); CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); glyphs = glyphVector.data(); } const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); if (!stringIndices) { indexVector.resize(glyphCount); CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); stringIndices = indexVector.data(); } if (gotBaseFont) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], fontData); haveGlyphs = true; } } #if !PLATFORM(IOS) } else { const SimpleFontData* runSimple = fontData->getCompositeFontReferenceFontData((NSFont *)runFont); if (runSimple) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], runSimple); haveGlyphs = true; } } } #endif // !PLATFORM(IOS) } } } } return haveGlyphs; }
CGFontRef FontPlatformData::cgFont() const { return CTFontCopyGraphicsFont(ctFont(), 0); }
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { bool haveGlyphs = false; #ifndef BUILDING_ON_TIGER if (fontData->orientation() == Horizontal || fontData->isBrokenIdeographFont()) { Vector<CGGlyph, 512> glyphs(bufferLength); wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); for (unsigned i = 0; i < length; ++i) { if (!glyphs[i]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i], fontData); haveGlyphs = true; } } } else { // We ask CoreText for possible vertical variant glyphs RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0))); RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get())); CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); CFIndex runCount = CFArrayGetCount(runArray); // Initialize glyph entries for (unsigned index = 0; index < length; ++index) setGlyphDataForIndex(offset + index, 0, 0); Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); CFDictionaryRef attributes = CTRunGetAttributes(ctRun); CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. if (CFEqual(fontData->platformData().cgFont(), runCGFont.get())) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); if (!glyphs) { glyphVector.resize(glyphCount); CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); glyphs = glyphVector.data(); } const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); if (!stringIndices) { indexVector.resize(glyphCount); CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); stringIndices = indexVector.data(); } for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], fontData); haveGlyphs = true; } } } } } #else // Use an array of long so we get good enough alignment. long glyphVector[(GLYPH_VECTOR_SIZE + sizeof(long) - 1) / sizeof(long)]; OSStatus status = wkInitializeGlyphVector(GlyphPage::size, &glyphVector); if (status != noErr) // This should never happen, perhaps indicates a bad font! If it does the // font substitution code will find an alternate font. return false; wkConvertCharToGlyphs(fontData->m_styleGroup, buffer, bufferLength, &glyphVector); unsigned numGlyphs = wkGetGlyphVectorNumGlyphs(&glyphVector); if (numGlyphs != length) { // This should never happen, perhaps indicates a bad font? // If it does happen, the font substitution code will find an alternate font. wkClearGlyphVector(&glyphVector); return false; } ATSLayoutRecord* glyphRecord = (ATSLayoutRecord*)wkGetGlyphVectorFirstRecord(glyphVector); for (unsigned i = 0; i < length; i++) { Glyph glyph = glyphRecord->glyphID; if (!glyph) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyph, fontData); haveGlyphs = true; } glyphRecord = (ATSLayoutRecord *)((char *)glyphRecord + wkGetGlyphVectorRecordSize(glyphVector)); } wkClearGlyphVector(&glyphVector); #endif return haveGlyphs; }
bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { bool haveGlyphs = false; if (!shouldUseCoreText(buffer, bufferLength, fontData)) { Vector<CGGlyph, 512> glyphs(bufferLength); CMFontGetGlyphsForUnichars(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); // wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); for (unsigned i = 0; i < length; ++i) { if (!glyphs[i]) setGlyphDataForIndex(offset + i, 0, 0); else { setGlyphDataForIndex(offset + i, glyphs[i], fontData); haveGlyphs = true; } } } else { // We ask CoreText for possible vertical variant glyphs RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0, fontData->hasVerticalGlyphs() ? Vertical : Horizontal))); RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get())); CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); CFIndex runCount = CFArrayGetCount(runArray); // Initialize glyph entries for (unsigned index = 0; index < length; ++index) setGlyphDataForIndex(offset + index, 0, 0); Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may // be non-CFEqual to fontData->platformData().cgFont(). RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(fontData->platformData().ctFont(), 0)); for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); CFDictionaryRef attributes = CTRunGetAttributes(ctRun); CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. if (CFEqual(cgFont.get(), runCGFont.get())) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); if (!glyphs) { glyphVector.resize(glyphCount); CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); glyphs = glyphVector.data(); } const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); if (!stringIndices) { indexVector.resize(glyphCount); CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); stringIndices = indexVector.data(); } for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], fontData); haveGlyphs = true; } } } } } return haveGlyphs; }
bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const { bool haveGlyphs = false; Vector<CGGlyph, 512> glyphs(bufferLength); if (!shouldUseCoreText(buffer, bufferLength, this)) { CGFontGetGlyphsForUnichars(platformData().cgFont(), buffer, glyphs.data(), bufferLength); for (unsigned i = 0; i < length; ++i) { if (glyphs[i]) { pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this); haveGlyphs = true; } } } else if (!platformData().isCompositeFontReference() && platformData().widthVariant() != RegularWidth && CTFontGetGlyphsForCharacters(platformData().ctFont(), buffer, glyphs.data(), bufferLength)) { // When buffer consists of surrogate pairs, CTFontGetGlyphsForCharacters // places the glyphs at indices corresponding to the first character of each pair. unsigned glyphStep = bufferLength / length; for (unsigned i = 0; i < length; ++i) { if (glyphs[i * glyphStep]) { pageToFill->setGlyphDataForIndex(offset + i, glyphs[i * glyphStep], this); haveGlyphs = true; } } } else { // We ask CoreText for possible vertical variant glyphs RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), getCFStringAttributes(0, hasVerticalGlyphs() ? Vertical : Horizontal))); RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get())); CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); CFIndex runCount = CFArrayGetCount(runArray); Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may // be non-CFEqual to platformData().cgFont(). RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(platformData().ctFont(), 0)); for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., platformData().ctFont(). CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); CFDictionaryRef attributes = CTRunGetAttributes(ctRun); CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. bool gotBaseFont = CFEqual(cgFont.get(), runCGFont.get()); if (gotBaseFont || platformData().isCompositeFontReference()) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); if (!glyphs) { glyphVector.resize(glyphCount); CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); glyphs = glyphVector.data(); } const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); if (!stringIndices) { indexVector.resize(glyphCount); CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); stringIndices = indexVector.data(); } if (gotBaseFont) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { pageToFill->setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], this); haveGlyphs = true; } } } else { const SimpleFontData* runSimple = getCompositeFontReferenceFontData((NSFont *)runFont); if (runSimple) { for (CFIndex i = 0; i < glyphCount; ++i) { if (stringIndices[i] >= static_cast<CFIndex>(length)) { done = true; break; } if (glyphs[i]) { pageToFill->setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], runSimple); haveGlyphs = true; } } } } } } } return haveGlyphs; }