本文整理汇总了C++中GlyphBuffer::advances方法的典型用法代码示例。如果您正苦于以下问题:C++ GlyphBuffer::advances方法的具体用法?C++ GlyphBuffer::advances怎么用?C++ GlyphBuffer::advances使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GlyphBuffer
的用法示例。
在下文中一共展示了GlyphBuffer::advances方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
const FloatPoint& point, const FloatRect& textRect) const
{
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
const OpenTypeVerticalData* verticalData = font->verticalData();
if (font->platformData().orientation() == Vertical && verticalData) {
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
AffineTransform savedMatrix = gc->getCTM();
gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
const unsigned kMaxBufferLength = 256;
Vector<FloatPoint, kMaxBufferLength> translations;
const FontMetrics& metrics = font->fontMetrics();
SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAscent() - metrics.floatAscent(IdeographicBaseline));
float horizontalOffset = point.x();
unsigned glyphIndex = 0;
while (glyphIndex < numGlyphs) {
unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
translations.resize(chunkLength);
verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chunkLength, reinterpret_cast<float*>(&translations[0]));
x = verticalOriginX;
y = SkFloatToScalar(point.y() + horizontalOffset - point.x());
float currentWidth = 0;
for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) {
pos[i].set(
x + SkIntToScalar(lroundf(translations[i].x())),
y + -SkIntToScalar(-lroundf(currentWidth - translations[i].y())));
currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
}
horizontalOffset += currentWidth;
paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect);
}
gc->setCTM(savedMatrix);
return;
}
if (!glyphBuffer.hasOffsets()) {
SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
SkScalar* xpos = storage.get();
const float* adv = glyphBuffer.advances(from);
for (unsigned i = 0; i < numGlyphs; i++) {
xpos[i] = x;
x += SkFloatToScalar(adv[i]);
}
const Glyph* glyphs = glyphBuffer.glyphs(from);
paintGlyphsHorizontal(gc, font, glyphs, numGlyphs, xpos, SkFloatToScalar(y), textRect);
return;
}
// FIXME: text rendering speed:
// Android has code in their WebCore fork to special case when the
// GlyphBuffer has no advances other than the defaults. In that case the
// text drawing can proceed faster. However, it's unclear when those
// patches may be upstreamed to WebKit so we always use the slower path
// here.
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
const FloatSize* offsets = glyphBuffer.offsets(from);
const float* advances = glyphBuffer.advances(from);
SkScalar advanceSoFar = SkFloatToScalar(0);
for (unsigned i = 0; i < numGlyphs; i++) {
pos[i].set(
x + SkFloatToScalar(offsets[i].width()) + advanceSoFar,
y + SkFloatToScalar(offsets[i].height()));
advanceSoFar += SkFloatToScalar(advances[i]);
}
const Glyph* glyphs = glyphBuffer.glyphs(from);
paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect);
}
示例2: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
switch(fontDescription().fontSmoothing()) {
case Antialiased: {
graphicsContext->setShouldAntialias(true);
shouldUseFontSmoothing = false;
break;
}
case SubpixelAntialiased: {
graphicsContext->setShouldAntialias(true);
shouldUseFontSmoothing = true;
break;
}
case NoSmoothing: {
graphicsContext->setShouldAntialias(false);
shouldUseFontSmoothing = false;
break;
}
case AutoSmoothing: {
// For the AutoSmooth case, don't do anything! Keep the default settings.
break;
}
default:
ASSERT_NOT_REACHED();
}
if (font->platformData().useGDI() && !shouldUseFontSmoothing) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext, shouldUseFontSmoothing);
const FontPlatformData& platformData = font->platformData();
CGContextSetFont(cgContext, platformData.cgFont());
CGAffineTransform matrix = CGAffineTransformIdentity;
matrix.b = -matrix.b;
matrix.d = -matrix.d;
if (platformData.syntheticOblique()) {
static float skew = -tanf(syntheticObliqueAngle * piFloat / 180.0f);
matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
}
CGContextSetTextMatrix(cgContext, matrix);
// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
CGContextSetFontSize(cgContext, platformData.size());
wkSetCGContextFontRenderingStyle(cgContext, font->isSystemFont(), false, font->platformData().useGDI());
FloatSize shadowSize;
float shadowBlur;
Color shadowColor;
graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor);
bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur;
if (hasSimpleShadow) {
// Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
graphicsContext->clearShadow();
Color fillColor = graphicsContext->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
graphicsContext->setFillColor(shadowFillColor, DeviceColorSpace);
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor, DeviceColorSpace);
}
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->syntheticBoldOffset(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
if (hasSimpleShadow)
graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace);
wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
}
示例3: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const
{
// compile-time assert
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t));
if (numGlyphs == 1 && glyphBuffer.glyphAt(from) == 0x3) {
// Webkit likes to draw end text control command for some reason
// Just ignore it
return;
}
SkPaint paint;
if (!setupForText(&paint, gc, font)) {
return;
}
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
SkPoint* pos = storage.get();
SkCanvas* canvas = gc->platformContext()->recordingCanvas();
/* We need an array of [x,y,x,y,x,y,...], but webkit is giving us
point.xy + [width, height, width, height, ...], so we have to convert
*/
if (font->platformData().orientation() == Vertical) {
float yOffset = SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
gc->platformContext()->setTextOffset(FloatSize(0.0f, -yOffset)); // compensate for offset in bounds calculation
y += yOffset;
}
if (EmojiFont::IsAvailable()) {
// set filtering, to make scaled images look nice(r)
paint.setFilterBitmap(true);
SkMatrix rotator;
rotator.reset();
if (font->platformData().orientation() == Vertical) {
canvas->save();
canvas->rotate(-90);
rotator.setRotate(90);
}
int localIndex = 0;
int localCount = 0;
for (int i = 0; i < numGlyphs; i++) {
if (EmojiFont::IsEmojiGlyph(glyphs[i])) {
if (localCount) {
rotator.mapPoints(&pos[localIndex], localCount);
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
}
EmojiFont::Draw(canvas, glyphs[i], x, y, paint);
// reset local index/count track for "real" glyphs
localCount = 0;
localIndex = i + 1;
} else {
pos[i].set(x, y);
localCount += 1;
}
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
// draw the last run of glyphs (if any)
if (localCount) {
rotator.mapPoints(&pos[localIndex], localCount);
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
}
if (font->platformData().orientation() == Vertical)
canvas->restore();
} else {
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
y += SkFloatToScalar(adv[i].height());
x += SkFloatToScalar(adv[i].width());
}
if (font->platformData().orientation() == Vertical) {
canvas->save();
canvas->rotate(-90);
SkMatrix rotator;
rotator.reset();
rotator.setRotate(90);
rotator.mapPoints(pos, numGlyphs);
}
canvas->drawPosText(glyphs,
numGlyphs * sizeof(uint16_t), pos, paint);
//.........这里部分代码省略.........
示例4: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time assert
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
// FIXME: text rendering speed:
// Android has code in their WebCore fork to special case when the
// GlyphBuffer has no advances other than the defaults. In that case the
// text drawing can proceed faster. However, it's unclear when those
// patches may be upstreamed to WebKit so we always use the slower path
// here.
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
SkPoint* pos = storage.get();
SkPoint* vPosBegin = storage2.get();
SkPoint* vPosEnd = storage3.get();
bool isVertical = font->platformData().orientation() == Vertical;
for (int i = 0; i < numGlyphs; i++) {
SkScalar myWidth = SkFloatToScalar(adv[i].width());
pos[i].set(x, y);
if (isVertical) {
vPosBegin[i].set(x + myWidth, y);
vPosEnd[i].set(x + myWidth, y - myWidth);
}
x += myWidth;
y += SkFloatToScalar(adv[i].height());
}
SkCanvas* canvas = gc->platformContext()->canvas();
TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode();
// We draw text up to two times (once for fill, once for stroke).
if (textMode & TextModeFill) {
SkPaint paint;
gc->platformContext()->setupPaintForFilling(&paint);
font->platformData().setupPaint(&paint);
adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
if (isVertical) {
SkPath path;
for (int i = 0; i < numGlyphs; ++i) {
path.reset();
path.moveTo(vPosBegin[i]);
path.lineTo(vPosEnd[i]);
canvas->drawTextOnPath(glyphs + i, 2, path, 0, paint);
}
} else
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
}
if ((textMode & TextModeStroke)
&& gc->platformContext()->getStrokeStyle() != NoStroke
&& gc->platformContext()->getStrokeThickness() > 0) {
SkPaint paint;
gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
font->platformData().setupPaint(&paint);
adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
if (textMode & TextModeFill) {
// If we also filled, we don't want to draw shadows twice.
// See comment in FontChromiumWin.cpp::paintSkiaText() for more details.
// Since we use the looper for shadows, we remove it (if any) now.
paint.setLooper(0);
}
if (isVertical) {
SkPath path;
for (int i = 0; i < numGlyphs; ++i) {
path.reset();
path.moveTo(vPosBegin[i]);
path.lineTo(vPosEnd[i]);
canvas->drawTextOnPath(glyphs + i, 2, path, 0, paint);
}
} else
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
}
}
示例5: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const
{
// compile-time assert
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t));
SkPaint paint;
if (!setupForText(&paint, gc, font)) {
return;
}
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
SkCanvas* canvas = gc->platformContext()->mCanvas;
/* We need an array of [x,y,x,y,x,y,...], but webkit is giving us
point.xy + [width, height, width, height, ...], so we have to convert
*/
if (EmojiFont::IsAvailable()) {
// set filtering, to make scaled images look nice(r)
paint.setFilterBitmap(true);
int localIndex = 0;
int localCount = 0;
for (int i = 0; i < numGlyphs; i++) {
if (EmojiFont::IsEmojiGlyph(glyphs[i])) {
if (localCount)
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
EmojiFont::Draw(canvas, glyphs[i], x, y, paint);
// reset local index/count track for "real" glyphs
localCount = 0;
localIndex = i + 1;
} else {
pos[i].set(x, y);
localCount += 1;
}
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
// draw the last run of glyphs (if any)
if (localCount)
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
} else {
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
}
}
示例6: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
if (font->platformData().useGDI()) {
static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs();
if (!canUsePlatformNativeGlyphs || !shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
}
uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext, shouldUseFontSmoothing);
const FontPlatformData& platformData = font->platformData();
CGContextSetFont(cgContext, platformData.cgFont());
CGAffineTransform matrix = CGAffineTransformIdentity;
matrix.b = -matrix.b;
matrix.d = -matrix.d;
if (platformData.syntheticOblique()) {
static float skew = -tanf(syntheticObliqueAngle * piFloat / 180.0f);
matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
}
CGContextSetTextMatrix(cgContext, matrix);
// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
CGContextSetFontSize(cgContext, platformData.size());
wkSetCGContextFontRenderingStyle(cgContext, font->isSystemFont(), false, font->platformData().useGDI());
IntSize shadowSize;
int shadowBlur;
Color shadowColor;
graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor);
bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur;
if (hasSimpleShadow) {
// Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
graphicsContext->clearShadow();
Color fillColor = graphicsContext->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
graphicsContext->setFillColor(shadowFillColor);
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->m_syntheticBoldOffset) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->m_syntheticBoldOffset, point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor);
}
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->m_syntheticBoldOffset) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->m_syntheticBoldOffset, point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
if (hasSimpleShadow)
graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor);
wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
}
示例7: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time assert
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
// FIXME: text rendering speed:
// Android has code in their WebCore fork to special case when the
// GlyphBuffer has no advances other than the defaults. In that case the
// text drawing can proceed faster. However, it's unclear when those
// patches may be upstreamed to WebKit so we always use the slower path
// here.
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
gc->platformContext()->prepareForSoftwareDraw();
SkCanvas* canvas = gc->platformContext()->canvas();
int textMode = gc->platformContext()->getTextDrawingMode();
// We draw text up to two times (once for fill, once for stroke).
if (textMode & cTextFill) {
SkPaint paint;
gc->platformContext()->setupPaintForFilling(&paint);
font->platformData().setupPaint(&paint);
adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->fillColor().rgb());
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
}
if ((textMode & cTextStroke)
&& gc->platformContext()->getStrokeStyle() != NoStroke
&& gc->platformContext()->getStrokeThickness() > 0) {
SkPaint paint;
gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
font->platformData().setupPaint(&paint);
adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->strokeColor().rgb());
if (textMode & cTextFill) {
// If we also filled, we don't want to draw shadows twice.
// See comment in FontChromiumWin.cpp::paintSkiaText() for more details.
paint.setLooper(0)->safeUnref();
}
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
}
}
示例8: drawTextWithSpacing
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();
}