483 w += glyphs.effectiveAdvance(i); |
483 w += glyphs.effectiveAdvance(i); |
484 |
484 |
485 return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); |
485 return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); |
486 } |
486 } |
487 |
487 |
|
488 #ifndef Q_WS_WINCE |
|
489 bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const |
|
490 { |
|
491 Q_ASSERT(metrics != 0); |
|
492 |
|
493 HDC hdc = shared_dc(); |
|
494 |
|
495 GLYPHMETRICS gm; |
|
496 DWORD res = 0; |
|
497 MAT2 mat; |
|
498 mat.eM11.value = mat.eM22.value = 1; |
|
499 mat.eM11.fract = mat.eM22.fract = 0; |
|
500 mat.eM21.value = mat.eM12.value = 0; |
|
501 mat.eM21.fract = mat.eM12.fract = 0; |
|
502 |
|
503 if (t.type() > QTransform::TxTranslate) { |
|
504 // We need to set the transform using the HDC's world |
|
505 // matrix rather than using the MAT2 above, because the |
|
506 // results provided when transforming via MAT2 does not |
|
507 // match the glyphs that are drawn using a WorldTransform |
|
508 XFORM xform; |
|
509 xform.eM11 = t.m11(); |
|
510 xform.eM12 = t.m12(); |
|
511 xform.eM21 = t.m21(); |
|
512 xform.eM22 = t.m22(); |
|
513 xform.eDx = 0; |
|
514 xform.eDy = 0; |
|
515 SetGraphicsMode(hdc, GM_ADVANCED); |
|
516 SetWorldTransform(hdc, &xform); |
|
517 } |
|
518 |
|
519 uint format = GGO_METRICS; |
|
520 if (ttf) |
|
521 format |= GGO_GLYPH_INDEX; |
|
522 res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat); |
|
523 |
|
524 if (t.type() > QTransform::TxTranslate) { |
|
525 XFORM xform; |
|
526 xform.eM11 = xform.eM22 = 1; |
|
527 xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; |
|
528 SetWorldTransform(hdc, &xform); |
|
529 SetGraphicsMode(hdc, GM_COMPATIBLE); |
|
530 } |
|
531 |
|
532 if (res != GDI_ERROR) { |
|
533 *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, |
|
534 (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); |
|
535 return true; |
|
536 } else { |
|
537 return false; |
|
538 } |
|
539 } |
|
540 #endif |
488 |
541 |
489 glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) |
542 glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) |
490 { |
543 { |
491 #ifndef Q_WS_WINCE |
544 #ifndef Q_WS_WINCE |
492 GLYPHMETRICS gm; |
|
493 |
|
494 HDC hdc = shared_dc(); |
545 HDC hdc = shared_dc(); |
495 SelectObject(hdc, hfont); |
546 SelectObject(hdc, hfont); |
496 if (!ttf) { |
547 |
|
548 glyph_metrics_t glyphMetrics; |
|
549 bool success = getOutlineMetrics(glyph, t, &glyphMetrics); |
|
550 |
|
551 if (!ttf && !success) { |
|
552 // Bitmap fonts |
497 wchar_t ch = glyph; |
553 wchar_t ch = glyph; |
498 ABCFLOAT abc; |
554 ABCFLOAT abc; |
499 GetCharABCWidthsFloat(hdc, ch, ch, &abc); |
555 GetCharABCWidthsFloat(hdc, ch, ch, &abc); |
500 int width = qRound(abc.abcfB); |
556 int width = qRound(abc.abcfB); |
501 |
557 |
502 return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); |
558 return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); |
503 } else { |
559 } |
504 DWORD res = 0; |
560 |
505 MAT2 mat; |
561 return glyphMetrics; |
506 mat.eM11.value = mat.eM22.value = 1; |
|
507 mat.eM11.fract = mat.eM22.fract = 0; |
|
508 mat.eM21.value = mat.eM12.value = 0; |
|
509 mat.eM21.fract = mat.eM12.fract = 0; |
|
510 |
|
511 if (t.type() > QTransform::TxTranslate) { |
|
512 // We need to set the transform using the HDC's world |
|
513 // matrix rather than using the MAT2 above, because the |
|
514 // results provided when transforming via MAT2 does not |
|
515 // match the glyphs that are drawn using a WorldTransform |
|
516 XFORM xform; |
|
517 xform.eM11 = t.m11(); |
|
518 xform.eM12 = t.m12(); |
|
519 xform.eM21 = t.m21(); |
|
520 xform.eM22 = t.m22(); |
|
521 xform.eDx = 0; |
|
522 xform.eDy = 0; |
|
523 SetGraphicsMode(hdc, GM_ADVANCED); |
|
524 SetWorldTransform(hdc, &xform); |
|
525 } |
|
526 |
|
527 res = GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, 0, &mat); |
|
528 |
|
529 if (t.type() > QTransform::TxTranslate) { |
|
530 XFORM xform; |
|
531 xform.eM11 = xform.eM22 = 1; |
|
532 xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; |
|
533 SetWorldTransform(hdc, &xform); |
|
534 SetGraphicsMode(hdc, GM_COMPATIBLE); |
|
535 } |
|
536 |
|
537 if (res != GDI_ERROR) { |
|
538 return glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, |
|
539 (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); |
|
540 } |
|
541 } |
|
542 return glyph_metrics_t(); |
|
543 #else |
562 #else |
544 HDC hdc = shared_dc(); |
563 HDC hdc = shared_dc(); |
545 HGDIOBJ oldFont = SelectObject(hdc, hfont); |
564 HGDIOBJ oldFont = SelectObject(hdc, hfont); |
546 |
565 |
547 ABC abc; |
566 ABC abc; |
983 HGDIOBJ oldfont = SelectObject(hdc, hf); |
1004 HGDIOBJ oldfont = SelectObject(hdc, hf); |
984 OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); |
1005 OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); |
985 Properties p; |
1006 Properties p; |
986 p.emSquare = unitsPerEm; |
1007 p.emSquare = unitsPerEm; |
987 p.italicAngle = otm->otmItalicAngle; |
1008 p.italicAngle = otm->otmItalicAngle; |
988 p.postscriptName = (char *)otm + (int)otm->otmpFamilyName; |
1009 p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1(); |
989 p.postscriptName += (char *)otm + (int)otm->otmpStyleName; |
1010 p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1(); |
990 #ifndef QT_NO_PRINTER |
1011 #ifndef QT_NO_PRINTER |
991 p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); |
1012 p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); |
992 #endif |
1013 #endif |
993 p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, |
1014 p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, |
994 otm->otmrcFontBox.right - otm->otmrcFontBox.left, |
1015 otm->otmrcFontBox.right - otm->otmrcFontBox.left, |