The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

742 lines
23KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. #include "win32_headers.h"
  24. #include "../../../src/juce_core/basics/juce_StandardHeader.h"
  25. BEGIN_JUCE_NAMESPACE
  26. #include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h"
  27. #include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
  28. #include "../../../src/juce_core/basics/juce_SystemStats.h"
  29. #include "../../../src/juce_core/basics/juce_Singleton.h"
  30. #include "../../../src/juce_appframework/gui/graphics/imaging/juce_Image.h"
  31. //==============================================================================
  32. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  33. UNICODE_FUNCTION (GetGlyphOutlineW, DWORD, (HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, LPVOID, CONST MAT2*))
  34. UNICODE_FUNCTION (GetTextMetricsW, BOOL, (HDC, LPTEXTMETRICW))
  35. UNICODE_FUNCTION (GetKerningPairsW, DWORD, (HDC, DWORD, LPKERNINGPAIR))
  36. UNICODE_FUNCTION (EnumFontFamiliesExW, int, (HDC, LPLOGFONTW, FONTENUMPROCW, LPARAM, DWORD))
  37. UNICODE_FUNCTION (CreateFontIndirectW, HFONT, (CONST LOGFONTW *));
  38. static void juce_initialiseUnicodeFileFontFunctions()
  39. {
  40. static bool initialised = false;
  41. if (! initialised)
  42. {
  43. initialised = true;
  44. if ((SystemStats::getOperatingSystemType() & SystemStats::WindowsNT) != 0)
  45. {
  46. HMODULE h = LoadLibraryA ("gdi32.dll");
  47. UNICODE_FUNCTION_LOAD (GetGlyphOutlineW)
  48. UNICODE_FUNCTION_LOAD (GetTextMetricsW)
  49. UNICODE_FUNCTION_LOAD (GetKerningPairsW)
  50. UNICODE_FUNCTION_LOAD (EnumFontFamiliesExW)
  51. UNICODE_FUNCTION_LOAD (CreateFontIndirectW)
  52. }
  53. }
  54. }
  55. #endif
  56. //==============================================================================
  57. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  58. static int CALLBACK fontEnum2 (ENUMLOGFONTEX* lpelfe,
  59. NEWTEXTMETRICEX*,
  60. int type,
  61. LPARAM lParam)
  62. {
  63. if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
  64. {
  65. const String fontName (lpelfe->elfLogFont.lfFaceName);
  66. ((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters (T("@")));
  67. }
  68. return 1;
  69. }
  70. #endif
  71. static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
  72. NEWTEXTMETRICEXW*,
  73. int type,
  74. LPARAM lParam)
  75. {
  76. if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
  77. {
  78. const String fontName (lpelfe->elfLogFont.lfFaceName);
  79. ((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters (T("@")));
  80. }
  81. return 1;
  82. }
  83. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  84. static int CALLBACK fontEnum1 (ENUMLOGFONTEX* lpelfe,
  85. NEWTEXTMETRICEX*,
  86. int type,
  87. LPARAM lParam)
  88. {
  89. if (lpelfe != 0
  90. && ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
  91. {
  92. LOGFONT lf;
  93. zerostruct (lf);
  94. lf.lfWeight = FW_DONTCARE;
  95. lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  96. lf.lfQuality = DEFAULT_QUALITY;
  97. lf.lfCharSet = DEFAULT_CHARSET;
  98. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  99. lf.lfPitchAndFamily = FF_DONTCARE;
  100. const String fontName (lpelfe->elfLogFont.lfFaceName);
  101. fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
  102. HDC dc = CreateCompatibleDC (0);
  103. EnumFontFamiliesEx (dc, &lf,
  104. (FONTENUMPROC) &fontEnum2,
  105. lParam, 0);
  106. DeleteDC (dc);
  107. }
  108. return 1;
  109. }
  110. #endif
  111. static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
  112. NEWTEXTMETRICEXW*,
  113. int type,
  114. LPARAM lParam)
  115. {
  116. if (lpelfe != 0
  117. && ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
  118. {
  119. LOGFONTW lf;
  120. zerostruct (lf);
  121. lf.lfWeight = FW_DONTCARE;
  122. lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  123. lf.lfQuality = DEFAULT_QUALITY;
  124. lf.lfCharSet = DEFAULT_CHARSET;
  125. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  126. lf.lfPitchAndFamily = FF_DONTCARE;
  127. const String fontName (lpelfe->elfLogFont.lfFaceName);
  128. fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
  129. HDC dc = CreateCompatibleDC (0);
  130. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  131. wEnumFontFamiliesExW (dc, &lf,
  132. (FONTENUMPROCW) &wfontEnum2,
  133. lParam, 0);
  134. #else
  135. EnumFontFamiliesExW (dc, &lf,
  136. (FONTENUMPROCW) &wfontEnum2,
  137. lParam, 0);
  138. #endif
  139. DeleteDC (dc);
  140. }
  141. return 1;
  142. }
  143. const StringArray Font::findAllTypefaceNames()
  144. {
  145. StringArray results;
  146. HDC dc = CreateCompatibleDC (0);
  147. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  148. if (wEnumFontFamiliesExW != 0)
  149. {
  150. LOGFONTW lf;
  151. zerostruct (lf);
  152. lf.lfWeight = FW_DONTCARE;
  153. lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  154. lf.lfQuality = DEFAULT_QUALITY;
  155. lf.lfCharSet = DEFAULT_CHARSET;
  156. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  157. lf.lfPitchAndFamily = FF_DONTCARE;
  158. lf.lfFaceName[0] = 0;
  159. wEnumFontFamiliesExW (dc, &lf,
  160. (FONTENUMPROCW) &wfontEnum1,
  161. (LPARAM) &results, 0);
  162. }
  163. else
  164. {
  165. LOGFONT lf;
  166. zerostruct (lf);
  167. lf.lfWeight = FW_DONTCARE;
  168. lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  169. lf.lfQuality = DEFAULT_QUALITY;
  170. lf.lfCharSet = DEFAULT_CHARSET;
  171. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  172. lf.lfPitchAndFamily = FF_DONTCARE;
  173. lf.lfFaceName[0] = 0;
  174. EnumFontFamiliesEx (dc, &lf,
  175. (FONTENUMPROC) &fontEnum1,
  176. (LPARAM) &results, 0);
  177. }
  178. #else
  179. {
  180. LOGFONTW lf;
  181. zerostruct (lf);
  182. lf.lfWeight = FW_DONTCARE;
  183. lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
  184. lf.lfQuality = DEFAULT_QUALITY;
  185. lf.lfCharSet = DEFAULT_CHARSET;
  186. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  187. lf.lfPitchAndFamily = FF_DONTCARE;
  188. lf.lfFaceName[0] = 0;
  189. EnumFontFamiliesExW (dc, &lf,
  190. (FONTENUMPROCW) &wfontEnum1,
  191. (LPARAM) &results, 0);
  192. }
  193. #endif
  194. DeleteDC (dc);
  195. results.sort (true);
  196. return results;
  197. }
  198. void Font::getDefaultFontNames (String& defaultSans,
  199. String& defaultSerif,
  200. String& defaultFixed)
  201. {
  202. defaultSans = "Verdana";
  203. defaultSerif = "Times";
  204. defaultFixed = "Lucida Console";
  205. }
  206. //==============================================================================
  207. class FontDCHolder : private DeletedAtShutdown
  208. {
  209. HDC dc;
  210. String fontName;
  211. KERNINGPAIR* kps;
  212. int numKPs;
  213. bool bold, italic;
  214. int size;
  215. FontDCHolder (const FontDCHolder&);
  216. const FontDCHolder& operator= (const FontDCHolder&);
  217. public:
  218. HFONT fontH;
  219. //==============================================================================
  220. FontDCHolder() throw()
  221. : dc (0),
  222. kps (0),
  223. numKPs (0),
  224. bold (false),
  225. italic (false),
  226. size (0)
  227. {
  228. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  229. juce_initialiseUnicodeFileFontFunctions();
  230. #endif
  231. }
  232. ~FontDCHolder() throw()
  233. {
  234. if (dc != 0)
  235. {
  236. DeleteDC (dc);
  237. DeleteObject (fontH);
  238. juce_free (kps);
  239. }
  240. clearSingletonInstance();
  241. }
  242. juce_DeclareSingleton_SingleThreaded_Minimal (FontDCHolder);
  243. //==============================================================================
  244. HDC loadFont (const String& fontName_,
  245. const bool bold_,
  246. const bool italic_,
  247. const int size_) throw()
  248. {
  249. if (fontName != fontName_ || bold != bold_ || italic != italic_ || size != size_)
  250. {
  251. fontName = fontName_;
  252. bold = bold_;
  253. italic = italic_;
  254. size = size_;
  255. if (dc != 0)
  256. {
  257. DeleteDC (dc);
  258. DeleteObject (fontH);
  259. juce_free (kps);
  260. kps = 0;
  261. }
  262. fontH = 0;
  263. dc = CreateCompatibleDC (0);
  264. SetMapperFlags (dc, 0);
  265. SetMapMode (dc, MM_TEXT);
  266. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  267. LOGFONT lf;
  268. LOGFONTW lfw;
  269. HFONT standardSizedFont = 0;
  270. if (wCreateFontIndirectW != 0)
  271. {
  272. zerostruct (lfw);
  273. lfw.lfCharSet = DEFAULT_CHARSET;
  274. lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  275. lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
  276. lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  277. lfw.lfQuality = PROOF_QUALITY;
  278. lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
  279. lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
  280. fontName.copyToBuffer (lfw.lfFaceName, LF_FACESIZE - 1);
  281. lfw.lfHeight = size > 0 ? size : -256;
  282. standardSizedFont = wCreateFontIndirectW (&lfw);
  283. }
  284. else
  285. {
  286. zerostruct (lf);
  287. lf.lfCharSet = DEFAULT_CHARSET;
  288. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  289. lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
  290. lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  291. lf.lfQuality = PROOF_QUALITY;
  292. lf.lfItalic = (BYTE) (italic ? TRUE : FALSE);
  293. lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
  294. fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
  295. lf.lfHeight = size > 0 ? size : -256;
  296. standardSizedFont = CreateFontIndirect (&lf);
  297. }
  298. #else
  299. LOGFONTW lfw;
  300. zerostruct (lfw);
  301. lfw.lfCharSet = DEFAULT_CHARSET;
  302. lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  303. lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
  304. lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  305. lfw.lfQuality = PROOF_QUALITY;
  306. lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
  307. lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
  308. fontName.copyToBuffer (lfw.lfFaceName, LF_FACESIZE - 1);
  309. lfw.lfHeight = size > 0 ? size : -256;
  310. HFONT standardSizedFont = CreateFontIndirectW (&lfw);
  311. #endif
  312. if (standardSizedFont != 0)
  313. {
  314. if (SelectObject (dc, standardSizedFont) != 0)
  315. {
  316. fontH = standardSizedFont;
  317. if (size == 0)
  318. {
  319. OUTLINETEXTMETRIC otm;
  320. if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
  321. {
  322. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  323. if (wCreateFontIndirectW != 0)
  324. {
  325. lfw.lfHeight = -(int) otm.otmEMSquare;
  326. fontH = wCreateFontIndirectW (&lfw);
  327. }
  328. else
  329. {
  330. lf.lfHeight = -(int) otm.otmEMSquare;
  331. fontH = CreateFontIndirect (&lf);
  332. }
  333. #else
  334. lfw.lfHeight = -(int) otm.otmEMSquare;
  335. fontH = CreateFontIndirectW (&lfw);
  336. #endif
  337. SelectObject (dc, fontH);
  338. DeleteObject (standardSizedFont);
  339. }
  340. }
  341. }
  342. else
  343. {
  344. jassertfalse
  345. }
  346. }
  347. else
  348. {
  349. jassertfalse
  350. }
  351. }
  352. return dc;
  353. }
  354. //==============================================================================
  355. KERNINGPAIR* getKerningPairs (int& numKPs_) throw()
  356. {
  357. if (kps == 0)
  358. {
  359. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  360. if (wGetKerningPairsW != 0)
  361. {
  362. numKPs = wGetKerningPairsW (dc, 0, 0);
  363. kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
  364. wGetKerningPairsW (dc, numKPs, kps);
  365. }
  366. else
  367. {
  368. numKPs = GetKerningPairs (dc, 0, 0);
  369. kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
  370. GetKerningPairs (dc, numKPs, kps);
  371. }
  372. #else
  373. numKPs = GetKerningPairsW (dc, 0, 0);
  374. kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
  375. GetKerningPairsW (dc, numKPs, kps);
  376. #endif
  377. }
  378. numKPs_ = numKPs;
  379. return kps;
  380. }
  381. };
  382. juce_ImplementSingleton_SingleThreaded (FontDCHolder);
  383. //==============================================================================
  384. static void addGlyphToTypeface (HDC dc,
  385. juce_wchar character,
  386. Typeface& dest,
  387. bool addKerning)
  388. {
  389. Path destShape;
  390. GLYPHMETRICS gm;
  391. float height;
  392. BOOL ok = false;
  393. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  394. if (wGetTextMetricsW != 0)
  395. {
  396. TEXTMETRICW tm;
  397. ok = wGetTextMetricsW (dc, &tm);
  398. height = (float) tm.tmHeight;
  399. }
  400. else
  401. {
  402. TEXTMETRIC tm;
  403. ok = GetTextMetrics (dc, &tm);
  404. height = (float) tm.tmHeight;
  405. }
  406. #else
  407. TEXTMETRICW tm;
  408. ok = GetTextMetricsW (dc, &tm);
  409. height = (float) tm.tmHeight;
  410. #endif
  411. if (! ok)
  412. {
  413. dest.addGlyph (character, destShape, 0);
  414. return;
  415. }
  416. const float scaleX = 1.0f / height;
  417. const float scaleY = -1.0f / height;
  418. static const MAT2 identityMatrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
  419. int bufSize;
  420. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  421. if (wGetGlyphOutlineW != 0)
  422. bufSize = wGetGlyphOutlineW (dc, character, GGO_NATIVE,
  423. &gm, 0, 0, &identityMatrix);
  424. else
  425. bufSize = GetGlyphOutline (dc, character, GGO_NATIVE,
  426. &gm, 0, 0, &identityMatrix);
  427. #else
  428. bufSize = GetGlyphOutlineW (dc, character, GGO_NATIVE,
  429. &gm, 0, 0, &identityMatrix);
  430. #endif
  431. if (bufSize > 0)
  432. {
  433. char* const data = (char*) juce_malloc (bufSize);
  434. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  435. if (wGetGlyphOutlineW != 0)
  436. wGetGlyphOutlineW (dc, character, GGO_NATIVE, &gm,
  437. bufSize, data, &identityMatrix);
  438. else
  439. GetGlyphOutline (dc, character, GGO_NATIVE, &gm,
  440. bufSize, data, &identityMatrix);
  441. #else
  442. GetGlyphOutlineW (dc, character, GGO_NATIVE, &gm,
  443. bufSize, data, &identityMatrix);
  444. #endif
  445. const TTPOLYGONHEADER* pheader = (TTPOLYGONHEADER*) data;
  446. while ((char*) pheader < data + bufSize)
  447. {
  448. #define remapX(v) (scaleX * (v).x.value)
  449. #define remapY(v) (scaleY * (v).y.value)
  450. float x = remapX (pheader->pfxStart);
  451. float y = remapY (pheader->pfxStart);
  452. destShape.startNewSubPath (x, y);
  453. const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
  454. const char* const curveEnd = ((const char*) pheader) + pheader->cb;
  455. while ((const char*) curve < curveEnd)
  456. {
  457. if (curve->wType == TT_PRIM_LINE)
  458. {
  459. for (int i = 0; i < curve->cpfx; ++i)
  460. {
  461. x = remapX (curve->apfx [i]);
  462. y = remapY (curve->apfx [i]);
  463. destShape.lineTo (x, y);
  464. }
  465. }
  466. else if (curve->wType == TT_PRIM_QSPLINE)
  467. {
  468. for (int i = 0; i < curve->cpfx - 1; ++i)
  469. {
  470. const float x2 = remapX (curve->apfx [i]);
  471. const float y2 = remapY (curve->apfx [i]);
  472. float x3, y3;
  473. if (i < curve->cpfx - 2)
  474. {
  475. x3 = 0.5f * (x2 + remapX (curve->apfx [i + 1]));
  476. y3 = 0.5f * (y2 + remapY (curve->apfx [i + 1]));
  477. }
  478. else
  479. {
  480. x3 = remapX (curve->apfx [i + 1]);
  481. y3 = remapY (curve->apfx [i + 1]);
  482. }
  483. destShape.quadraticTo (x2, y2, x3, y3);
  484. x = x3;
  485. y = y3;
  486. }
  487. }
  488. curve = (const TTPOLYCURVE*) &(curve->apfx [curve->cpfx]);
  489. }
  490. pheader = (const TTPOLYGONHEADER*) curve;
  491. destShape.closeSubPath();
  492. }
  493. juce_free (data);
  494. }
  495. dest.addGlyph (character, destShape, gm.gmCellIncX / height);
  496. if (addKerning)
  497. {
  498. int numKPs;
  499. const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
  500. for (int i = 0; i < numKPs; ++i)
  501. {
  502. if (kps[i].wFirst == character)
  503. {
  504. dest.addKerningPair (kps[i].wFirst,
  505. kps[i].wSecond,
  506. kps[i].iKernAmount / height);
  507. }
  508. }
  509. }
  510. }
  511. //==============================================================================
  512. void Typeface::findAndAddSystemGlyph (juce_wchar character) throw()
  513. {
  514. HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), 0);
  515. addGlyphToTypeface (dc, character, *this, true);
  516. }
  517. /*Image* Typeface::renderGlyphToImage (juce_wchar character, float& topLeftX, float& topLeftY)
  518. {
  519. HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), hintingSize);
  520. int bufSize;
  521. GLYPHMETRICS gm;
  522. const UINT format = GGO_GRAY2_BITMAP;
  523. const int shift = 6;
  524. if (wGetGlyphOutlineW != 0)
  525. bufSize = wGetGlyphOutlineW (dc, character, format, &gm, 0, 0, &identityMatrix);
  526. else
  527. bufSize = GetGlyphOutline (dc, character, format, &gm, 0, 0, &identityMatrix);
  528. Image* im = new Image (Image::SingleChannel, jmax (1, gm.gmBlackBoxX), jmax (1, gm.gmBlackBoxY), true);
  529. if (bufSize > 0)
  530. {
  531. topLeftX = (float) gm.gmptGlyphOrigin.x;
  532. topLeftY = (float) -gm.gmptGlyphOrigin.y;
  533. uint8* const data = (uint8*) juce_calloc (bufSize);
  534. if (wGetGlyphOutlineW != 0)
  535. wGetGlyphOutlineW (dc, character, format, &gm, bufSize, data, &identityMatrix);
  536. else
  537. GetGlyphOutline (dc, character, format, &gm, bufSize, data, &identityMatrix);
  538. const int stride = ((gm.gmBlackBoxX + 3) & ~3);
  539. for (int y = gm.gmBlackBoxY; --y >= 0;)
  540. {
  541. for (int x = gm.gmBlackBoxX; --x >= 0;)
  542. {
  543. const int level = data [x + y * stride] << shift;
  544. if (level > 0)
  545. im->setPixelAt (x, y, Colour ((uint8) 0xff, (uint8) 0xff, (uint8) 0xff, (uint8) jmin (0xff, level)));
  546. }
  547. }
  548. juce_free (data);
  549. }
  550. return im;
  551. }*/
  552. //==============================================================================
  553. void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
  554. bool bold,
  555. bool italic,
  556. bool addAllGlyphsToFont) throw()
  557. {
  558. clear();
  559. HDC dc = FontDCHolder::getInstance()->loadFont (fontName, bold, italic, 0);
  560. float height;
  561. int firstChar, lastChar;
  562. #if JUCE_ENABLE_WIN98_COMPATIBILITY
  563. if (wGetTextMetricsW != 0)
  564. {
  565. TEXTMETRICW tm;
  566. wGetTextMetricsW (dc, &tm);
  567. height = (float) tm.tmHeight;
  568. firstChar = tm.tmFirstChar;
  569. lastChar = tm.tmLastChar;
  570. setAscent (tm.tmAscent / height);
  571. setDefaultCharacter (tm.tmDefaultChar);
  572. }
  573. else
  574. {
  575. TEXTMETRIC tm;
  576. GetTextMetrics (dc, &tm);
  577. height = (float) tm.tmHeight;
  578. firstChar = tm.tmFirstChar;
  579. lastChar = tm.tmLastChar;
  580. setAscent (tm.tmAscent / height);
  581. setDefaultCharacter (tm.tmDefaultChar);
  582. }
  583. #else
  584. {
  585. TEXTMETRICW tm;
  586. GetTextMetricsW (dc, &tm);
  587. height = (float) tm.tmHeight;
  588. firstChar = tm.tmFirstChar;
  589. lastChar = tm.tmLastChar;
  590. setAscent (tm.tmAscent / height);
  591. setDefaultCharacter (tm.tmDefaultChar);
  592. }
  593. #endif
  594. setName (fontName);
  595. setBold (bold);
  596. setItalic (italic);
  597. if (addAllGlyphsToFont)
  598. {
  599. for (int character = firstChar; character <= lastChar; ++character)
  600. addGlyphToTypeface (dc, (juce_wchar) character, *this, false);
  601. int numKPs;
  602. const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
  603. for (int i = 0; i < numKPs; ++i)
  604. {
  605. addKerningPair (kps[i].wFirst,
  606. kps[i].wSecond,
  607. kps[i].iKernAmount / height);
  608. }
  609. }
  610. }
  611. END_JUCE_NAMESPACE