]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: font.cpp | |
3 | // Purpose: wxFont class | |
4 | // Author: David Webster | |
5 | // Modified by: | |
6 | // Created: 10/06/99 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) David Webster | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
20 | #include <malloc.h> | |
21 | // For compilers that support precompilation, includes "wx.h". | |
22 | #include "wx/wxprec.h" | |
23 | ||
24 | #ifndef WX_PRECOMP | |
25 | #include <stdio.h> | |
26 | #include "wx/setup.h" | |
27 | #include "wx/list.h" | |
28 | #include "wx/utils.h" | |
29 | #include "wx/app.h" | |
30 | #include "wx/font.h" | |
31 | #endif // WX_PRECOMP | |
32 | ||
33 | #include "wx/os2/private.h" | |
34 | ||
35 | IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) | |
36 | ||
37 | #if wxUSE_PORTABLE_FONTS_IN_MSW | |
38 | IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject) | |
39 | #endif | |
40 | ||
41 | // ---------------------------------------------------------------------------- | |
42 | // wxFontRefData - the internal description of the font | |
43 | // ---------------------------------------------------------------------------- | |
44 | ||
45 | class WXDLLEXPORT wxFontRefData: public wxGDIRefData | |
46 | { | |
47 | friend class WXDLLEXPORT wxFont; | |
48 | ||
49 | public: | |
50 | wxFontRefData() | |
51 | { | |
52 | Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE, | |
53 | "", wxFONTENCODING_DEFAULT); | |
54 | } | |
55 | ||
56 | wxFontRefData(const wxFontRefData& data) | |
57 | { | |
58 | Init(data.m_nPointSize, data.m_nFamily, data.m_nStyle, data.m_nWeight, | |
59 | data.m_bUnderlined, data.m_sFaceName, data.m_vEncoding); | |
60 | ||
61 | m_nFontId = data.m_nFontId; | |
62 | } | |
63 | ||
64 | wxFontRefData( int nSize | |
65 | ,int nFamily | |
66 | ,int nStyle | |
67 | ,int nWeight | |
68 | ,bool bUnderlined | |
69 | ,const wxString& sFaceName | |
70 | ,wxFontEncoding vEncoding | |
71 | ) | |
72 | { | |
73 | Init(nSize, nFamily, nStyle, nWeight, bUnderlined, sFaceName, vEncoding); | |
74 | } | |
75 | ||
76 | virtual ~wxFontRefData(); | |
77 | ||
78 | protected: | |
79 | // common part of all ctors | |
80 | void Init( int nSize | |
81 | ,int nFamily | |
82 | ,int nStyle | |
83 | ,int nWeight | |
84 | ,bool bUnderlined | |
85 | ,const wxString& rsFaceName | |
86 | ,wxFontEncoding vEncoding | |
87 | ); | |
88 | ||
89 | // | |
90 | // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE | |
91 | // DELETED by destructor | |
92 | // | |
93 | bool m_bTemporary; | |
94 | int m_nFontId; | |
95 | ||
96 | // | |
97 | // Font characterstics | |
98 | // | |
99 | int m_nPointSize; | |
100 | int m_nFamily; | |
101 | int m_nStyle; | |
102 | int m_nWeight; | |
103 | bool m_bUnderlined; | |
104 | wxString m_sFaceName; | |
105 | wxFontEncoding m_vEncoding; | |
106 | ||
107 | // | |
108 | // Some PM specific stuff | |
109 | // | |
110 | WXHFONT m_hFont; | |
111 | PFONTMETRICS m_pFM; // array of FONTMETRICS structs | |
112 | int m_nNumFonts; // number of fonts in array | |
113 | HPS m_hPS; // PS handle this font belongs to | |
114 | FATTRS m_vFattrs; // Current fattrs struct | |
115 | FACENAMEDESC m_vFname; // Current facename struct | |
116 | }; // end of CLASS wxFontRefData | |
117 | ||
118 | // ============================================================================ | |
119 | // implementation | |
120 | // ============================================================================ | |
121 | ||
122 | // ---------------------------------------------------------------------------- | |
123 | // wxFontRefData | |
124 | // ---------------------------------------------------------------------------- | |
125 | ||
126 | void wxFontRefData::Init( | |
127 | int nPointSize | |
128 | , int nFamily | |
129 | , int nStyle | |
130 | , int nWeight | |
131 | , bool bUnderlined | |
132 | , const wxString& rsFaceName | |
133 | , wxFontEncoding vEncoding | |
134 | ) | |
135 | { | |
136 | m_nStyle = nStyle; | |
137 | m_nPointSize = nPointSize; | |
138 | m_nFamily = nFamily; | |
139 | m_nStyle = nStyle; | |
140 | m_nWeight = nWeight; | |
141 | m_bUnderlined = bUnderlined; | |
142 | m_sFaceName = rsFaceName; | |
143 | m_vEncoding = vEncoding; | |
144 | m_nFontId = 0; | |
145 | m_bTemporary = FALSE; | |
146 | ||
147 | m_hFont = 0; | |
148 | m_pFM = (PFONTMETRICS)NULL; | |
149 | m_hPS = NULLHANDLE; | |
150 | m_nNumFonts = 0; | |
151 | } // end of wxFontRefData::Init | |
152 | ||
153 | wxFontRefData::~wxFontRefData() | |
154 | { | |
155 | if (m_pFM) | |
156 | delete [] m_pFM; | |
157 | m_pFM = (PFONTMETRICS)NULL; | |
158 | } | |
159 | ||
160 | // ---------------------------------------------------------------------------- | |
161 | // wxFont | |
162 | // ---------------------------------------------------------------------------- | |
163 | ||
164 | void wxFont::Init() | |
165 | { | |
166 | if ( wxTheFontList ) | |
167 | wxTheFontList->Append(this); | |
168 | } | |
169 | ||
170 | // ---------------------------------------------------------------------------- | |
171 | // Constructor for a font. Note that the real construction is done | |
172 | // in wxDC::SetFont, when information is available about scaling etc. | |
173 | // ---------------------------------------------------------------------------- | |
174 | bool wxFont::Create( | |
175 | int nPointSize | |
176 | , int nFamily | |
177 | , int nStyle | |
178 | , int nWeight | |
179 | , bool bUnderlined | |
180 | , const wxString& rsFaceName | |
181 | , wxFontEncoding vEncoding | |
182 | ) | |
183 | { | |
184 | UnRef(); | |
185 | m_refData = new wxFontRefData( nPointSize | |
186 | ,nFamily | |
187 | ,nStyle | |
188 | ,nWeight | |
189 | ,bUnderlined | |
190 | ,rsFaceName | |
191 | ,vEncoding | |
192 | ); | |
193 | RealizeResource(); | |
194 | return TRUE; | |
195 | } // end of wxFont::Create | |
196 | ||
197 | wxFont::~wxFont() | |
198 | { | |
199 | if (wxTheFontList) | |
200 | wxTheFontList->DeleteObject(this); | |
201 | } // end of wxFont::~wxFont | |
202 | ||
203 | // ---------------------------------------------------------------------------- | |
204 | // real implementation | |
205 | // Boris' Kovalenko comments: | |
206 | // Because OS/2 fonts are associated with PS we can not create the font | |
207 | // here, but we may check that font definition is true | |
208 | // ---------------------------------------------------------------------------- | |
209 | ||
210 | bool wxFont::RealizeResource() | |
211 | { | |
212 | LONG lNumFonts = 0L; | |
213 | LONG lTemp = 0L; | |
214 | PFONTMETRICS pFM = NULL; | |
215 | ERRORID vError; | |
216 | ||
217 | if ( GetResourceHandle() ) | |
218 | { | |
219 | // VZ: the old code returned FALSE in this case, but it doesn't seem | |
220 | // to make sense because the font _was_ created | |
221 | wxLogDebug(wxT("Calling wxFont::RealizeResource() twice")); | |
222 | ||
223 | return TRUE; | |
224 | } | |
225 | ||
226 | LONG flId; | |
227 | bool bInternalPS = FALSE; // if we have to create one | |
228 | ||
229 | // | |
230 | // Now cheking | |
231 | // | |
232 | flId = 1L; | |
233 | if (!M_FONTDATA->m_hPS) | |
234 | { | |
235 | M_FONTDATA->m_hPS = ::WinGetPS(HWND_DESKTOP); | |
236 | bInternalPS = TRUE; | |
237 | } | |
238 | ||
239 | if (M_FONTDATA->m_pFM) | |
240 | { | |
241 | delete [] M_FONTDATA->m_pFM; | |
242 | M_FONTDATA->m_pFM = NULL; | |
243 | } | |
244 | // | |
245 | // Determine the number of fonts. | |
246 | // | |
247 | lNumFonts = ::GpiQueryFonts( M_FONTDATA->m_hPS | |
248 | ,QF_PUBLIC | |
249 | ,NULL | |
250 | ,&lTemp | |
251 | ,(LONG) sizeof(FONTMETRICS) | |
252 | ,NULL | |
253 | ); | |
254 | ||
255 | // | |
256 | // Allocate space for the font metrics. | |
257 | // | |
258 | pFM = new FONTMETRICS[lNumFonts + 1]; | |
259 | ||
260 | // | |
261 | // Retrieve the font metrics. | |
262 | // | |
263 | lTemp = lNumFonts; | |
264 | lTemp = ::GpiQueryFonts( M_FONTDATA->m_hPS | |
265 | ,QF_PUBLIC | |
266 | ,NULL | |
267 | ,&lTemp | |
268 | ,(LONG) sizeof(FONTMETRICS) | |
269 | ,pFM | |
270 | ); | |
271 | SetFM( pFM | |
272 | ,(int)lNumFonts | |
273 | ); | |
274 | ||
275 | wxString sVals; | |
276 | ||
277 | for (int i = 0; i < lNumFonts; i++) | |
278 | { | |
279 | sVals << "Face: " <<M_FONTDATA->m_pFM[i].szFacename | |
280 | << "Family: " <<M_FONTDATA->m_pFM[i].szFamilyname | |
281 | << " PointSize: " << M_FONTDATA->m_pFM[i].lEmHeight | |
282 | << " Height: " << M_FONTDATA->m_pFM[i].lXHeight | |
283 | ; | |
284 | sVals = ""; | |
285 | } | |
286 | M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS); | |
287 | M_FONTDATA->m_vFattrs.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed | |
288 | FATTR_FONTUSE_TRANSFORMABLE; // may be transformed | |
289 | M_FONTDATA->m_vFattrs.fsType = 0; | |
290 | M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_vFattrs.lAveCharWidth = 0; | |
291 | M_FONTDATA->m_vFattrs.idRegistry = 0; | |
292 | M_FONTDATA->m_vFattrs.lMatch = 0; | |
293 | ||
294 | M_FONTDATA->m_vFname.usSize = sizeof(FACENAMEDESC); | |
295 | M_FONTDATA->m_vFname.usWidthClass = FWIDTH_NORMAL; | |
296 | M_FONTDATA->m_vFname.usReserved = 0; | |
297 | M_FONTDATA->m_vFname.flOptions = 0; | |
298 | ||
299 | OS2SelectMatchingFontByName(); | |
300 | ||
301 | long lNumLids = ::GpiQueryNumberSetIds(M_FONTDATA->m_hPS); | |
302 | long lGpiError; | |
303 | ||
304 | // | |
305 | // First we should generate unique id | |
306 | // | |
307 | if(lNumLids ) | |
308 | { | |
309 | long alTypes[255]; | |
310 | STR8 azNames[255]; | |
311 | long alIds[255]; | |
312 | ||
313 | if(!::GpiQuerySetIds( M_FONTDATA->m_hPS | |
314 | ,lNumLids | |
315 | ,alTypes | |
316 | ,azNames | |
317 | ,alIds | |
318 | )) | |
319 | { | |
320 | if (bInternalPS) | |
321 | ::WinReleasePS(M_FONTDATA->m_hPS); | |
322 | return 0; | |
323 | } | |
324 | ||
325 | for(unsigned long LCNum = 0; LCNum < lNumLids; LCNum++) | |
326 | if(alIds[LCNum] == flId) | |
327 | ++flId; | |
328 | if(flId > 254) // wow, no id available! | |
329 | { | |
330 | if (bInternalPS) | |
331 | ::WinReleasePS(M_FONTDATA->m_hPS); | |
332 | return 0; | |
333 | } | |
334 | } | |
335 | ||
336 | // | |
337 | // Release and delete the current font | |
338 | // | |
339 | ::GpiSetCharSet(M_FONTDATA->m_hPS, LCID_DEFAULT);/* release the font before deleting */ | |
340 | ::GpiDeleteSetId(M_FONTDATA->m_hPS, 1L); /* delete the logical font */ | |
341 | ||
342 | // | |
343 | // Now build a facestring | |
344 | // | |
345 | char zFacename[128]; | |
346 | strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename); | |
347 | ||
348 | if(::GpiQueryFaceString( M_FONTDATA->m_hPS | |
349 | ,zFacename | |
350 | ,&M_FONTDATA->m_vFname | |
351 | ,FACESIZE | |
352 | ,M_FONTDATA->m_vFattrs.szFacename | |
353 | ) == GPI_ERROR) | |
354 | { | |
355 | vError = ::WinGetLastError(vHabmain); | |
356 | } | |
357 | ||
358 | strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename); | |
359 | ||
360 | if(::GpiCreateLogFont( M_FONTDATA->m_hPS | |
361 | ,NULL | |
362 | ,flId | |
363 | ,&M_FONTDATA->m_vFattrs | |
364 | ) != GPI_ERROR) | |
365 | M_FONTDATA->m_hFont = (WXHFONT)1; | |
366 | ||
367 | ||
368 | if (bInternalPS) | |
369 | { | |
370 | if(M_FONTDATA->m_hFont) | |
371 | ::GpiDeleteSetId( M_FONTDATA->m_hPS | |
372 | ,flId | |
373 | ); | |
374 | ||
375 | ::WinReleasePS(M_FONTDATA->m_hPS); | |
376 | } | |
377 | else | |
378 | ::GpiSetCharSet(M_FONTDATA->m_hPS, flId); // sets font for presentation space | |
379 | if (!M_FONTDATA->m_hFont) | |
380 | { | |
381 | wxLogLastError("CreateFont"); | |
382 | } | |
383 | M_FONTDATA->m_nFontId = flId; | |
384 | return(M_FONTDATA->m_hFont != 0); | |
385 | } // end of wxFont::RealizeResource | |
386 | ||
387 | bool wxFont::FreeResource( | |
388 | bool bForce | |
389 | ) | |
390 | { | |
391 | if (GetResourceHandle()) | |
392 | { | |
393 | M_FONTDATA->m_hFont = 0; | |
394 | ::GpiDeleteSetId( M_FONTDATA->m_hPS | |
395 | ,M_FONTDATA->m_nFontId | |
396 | ); | |
397 | return TRUE; | |
398 | } | |
399 | return FALSE; | |
400 | } // end of wxFont::FreeResource | |
401 | ||
402 | WXHANDLE wxFont::GetHFONT() const | |
403 | { | |
404 | if (!M_FONTDATA) | |
405 | return 0; | |
406 | else | |
407 | return (WXHANDLE)M_FONTDATA->m_hFont; | |
408 | } // end of wxFont::GetHFONT | |
409 | ||
410 | WXHANDLE wxFont::GetResourceHandle() | |
411 | { | |
412 | return GetHFONT(); | |
413 | } // end of wxFont::GetResourceHandle | |
414 | ||
415 | bool wxFont::IsFree() const | |
416 | { | |
417 | return (M_FONTDATA && (M_FONTDATA->m_hFont == 0)); | |
418 | } // end of wxFont::IsFree | |
419 | ||
420 | void wxFont::Unshare() | |
421 | { | |
422 | // Don't change shared data | |
423 | if ( !m_refData ) | |
424 | { | |
425 | m_refData = new wxFontRefData(); | |
426 | } | |
427 | else | |
428 | { | |
429 | wxFontRefData* ref = new wxFontRefData(*M_FONTDATA); | |
430 | UnRef(); | |
431 | m_refData = ref; | |
432 | } | |
433 | } // end of wxFont::Unshare | |
434 | ||
435 | // ---------------------------------------------------------------------------- | |
436 | // change font attribute: we recreate font when doing it | |
437 | // ---------------------------------------------------------------------------- | |
438 | ||
439 | void wxFont::SetPointSize( | |
440 | int nPointSize | |
441 | ) | |
442 | { | |
443 | Unshare(); | |
444 | ||
445 | M_FONTDATA->m_nPointSize = nPointSize; | |
446 | ||
447 | RealizeResource(); | |
448 | } // end of wxFont::SetPointSize | |
449 | ||
450 | void wxFont::SetFamily( | |
451 | int nFamily | |
452 | ) | |
453 | { | |
454 | Unshare(); | |
455 | ||
456 | M_FONTDATA->m_nFamily = nFamily; | |
457 | ||
458 | RealizeResource(); | |
459 | } // end of wxFont::SetFamily | |
460 | ||
461 | void wxFont::SetStyle( | |
462 | int nStyle | |
463 | ) | |
464 | { | |
465 | Unshare(); | |
466 | ||
467 | M_FONTDATA->m_nStyle = nStyle; | |
468 | ||
469 | RealizeResource(); | |
470 | } // end of wxFont::SetStyle | |
471 | ||
472 | void wxFont::SetWeight( | |
473 | int nWeight | |
474 | ) | |
475 | { | |
476 | Unshare(); | |
477 | ||
478 | M_FONTDATA->m_nWeight = nWeight; | |
479 | ||
480 | RealizeResource(); | |
481 | } // end of wxFont::SetWeight | |
482 | ||
483 | void wxFont::SetFaceName( | |
484 | const wxString& rsFaceName | |
485 | ) | |
486 | { | |
487 | Unshare(); | |
488 | ||
489 | M_FONTDATA->m_sFaceName = rsFaceName; | |
490 | ||
491 | RealizeResource(); | |
492 | } // end of wxFont::SetFaceName | |
493 | ||
494 | void wxFont::SetUnderlined( | |
495 | bool bUnderlined | |
496 | ) | |
497 | { | |
498 | Unshare(); | |
499 | ||
500 | M_FONTDATA->m_bUnderlined = bUnderlined; | |
501 | ||
502 | RealizeResource(); | |
503 | } // end of wxFont::SetUnderlined | |
504 | ||
505 | void wxFont::SetEncoding( | |
506 | wxFontEncoding vEncoding | |
507 | ) | |
508 | { | |
509 | Unshare(); | |
510 | ||
511 | M_FONTDATA->m_vEncoding = vEncoding; | |
512 | ||
513 | RealizeResource(); | |
514 | } // end of wxFont::SetEncoding | |
515 | ||
516 | void wxFont::SetPS( | |
517 | HPS hPS | |
518 | ) | |
519 | { | |
520 | Unshare(); | |
521 | ||
522 | M_FONTDATA->m_hPS = hPS; | |
523 | ||
524 | RealizeResource(); | |
525 | } // end of wxFont::SetPS | |
526 | ||
527 | void wxFont::SetFM( | |
528 | PFONTMETRICS pFM | |
529 | , int nNumFonts | |
530 | ) | |
531 | { | |
532 | // | |
533 | // Don't realize the font with this one | |
534 | // | |
535 | M_FONTDATA->m_pFM = pFM; | |
536 | M_FONTDATA->m_nNumFonts = nNumFonts; | |
537 | } // end of wxFont::SetFM | |
538 | ||
539 | // ---------------------------------------------------------------------------- | |
540 | // accessors | |
541 | // ---------------------------------------------------------------------------- | |
542 | ||
543 | int wxFont::GetPointSize() const | |
544 | { | |
545 | wxFontRefData* pTmp; | |
546 | ||
547 | pTmp = M_FONTDATA; | |
548 | if(pTmp) | |
549 | return pTmp->m_nPointSize; | |
550 | else | |
551 | return 10; | |
552 | } // end of wxFont::GetPointSize | |
553 | ||
554 | int wxFont::GetFamily() const | |
555 | { | |
556 | return M_FONTDATA->m_nFamily; | |
557 | } // end of wxFont::GetFamily | |
558 | ||
559 | int wxFont::GetFontId() const | |
560 | { | |
561 | return M_FONTDATA->m_nFontId; | |
562 | } // end of wxFont::GetFontId | |
563 | ||
564 | int wxFont::GetStyle() const | |
565 | { | |
566 | return M_FONTDATA->m_nStyle; | |
567 | } // end of wxFont::GetStyle | |
568 | ||
569 | int wxFont::GetWeight() const | |
570 | { | |
571 | return M_FONTDATA->m_nWeight; | |
572 | } | |
573 | ||
574 | bool wxFont::GetUnderlined() const | |
575 | { | |
576 | return M_FONTDATA->m_bUnderlined; | |
577 | } // end of wxFont::GetUnderlined | |
578 | ||
579 | wxString wxFont::GetFaceName() const | |
580 | { | |
581 | wxString sStr; | |
582 | ||
583 | if ( M_FONTDATA ) | |
584 | sStr = M_FONTDATA->m_sFaceName ; | |
585 | return sStr; | |
586 | } // end of wxFont::GetFaceName | |
587 | ||
588 | wxFontEncoding wxFont::GetEncoding() const | |
589 | { | |
590 | return M_FONTDATA->m_vEncoding; | |
591 | } // end of wxFont::GetEncoding | |
592 | ||
593 | HPS wxFont::GetPS() const | |
594 | { | |
595 | return M_FONTDATA->m_hPS; | |
596 | } // end of wxFont::GetPS | |
597 | ||
598 | void wxFont::OS2SelectMatchingFontByName() | |
599 | { | |
600 | int i; | |
601 | int nDiff0; | |
602 | int nDiff; | |
603 | int nIs; | |
604 | int nIndex; | |
605 | int nMinDiff; | |
606 | int nMinDiff0; | |
607 | int nApirc; | |
608 | int anDiff[16]; | |
609 | int anMinDiff[16]; | |
610 | STR8 zFn; | |
611 | char zFontFaceName[FACESIZE]; | |
612 | wxString sFaceName; | |
613 | USHORT usWeightClass; | |
614 | int fsSelection = 0; | |
615 | ||
616 | nMinDiff0 = 0xf000; | |
617 | for(i = 0;i < 16; i++) | |
618 | anMinDiff[i] = nMinDiff0; | |
619 | ||
620 | switch (GetFamily()) | |
621 | { | |
622 | case wxSCRIPT: | |
623 | sFaceName = wxT("Script"); | |
624 | break; | |
625 | ||
626 | case wxDECORATIVE: | |
627 | case wxROMAN: | |
628 | sFaceName = wxT("Times New Roman"); | |
629 | break; | |
630 | ||
631 | case wxTELETYPE: | |
632 | case wxMODERN: | |
633 | sFaceName = wxT("Courier") ; | |
634 | break; | |
635 | ||
636 | case wxSWISS: | |
637 | sFaceName = wxT("WarpSans") ; | |
638 | break; | |
639 | ||
640 | case wxDEFAULT: | |
641 | default: | |
642 | sFaceName = wxT("Helv") ; | |
643 | } | |
644 | ||
645 | switch (GetWeight()) | |
646 | { | |
647 | default: | |
648 | wxFAIL_MSG(_T("unknown font weight")); | |
649 | // fall through | |
650 | usWeightClass = FWEIGHT_DONT_CARE; | |
651 | break; | |
652 | ||
653 | case wxNORMAL: | |
654 | usWeightClass = FWEIGHT_NORMAL; | |
655 | break; | |
656 | ||
657 | case wxLIGHT: | |
658 | usWeightClass = FWEIGHT_LIGHT; | |
659 | break; | |
660 | ||
661 | case wxBOLD: | |
662 | usWeightClass = FWEIGHT_BOLD; | |
663 | break; | |
664 | ||
665 | case wxFONTWEIGHT_MAX: | |
666 | usWeightClass = FWEIGHT_ULTRA_BOLD; | |
667 | break; | |
668 | } | |
669 | M_FONTDATA->m_vFname.usWeightClass = usWeightClass; | |
670 | ||
671 | switch (GetStyle()) | |
672 | { | |
673 | case wxITALIC: | |
674 | case wxSLANT: | |
675 | fsSelection = FM_SEL_ITALIC; | |
676 | M_FONTDATA->m_vFname.flOptions = FTYPE_ITALIC; | |
677 | break; | |
678 | ||
679 | default: | |
680 | wxFAIL_MSG(wxT("unknown font slant")); | |
681 | // fall through | |
682 | ||
683 | case wxNORMAL: | |
684 | fsSelection = 0; | |
685 | break; | |
686 | } | |
687 | ||
688 | wxStrncpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName)); | |
689 | M_FONTDATA->m_nPointSize = GetPointSize(); | |
690 | nIndex = 0; | |
691 | for(i = 0, nIs = 0; i < M_FONTDATA->m_nNumFonts; i++) | |
692 | { | |
693 | // Debug code | |
694 | int nPointSize = M_FONTDATA->m_nPointSize; | |
695 | int nEmHeight = 0; | |
696 | int nXHeight = 0; | |
697 | anDiff[0] = wxGpiStrcmp(M_FONTDATA->m_pFM[i].szFamilyname, zFontFaceName); | |
698 | anDiff[1] = abs(M_FONTDATA->m_pFM[i].lEmHeight - M_FONTDATA->m_nPointSize); | |
699 | anDiff[2] = abs(M_FONTDATA->m_pFM[i].usWeightClass - usWeightClass); | |
700 | anDiff[3] = abs((M_FONTDATA->m_pFM[i].fsSelection & 0x2f) - fsSelection); | |
701 | if(anDiff[0] == 0) | |
702 | { | |
703 | nEmHeight = (int)M_FONTDATA->m_pFM[i].lEmHeight; | |
704 | nXHeight =(int)M_FONTDATA->m_pFM[i].lXHeight; | |
705 | if( (nIs & 0x01) == 0) | |
706 | { | |
707 | nIs = 1; | |
708 | nIndex = i; | |
709 | anMinDiff[1] = anDiff[1]; | |
710 | anMinDiff[2] = anDiff[2]; | |
711 | anMinDiff[3] = anDiff[3]; | |
712 | } | |
713 | else if(anDiff[3] < anMinDiff[3]) | |
714 | { | |
715 | nIndex = i; | |
716 | anMinDiff[3] = anDiff[3]; | |
717 | } | |
718 | else if(anDiff[2] < anMinDiff[2]) | |
719 | { | |
720 | nIndex = i; | |
721 | anMinDiff[2] = anDiff[2]; | |
722 | } | |
723 | else if(anDiff[1] < anMinDiff[1]) | |
724 | { | |
725 | nIndex = i; | |
726 | anMinDiff[1] = anDiff[1]; | |
727 | } | |
728 | anMinDiff[0] = 0; | |
729 | } | |
730 | else if(anDiff[0] < anMinDiff[0]) | |
731 | { | |
732 | nIs = 2; | |
733 | nIndex = i; | |
734 | anMinDiff[3] = anDiff[3]; | |
735 | anMinDiff[2] = anDiff[2]; | |
736 | anMinDiff[1] = anDiff[1]; | |
737 | anMinDiff[0] = anDiff[0]; | |
738 | } | |
739 | else if(anDiff[0] == anMinDiff[0]) | |
740 | { | |
741 | if(anDiff[3] < anMinDiff[3]) | |
742 | { | |
743 | nIndex = i; | |
744 | anMinDiff[3] = anDiff[3]; | |
745 | nIs = 2; | |
746 | } | |
747 | else if(anDiff[2] < anMinDiff[2]) | |
748 | { | |
749 | nIndex = i; | |
750 | anMinDiff[2] = anDiff[2]; | |
751 | nIs = 2; | |
752 | } | |
753 | else if(anDiff[1] < anMinDiff[1]) | |
754 | { | |
755 | nIndex = i; | |
756 | anMinDiff[1] = anDiff[1]; | |
757 | nIs = 2; | |
758 | } | |
759 | } | |
760 | } | |
761 | ||
762 | M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS); // sets size of structure | |
763 | M_FONTDATA->m_vFattrs.fsSelection = M_FONTDATA->m_pFM[nIndex].fsSelection; // uses default selection | |
764 | M_FONTDATA->m_vFattrs.lMatch = M_FONTDATA->m_pFM[nIndex].lMatch; // force match | |
765 | M_FONTDATA->m_vFattrs.idRegistry = M_FONTDATA->m_pFM[nIndex].idRegistry; // uses default registry | |
766 | M_FONTDATA->m_vFattrs.usCodePage = M_FONTDATA->m_pFM[nIndex].usCodePage; // code-page | |
767 | if(M_FONTDATA->m_pFM[nIndex].lMatch) | |
768 | { | |
769 | M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_pFM[nIndex].lMaxBaselineExt; // requested font height | |
770 | M_FONTDATA->m_vFattrs.lAveCharWidth = M_FONTDATA->m_pFM[nIndex].lAveCharWidth ; // requested font width | |
771 | } | |
772 | else | |
773 | { | |
774 | M_FONTDATA->m_vFattrs.lMaxBaselineExt = 0; | |
775 | M_FONTDATA->m_vFattrs.lAveCharWidth = 0; | |
776 | } | |
777 | M_FONTDATA->m_vFattrs.fsType = 0;// pfm->fsType; /* uses default type */ | |
778 | M_FONTDATA->m_vFattrs.fsFontUse = 0; | |
779 | ||
780 | wxStrcpy(M_FONTDATA->m_vFattrs.szFacename, M_FONTDATA->m_pFM[nIndex].szFacename); | |
781 | // Debug | |
782 | strcpy(zFontFaceName, M_FONTDATA->m_pFM[nIndex].szFacename); | |
783 | strcpy(zFontFaceName, M_FONTDATA->m_vFattrs.szFacename); | |
784 | ||
785 | if(usWeightClass >= FWEIGHT_BOLD) | |
786 | M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_BOLD; | |
787 | if(GetUnderlined()) | |
788 | M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_UNDERSCORE; | |
789 | if(fsSelection & FM_SEL_ITALIC) | |
790 | M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_ITALIC; | |
791 | } | |
792 | ||
793 | ||
794 |