347 |
347 |
348 bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, |
348 bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, |
349 int *nglyphs, QTextEngine::ShaperFlags flags) const |
349 int *nglyphs, QTextEngine::ShaperFlags flags) const |
350 { |
350 { |
351 *nglyphs = len; |
351 *nglyphs = len; |
|
352 QCFType<CFStringRef> cfstring; |
|
353 |
352 QVarLengthArray<CGGlyph> cgGlyphs(len); |
354 QVarLengthArray<CGGlyph> cgGlyphs(len); |
353 CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); |
355 CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); |
354 |
356 |
355 for (int i = 0; i < len; ++i) |
357 for (int i = 0; i < len; ++i) { |
356 glyphs->glyphs[i] = cgGlyphs[i]; |
358 if (cgGlyphs[i]) { |
|
359 glyphs->glyphs[i] = cgGlyphs[i]; |
|
360 } else { |
|
361 if (!cfstring) |
|
362 cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), len, kCFAllocatorNull); |
|
363 QCFType<CTFontRef> substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); |
|
364 CGGlyph substituteGlyph = 0; |
|
365 CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); |
|
366 if (substituteGlyph) { |
|
367 const uint fontIndex = (fontIndexForFont(substituteFont) << 24); |
|
368 glyphs->glyphs[i] = substituteGlyph | fontIndex; |
|
369 if (!(flags & QTextEngine::GlyphIndicesOnly)) { |
|
370 CGSize advance; |
|
371 CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); |
|
372 glyphs->advances_x[i] = QFixed::fromReal(advance.width); |
|
373 glyphs->advances_y[i] = QFixed::fromReal(advance.height); |
|
374 } |
|
375 } |
|
376 } |
|
377 } |
357 |
378 |
358 if (flags & QTextEngine::GlyphIndicesOnly) |
379 if (flags & QTextEngine::GlyphIndicesOnly) |
359 return true; |
380 return true; |
360 |
381 |
361 QVarLengthArray<CGSize> advances(len); |
382 QVarLengthArray<CGSize> advances(len); |
362 CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); |
383 CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); |
363 |
384 |
364 for (int i = 0; i < len; ++i) { |
385 for (int i = 0; i < len; ++i) { |
|
386 if (glyphs->glyphs[i] & 0xff000000) |
|
387 continue; |
365 glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); |
388 glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); |
366 glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); |
389 glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); |
367 if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { |
390 } |
|
391 |
|
392 if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { |
|
393 for (int i = 0; i < len; ++i) { |
368 glyphs->advances_x[i] = glyphs->advances_x[i].round(); |
394 glyphs->advances_x[i] = glyphs->advances_x[i].round(); |
369 glyphs->advances_y[i] = glyphs->advances_y[i].round(); |
395 glyphs->advances_y[i] = glyphs->advances_y[i].round(); |
370 } |
396 } |
371 } |
397 } |
372 |
398 |
427 } |
453 } |
428 |
454 |
429 glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) |
455 glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) |
430 { |
456 { |
431 QFixed w; |
457 QFixed w; |
|
458 bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; |
|
459 |
432 for (int i = 0; i < glyphs.numGlyphs; ++i) { |
460 for (int i = 0; i < glyphs.numGlyphs; ++i) { |
433 w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) |
461 w += round ? glyphs.effectiveAdvance(i).round() |
434 ? glyphs.effectiveAdvance(i).round() |
462 : glyphs.effectiveAdvance(i); |
435 : glyphs.effectiveAdvance(i); |
463 } |
436 } |
464 return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); |
437 return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); |
|
438 } |
465 } |
439 glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) |
466 glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) |
440 { |
467 { |
441 glyph_metrics_t ret; |
468 glyph_metrics_t ret; |
442 CGGlyph g = glyph; |
469 CGGlyph g = glyph; |
1452 } |
1479 } |
1453 |
1480 |
1454 glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs) |
1481 glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs) |
1455 { |
1482 { |
1456 QFixed w; |
1483 QFixed w; |
|
1484 bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; |
1457 for (int i = 0; i < glyphs.numGlyphs; ++i) { |
1485 for (int i = 0; i < glyphs.numGlyphs; ++i) { |
1458 w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) |
1486 w += round ? glyphs.effectiveAdvance(i).round() |
1459 ? glyphs.effectiveAdvance(i).round() |
1487 : glyphs.effectiveAdvance(i); |
1460 : glyphs.effectiveAdvance(i); |
1488 } |
1461 } |
1489 return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); |
1462 return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); |
|
1463 } |
1490 } |
1464 |
1491 |
1465 glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph) |
1492 glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph) |
1466 { |
1493 { |
1467 GlyphID atsuGlyph = glyph; |
1494 GlyphID atsuGlyph = glyph; |