< prev index next >

src/java.desktop/windows/native/libawt/windows/awt_Font.cpp

Print this page




 381         throw;
 382     }
 383 
 384     env->DeleteLocalRef(compFont);
 385     return awtFont;
 386 }
 387 
 388 static void strip_tail(wchar_t* text, wchar_t* tail) { // strips tail and any possible whitespace before it from the end of text
 389     if (wcslen(text)<=wcslen(tail)) {
 390         return;
 391     }
 392     wchar_t* p = text+wcslen(text)-wcslen(tail);
 393     if (!wcscmp(p, tail)) {
 394         while(p>text && iswspace(*(p-1)))
 395             p--;
 396         *p = 0;
 397     }
 398 
 399 }
 400 
































 401 static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
 402                              int angle=0, float awScale=1.0f)
 403 {
 404     LOGFONTW logFont;
 405 
 406     logFont.lfWidth = 0;
 407     logFont.lfEscapement = angle;
 408     logFont.lfOrientation = angle;
 409     logFont.lfUnderline = FALSE;
 410     logFont.lfStrikeOut = FALSE;
 411     logFont.lfCharSet = GetNativeCharset(name);
 412     if (angle == 0 && awScale == 1.0f) {
 413         logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
 414     } else {
 415         logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
 416     }
 417     logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
 418     logFont.lfQuality = DEFAULT_QUALITY;
 419     logFont.lfPitchAndFamily = DEFAULT_PITCH;
 420 
 421     // Set style
 422     logFont.lfWeight = (style & java_awt_Font_BOLD) ? FW_BOLD : FW_NORMAL;
 423     logFont.lfItalic = (style & java_awt_Font_ITALIC) != 0;
 424     logFont.lfUnderline = 0;//(style & java_awt_Font_UNDERLINE) != 0;
 425 
 426     // Get point size
 427     logFont.lfHeight = -height;
 428 
 429     // Set font name
 430     WCHAR tmpname[80];
 431     wcscpy(tmpname, name);
 432     WCHAR* delimit = wcschr(tmpname, L',');
 433     if (delimit != NULL)
 434         *delimit = L'\0';  // terminate the string after the font name.
 435     // strip "Bold" and "Italic" from the end of the name
 436     strip_tail(tmpname,L""); //strip possible trailing whitespace
 437     strip_tail(tmpname,L"Italic");
 438     strip_tail(tmpname,L"Bold");
 439     wcscpy(&(logFont.lfFaceName[0]), tmpname);
 440     HFONT hFont = ::CreateFontIndirect(&logFont);
 441     DASSERT(hFont != NULL);
 442     // get a expanded or condensed version if its specified.
 443     if (awScale != 1.0f) {
 444         HDC hDC = ::GetDC(0);
 445         HFONT oldFont = (HFONT)::SelectObject(hDC, hFont);
 446         TEXTMETRIC tm;
 447         DWORD avgWidth;
 448         GetTextMetrics(hDC, &tm);
 449         oldFont = (HFONT)::SelectObject(hDC, oldFont);
 450         if (oldFont != NULL) { // should be the same as hFont
 451             VERIFY(::DeleteObject(oldFont));
 452         }
 453         avgWidth = tm.tmAveCharWidth;
 454         logFont.lfWidth = (LONG)((fabs)(avgWidth*awScale));
 455         hFont = ::CreateFontIndirect(&logFont);
 456         DASSERT(hFont != NULL);
 457         VERIFY(::ReleaseDC(0, hDC));
 458     }
 459 
 460     return hFont;
 461 }
 462 
 463 HFONT AwtFont::CreateHFont(WCHAR* name, int style, int height,
 464                            int angle, float awScale)
 465 {
 466     WCHAR longName[80];
 467     // 80 > (max face name(=30) + strlen("CHINESEBIG5_CHARSET"))
 468     // longName doesn't have to be printable.  So, it is OK not to convert.
 469 
 470     wsprintf(longName, L"%ls-%d-%d", name, style, height);
 471 
 472     HFONT hFont = NULL;
 473 
 474     // only cache & share unrotated, unexpanded/uncondensed fonts


 518     jobject font = env->GetObjectField(fontMetrics, AwtFont::fontID);
 519     AwtFont* awtFont = AwtFont::GetFont(env, font);
 520 
 521     if (!awtFont) {
 522         /* failed to get font */
 523         return;
 524     }
 525 
 526     HDC hDC = ::GetDC(0);
 527     DASSERT(hDC != NULL);
 528 
 529     HGDIOBJ oldFont = ::SelectObject(hDC, awtFont->GetHFont());
 530     TEXTMETRIC metrics;
 531     VERIFY(::GetTextMetrics(hDC, &metrics));
 532 
 533     awtFont->m_ascent = metrics.tmAscent;
 534 
 535     int ascent = metrics.tmAscent;
 536     int descent = metrics.tmDescent;
 537     int leading = metrics.tmExternalLeading;
 538     env->SetIntField(fontMetrics, AwtFont::ascentID, ascent);
 539     env->SetIntField(fontMetrics, AwtFont::descentID, descent);
 540     env->SetIntField(fontMetrics, AwtFont::leadingID, leading);
 541     env->SetIntField(fontMetrics, AwtFont::heightID, metrics.tmAscent +
 542                      metrics.tmDescent + leading);
 543     env->SetIntField(fontMetrics, AwtFont::maxAscentID, ascent);
 544     env->SetIntField(fontMetrics, AwtFont::maxDescentID, descent);

 545 
 546     int maxHeight =  ascent + descent + leading;
 547     env->SetIntField(fontMetrics, AwtFont::maxHeightID, maxHeight);
 548 
 549     int maxAdvance = metrics.tmMaxCharWidth;
 550     env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, maxAdvance);
 551 
 552     awtFont->m_overhang = metrics.tmOverhang;
 553 
 554     jint intWidths[256];
 555     memset(intWidths, 0, 256 * sizeof(int));
 556     VERIFY(::GetCharWidth(hDC, metrics.tmFirstChar,
 557                           min(metrics.tmLastChar, 255),
 558                           (int *)&intWidths[metrics.tmFirstChar]));
 559     env->SetIntArrayRegion(widths, 0, 256, intWidths);
 560     env->SetObjectField(fontMetrics, AwtFont::widthsID, widths);
 561 
 562     // Get font metrics on remaining fonts (if multifont).
 563     for (int j = 1; j < awtFont->GetHFontNum(); j++) {
 564         ::SelectObject(hDC, awtFont->GetHFont(j));
 565         VERIFY(::GetTextMetrics(hDC, &metrics));
 566         env->SetIntField(fontMetrics, AwtFont::maxAscentID,
 567                          ascent = max(ascent, metrics.tmAscent));
 568         env->SetIntField(fontMetrics, AwtFont::maxDescentID,
 569                          descent = max(descent, metrics.tmDescent));
 570         env->SetIntField(fontMetrics, AwtFont::maxHeightID,


 801 /*
 802  * Class:     sun_awt_windows_WFontMetrics
 803  * Method:    stringWidth
 804  * Signature: (Ljava/lang/String;)I
 805  */
 806 JNIEXPORT jint JNICALL
 807 Java_sun_awt_windows_WFontMetrics_stringWidth(JNIEnv *env, jobject self,
 808                                               jstring str)
 809 {
 810     TRY;
 811 
 812     if (str == NULL) {
 813         JNU_ThrowNullPointerException(env, "str argument");
 814         return NULL;
 815     }
 816     HDC hDC = ::GetDC(0);    DASSERT(hDC != NULL);
 817 
 818     jobject font = env->GetObjectField(self, AwtFont::fontID);
 819 
 820     long ret = AwtFont::getMFStringWidth(hDC, font, str);

 821     VERIFY(::ReleaseDC(0, hDC));
 822     return ret;
 823 
 824     CATCH_BAD_ALLOC_RET(0);
 825 }
 826 
 827 /*
 828  * Class:     sun_awt_windows_WFontMetrics
 829  * Method:    charsWidth
 830  * Signature: ([CII)I
 831  */
 832 JNIEXPORT jint JNICALL
 833 Java_sun_awt_windows_WFontMetrics_charsWidth(JNIEnv *env, jobject self,
 834                                              jcharArray str,
 835                                              jint off, jint len)
 836 {
 837     TRY;
 838 
 839     if (str == NULL) {
 840         JNU_ThrowNullPointerException(env, "str argument");


 907             for (; len; len--) {
 908                 result += widths[*pStr++];
 909             }
 910         } catch (...) {
 911             if (widths != NULL) {
 912                 env->ReleasePrimitiveArrayCritical(array, widths, 0);
 913             }
 914             throw;
 915         }
 916 
 917         env->ReleasePrimitiveArrayCritical(array, widths, 0);
 918 
 919     } catch (...) {
 920         if (pStrBody != NULL) {
 921             env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
 922         }
 923         throw;
 924     }
 925 
 926     env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
 927     return result;
 928 
 929     CATCH_BAD_ALLOC_RET(0);
 930 }
 931 
 932 
 933 /*
 934  * Class:     sun_awt_windows_WFontMetrics
 935  * Method:    init
 936  * Signature: ()V
 937  */
 938 JNIEXPORT void JNICALL
 939 Java_sun_awt_windows_WFontMetrics_init(JNIEnv *env, jobject self)
 940 {
 941     TRY;
 942 
 943     jobject font = env->GetObjectField(self, AwtFont::fontID);
 944     if (font == NULL) {
 945         JNU_ThrowNullPointerException(env, "fontMetrics' font");
 946         return;
 947     }




 381         throw;
 382     }
 383 
 384     env->DeleteLocalRef(compFont);
 385     return awtFont;
 386 }
 387 
 388 static void strip_tail(wchar_t* text, wchar_t* tail) { // strips tail and any possible whitespace before it from the end of text
 389     if (wcslen(text)<=wcslen(tail)) {
 390         return;
 391     }
 392     wchar_t* p = text+wcslen(text)-wcslen(tail);
 393     if (!wcscmp(p, tail)) {
 394         while(p>text && iswspace(*(p-1)))
 395             p--;
 396         *p = 0;
 397     }
 398 
 399 }
 400 
 401 static int ScaleUpX(float x) {
 402     int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
 403         ::GetDesktopWindow());
 404     Devices::InstanceAccess devices;
 405     AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
 406     return device == NULL ? x : device->ScaleUpX(x);
 407 }
 408 
 409 static int ScaleUpY(int y) {
 410     int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
 411         ::GetDesktopWindow());
 412     Devices::InstanceAccess devices;
 413     AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
 414     return device == NULL ? y : device->ScaleUpY(y);
 415 }
 416 
 417 static int ScaleDownX(int x) {
 418     int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
 419         ::GetDesktopWindow());
 420     Devices::InstanceAccess devices;
 421     AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
 422     return device == NULL ? x : device->ScaleDownX(x);
 423 }
 424 
 425 static int ScaleDownY(int y) {
 426     int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
 427         ::GetDesktopWindow());
 428     Devices::InstanceAccess devices;
 429     AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
 430     return device == NULL ? y : device->ScaleDownY(y);
 431 }
 432 
 433 static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
 434                              int angle=0, float awScale=1.0f)
 435 {
 436     LOGFONTW logFont;
 437 
 438     logFont.lfWidth = 0;
 439     logFont.lfEscapement = angle;
 440     logFont.lfOrientation = angle;
 441     logFont.lfUnderline = FALSE;
 442     logFont.lfStrikeOut = FALSE;
 443     logFont.lfCharSet = GetNativeCharset(name);
 444     if (angle == 0 && awScale == 1.0f) {
 445         logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
 446     } else {
 447         logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
 448     }
 449     logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
 450     logFont.lfQuality = DEFAULT_QUALITY;
 451     logFont.lfPitchAndFamily = DEFAULT_PITCH;
 452 
 453     // Set style
 454     logFont.lfWeight = (style & java_awt_Font_BOLD) ? FW_BOLD : FW_NORMAL;
 455     logFont.lfItalic = (style & java_awt_Font_ITALIC) != 0;
 456     logFont.lfUnderline = 0;//(style & java_awt_Font_UNDERLINE) != 0;
 457 
 458     // Get point size
 459     logFont.lfHeight = ScaleUpY(-height);
 460 
 461     // Set font name
 462     WCHAR tmpname[80];
 463     wcscpy(tmpname, name);
 464     WCHAR* delimit = wcschr(tmpname, L',');
 465     if (delimit != NULL)
 466         *delimit = L'\0';  // terminate the string after the font name.
 467     // strip "Bold" and "Italic" from the end of the name
 468     strip_tail(tmpname,L""); //strip possible trailing whitespace
 469     strip_tail(tmpname,L"Italic");
 470     strip_tail(tmpname,L"Bold");
 471     wcscpy(&(logFont.lfFaceName[0]), tmpname);
 472     HFONT hFont = ::CreateFontIndirect(&logFont);
 473     DASSERT(hFont != NULL);
 474     // get a expanded or condensed version if its specified.
 475     if (awScale != 1.0f) {
 476         HDC hDC = ::GetDC(0);
 477         HFONT oldFont = (HFONT)::SelectObject(hDC, hFont);
 478         TEXTMETRIC tm;
 479         DWORD avgWidth;
 480         GetTextMetrics(hDC, &tm);
 481         oldFont = (HFONT)::SelectObject(hDC, oldFont);
 482         if (oldFont != NULL) { // should be the same as hFont
 483             VERIFY(::DeleteObject(oldFont));
 484         }
 485         avgWidth = tm.tmAveCharWidth;
 486         logFont.lfWidth = (LONG) ScaleUpX((fabs) (avgWidth * awScale));
 487         hFont = ::CreateFontIndirect(&logFont);
 488         DASSERT(hFont != NULL);
 489         VERIFY(::ReleaseDC(0, hDC));
 490     }
 491 
 492     return hFont;
 493 }
 494 
 495 HFONT AwtFont::CreateHFont(WCHAR* name, int style, int height,
 496                            int angle, float awScale)
 497 {
 498     WCHAR longName[80];
 499     // 80 > (max face name(=30) + strlen("CHINESEBIG5_CHARSET"))
 500     // longName doesn't have to be printable.  So, it is OK not to convert.
 501 
 502     wsprintf(longName, L"%ls-%d-%d", name, style, height);
 503 
 504     HFONT hFont = NULL;
 505 
 506     // only cache & share unrotated, unexpanded/uncondensed fonts


 550     jobject font = env->GetObjectField(fontMetrics, AwtFont::fontID);
 551     AwtFont* awtFont = AwtFont::GetFont(env, font);
 552 
 553     if (!awtFont) {
 554         /* failed to get font */
 555         return;
 556     }
 557 
 558     HDC hDC = ::GetDC(0);
 559     DASSERT(hDC != NULL);
 560 
 561     HGDIOBJ oldFont = ::SelectObject(hDC, awtFont->GetHFont());
 562     TEXTMETRIC metrics;
 563     VERIFY(::GetTextMetrics(hDC, &metrics));
 564 
 565     awtFont->m_ascent = metrics.tmAscent;
 566 
 567     int ascent = metrics.tmAscent;
 568     int descent = metrics.tmDescent;
 569     int leading = metrics.tmExternalLeading;
 570 
 571     env->SetIntField(fontMetrics, AwtFont::ascentID, ScaleDownY(ascent));
 572     env->SetIntField(fontMetrics, AwtFont::descentID, ScaleDownY(descent));
 573     env->SetIntField(fontMetrics, AwtFont::leadingID, ScaleDownX(leading));
 574     env->SetIntField(fontMetrics, AwtFont::heightID, 
 575         ScaleDownY(metrics.tmAscent + metrics.tmDescent + leading));
 576     env->SetIntField(fontMetrics, AwtFont::maxAscentID, ScaleDownY(ascent));
 577     env->SetIntField(fontMetrics, AwtFont::maxDescentID, ScaleDownY(descent));
 578 
 579     int maxHeight =  ascent + descent + leading;
 580     env->SetIntField(fontMetrics, AwtFont::maxHeightID, ScaleDownY(maxHeight));
 581 
 582     int maxAdvance = metrics.tmMaxCharWidth;
 583     env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, ScaleDownX(maxAdvance));
 584 
 585     awtFont->m_overhang = metrics.tmOverhang;
 586 
 587     jint intWidths[256];
 588     memset(intWidths, 0, 256 * sizeof(int));
 589     VERIFY(::GetCharWidth(hDC, metrics.tmFirstChar,
 590                           min(metrics.tmLastChar, 255),
 591                           (int *)&intWidths[metrics.tmFirstChar]));
 592     env->SetIntArrayRegion(widths, 0, 256, intWidths);
 593     env->SetObjectField(fontMetrics, AwtFont::widthsID, widths);
 594 
 595     // Get font metrics on remaining fonts (if multifont).
 596     for (int j = 1; j < awtFont->GetHFontNum(); j++) {
 597         ::SelectObject(hDC, awtFont->GetHFont(j));
 598         VERIFY(::GetTextMetrics(hDC, &metrics));
 599         env->SetIntField(fontMetrics, AwtFont::maxAscentID,
 600                          ascent = max(ascent, metrics.tmAscent));
 601         env->SetIntField(fontMetrics, AwtFont::maxDescentID,
 602                          descent = max(descent, metrics.tmDescent));
 603         env->SetIntField(fontMetrics, AwtFont::maxHeightID,


 834 /*
 835  * Class:     sun_awt_windows_WFontMetrics
 836  * Method:    stringWidth
 837  * Signature: (Ljava/lang/String;)I
 838  */
 839 JNIEXPORT jint JNICALL
 840 Java_sun_awt_windows_WFontMetrics_stringWidth(JNIEnv *env, jobject self,
 841                                               jstring str)
 842 {
 843     TRY;
 844 
 845     if (str == NULL) {
 846         JNU_ThrowNullPointerException(env, "str argument");
 847         return NULL;
 848     }
 849     HDC hDC = ::GetDC(0);    DASSERT(hDC != NULL);
 850 
 851     jobject font = env->GetObjectField(self, AwtFont::fontID);
 852 
 853     long ret = AwtFont::getMFStringWidth(hDC, font, str);
 854     ret = ScaleDownX(ret);
 855     VERIFY(::ReleaseDC(0, hDC));
 856     return ret;
 857 
 858     CATCH_BAD_ALLOC_RET(0);
 859 }
 860 
 861 /*
 862  * Class:     sun_awt_windows_WFontMetrics
 863  * Method:    charsWidth
 864  * Signature: ([CII)I
 865  */
 866 JNIEXPORT jint JNICALL
 867 Java_sun_awt_windows_WFontMetrics_charsWidth(JNIEnv *env, jobject self,
 868                                              jcharArray str,
 869                                              jint off, jint len)
 870 {
 871     TRY;
 872 
 873     if (str == NULL) {
 874         JNU_ThrowNullPointerException(env, "str argument");


 941             for (; len; len--) {
 942                 result += widths[*pStr++];
 943             }
 944         } catch (...) {
 945             if (widths != NULL) {
 946                 env->ReleasePrimitiveArrayCritical(array, widths, 0);
 947             }
 948             throw;
 949         }
 950 
 951         env->ReleasePrimitiveArrayCritical(array, widths, 0);
 952 
 953     } catch (...) {
 954         if (pStrBody != NULL) {
 955             env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
 956         }
 957         throw;
 958     }
 959 
 960     env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
 961     return ScaleDownX(result);
 962 
 963     CATCH_BAD_ALLOC_RET(0);
 964 }
 965 
 966 
 967 /*
 968  * Class:     sun_awt_windows_WFontMetrics
 969  * Method:    init
 970  * Signature: ()V
 971  */
 972 JNIEXPORT void JNICALL
 973 Java_sun_awt_windows_WFontMetrics_init(JNIEnv *env, jobject self)
 974 {
 975     TRY;
 976 
 977     jobject font = env->GetObjectField(self, AwtFont::fontID);
 978     if (font == NULL) {
 979         JNU_ThrowNullPointerException(env, "fontMetrics' font");
 980         return;
 981     }


< prev index next >