Leaked source code of windows server 2003
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.

4674 lines
137 KiB

  1. /******************************************************************************
  2. Source File: Font Viewer.CPP
  3. This implements the various classes that make up the font editor for the
  4. studio. The editor is basically a property sheet with a sizable collection
  5. of pages.
  6. Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved.
  7. A Pretty Penny Enterprises Production.
  8. Change History:
  9. 03-05-1997 Bob_Kjelgaard@Prodigy.Net
  10. NOTES: an FWORD is a short int
  11. The PANOSE structure describes the PANOSE font-classification values for a TrueType font.
  12. These characteristics are then used to associate the font with other fonts of similar appearance but different names.
  13. typedef struct tagPANOSE { // pnse
  14. BYTE bFamilyType;
  15. BYTE bSerifStyle;
  16. BYTE bWeight;
  17. BYTE bProportion;
  18. BYTE bContrast;
  19. BYTE bStrokeVariation;
  20. BYTE bArmStyle;
  21. BYTE bLetterform;
  22. BYTE bMidline;
  23. BYTE bXHeight;
  24. } PANOSE
  25. ******************************************************************************/
  26. #include "StdAfx.H"
  27. #include <gpdparse.h>
  28. #include "MiniDev.H"
  29. #include "ChildFrm.H" // Definition of Tool Tips Property Page class
  30. #include "comctrls.h"
  31. #include <stdlib.h>
  32. #include "FontView.H" // FontView.H also includes comctrls.h
  33. #include "rcfile.h"
  34. /******************************************************************************
  35. CFontViewer class- this is the guy who owns the overall control of the view,
  36. although he wisely delegates the work to the MFC Property Sheet class and the
  37. other view classes. I should be so wise.
  38. ******************************************************************************/
  39. IMPLEMENT_DYNCREATE(CFontViewer, CView)
  40. CFontViewer::CFontViewer() {
  41. }
  42. CFontViewer::~CFontViewer() {
  43. }
  44. BEGIN_MESSAGE_MAP(CFontViewer, CView)
  45. //{{AFX_MSG_MAP(CFontViewer)
  46. ON_WM_DESTROY()
  47. //}}AFX_MSG_MAP
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CFontViewer drawing
  51. void CFontViewer::OnDraw(CDC* pDC) { CDocument* pDoc = GetDocument();}
  52. CFontInfo * gpCFontInfo;
  53. /******************************************************************************
  54. CFontViewer::OnInitialUpdate
  55. This handles the initial update of the view, meaning all of the background
  56. noise of creation is essentially complete.
  57. I initialize the property pages by pointing each to the underlying CFontInfo,
  58. add them to the property sheet as needed, then create the sheet, position it
  59. so it aligns with the view, then adjust the owning frame's size and style so
  60. that everything looks like it really belongs where it is.
  61. ******************************************************************************/
  62. void CFontViewer::OnInitialUpdate()
  63. {
  64. CFontInfo *pcfi = GetDocument()->Font();
  65. gpCFontInfo = pcfi;
  66. if (pcfi->Name().IsEmpty())
  67. {
  68. pcfi->Rename(GetDocument()->GetTitle());
  69. GetDocument()->SetModifiedFlag(FALSE); // Rename sets it
  70. }
  71. m_cps.Construct(IDR_MAINFRAME, this);
  72. // Each property page needs a pointer to the fontinfo class
  73. m_cfhp.Init(pcfi, (CFontInfoContainer*) GetDocument(), this);
  74. m_cfimp.Init(pcfi);
  75. m_cfemp.Init(pcfi);
  76. m_cfwp.Init(pcfi);
  77. m_cfkp.Init(pcfi);
  78. // Add each property page to the property sheet
  79. m_cps.AddPage(&m_cfhp);
  80. m_cps.AddPage(&m_cfimp);
  81. m_cps.AddPage(&m_cfemp);
  82. m_cps.AddPage(&m_cfwp);
  83. m_cps.AddPage(&m_cfkp);
  84. // Create the property sheet
  85. m_cps.Create(this, WS_CHILD, WS_EX_CLIENTEDGE);
  86. // Get the bounding rectangle, and use it to set the frame size,
  87. // after first using it to align the origin with this view.
  88. CRect crPropertySheet;
  89. m_cps.GetWindowRect(crPropertySheet);
  90. // Position property sheet within the child frame
  91. crPropertySheet -= crPropertySheet.TopLeft();
  92. m_cps.MoveWindow(crPropertySheet, FALSE);
  93. GetParentFrame()->CalcWindowRect(crPropertySheet);
  94. GetParentFrame()->SetWindowPos(NULL, 0, 0, crPropertySheet.Width(),
  95. crPropertySheet.Height(),
  96. SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
  97. CView::OnInitialUpdate();
  98. m_cps.ShowWindow(SW_SHOWNA);
  99. // GetParentFrame() -> ShowWindow(SW_SHOW);
  100. }
  101. /******************************************************************************
  102. CFontViewer::OnActivateView
  103. For some reason, the property sheet does not get the focus when the frame is
  104. activated (probably the view class takes it away from us). This little gem
  105. makes sure keyboard users don't get miffed by this.
  106. ******************************************************************************/
  107. void CFontViewer::OnActivateView(BOOL bActivate, CView* pcvActivate,CView* pcvDeactivate)
  108. {
  109. // In case the base class does anything else of value, pass it on...
  110. CView::OnActivateView(bActivate, pcvActivate, pcvDeactivate);
  111. if (bActivate)
  112. m_cps.SetFocus();
  113. }
  114. /******************************************************************************
  115. CFontViewer::OnDestroy
  116. This override is used to inform the embedded font that we are being
  117. destroyed. If we were created by the font, then it will NULL its pointer
  118. to us, and won't try to destroy us when it is destroyed.
  119. ******************************************************************************/
  120. void CFontViewer::OnDestroy()
  121. {
  122. CView::OnDestroy();
  123. if (GetDocument() -> Font())
  124. GetDocument() -> Font() -> OnEditorDestroyed();
  125. }
  126. /******************************************************************************
  127. CFontViewer::ValidateUFM
  128. This routine manages UFM field validation. The data to be validated is in
  129. the controls on the property pages and in various other member variables
  130. because this is the data the user has just modified. It is the most up to
  131. data. Data is not saved back into the CFontInfo class until the user closes
  132. the document (essentially, the UFM Editor) and says to save its contents.
  133. Each page function is called to perform the validation on the fields diplayed
  134. on its page. If a check fails and the user wants to fix the problem, true
  135. is returned. Otherwise, false is returned.
  136. Note:
  137. Not every field in the UFM is validated. Only those specified by Ganesh
  138. Pandey, MS Printer Driver Development team, are checked. The fields are
  139. listed in the Minidriver Development Tool Work List revision 5. See the
  140. ValidateUFMFields() routines in each page clase for more details.
  141. ******************************************************************************/
  142. bool CFontViewer::ValidateSelectedUFMDataFields()
  143. {
  144. // Validate data on the headers page.
  145. if (m_cfhp.ValidateUFMFields()) {
  146. m_cps.SetActivePage(&m_cfhp) ;
  147. m_cfhp.m_cfelcUniDrv.SetFocus() ;
  148. return true ;
  149. } ;
  150. // Validate data on the IFIMetrics page.
  151. if (m_cfimp.ValidateUFMFields()) {
  152. m_cps.SetActivePage(&m_cfimp) ;
  153. return true ;
  154. } ;
  155. // Validate data on the ExtMetrics page.
  156. if (m_cfemp.ValidateUFMFields()) {
  157. m_cps.SetActivePage(&m_cfemp) ;
  158. m_cfemp.m_cfelcExtMetrics.SetFocus() ;
  159. return true ;
  160. } ;
  161. // Validate data on the widths page.
  162. if (m_cfwp.ValidateUFMFields()) {
  163. m_cps.SetActivePage(&m_cfwp) ;
  164. return true ;
  165. } ;
  166. // Validate data on the kerning pairs page.
  167. if (m_cfkp.ValidateUFMFields()) {
  168. m_cps.SetActivePage(&m_cfkp) ;
  169. return true ;
  170. } ;
  171. // All checks passed or the user doesn't want to fix the problems...
  172. return false ;
  173. }
  174. /******************************************************************************
  175. CFontViewer::SaveEditorDataInUFM
  176. Manage saving all editor data. By "save", I mean copy all of the data
  177. collected in the UFM Editor's controls back into the correct variables and
  178. structures in the CFontInfo class instance associated with this instance of
  179. the UFM Editor. See CFontInfoContainer::OnSaveDocument() for more info.
  180. Return true if there was a problem saving the data. Otherwise, return false.
  181. ******************************************************************************/
  182. bool CFontViewer::SaveEditorDataInUFM()
  183. {
  184. // Save data on the headers page.
  185. if (m_cfhp.SavePageData())
  186. return true ;
  187. // Save data on the IFIMetrics page.
  188. if (m_cfimp.SavePageData())
  189. return true ;
  190. // Save data on the ExtMetrics page.
  191. if (m_cfemp.SavePageData())
  192. return true ;
  193. // Save data on the widths page.
  194. if (m_cfwp.SavePageData())
  195. return true ;
  196. // Save data on the kerning pairs page.
  197. if (m_cfkp.SavePageData())
  198. return true ;
  199. // All went well so...
  200. return false ;
  201. }
  202. /******************************************************************************
  203. CFontViewer::HandleCPGTTChange
  204. ******************************************************************************/
  205. void CFontViewer::HandleCPGTTChange(bool bgttidchanged)
  206. {
  207. // Get a ptr to the doc class and a pointer to the font class.
  208. CFontInfoContainer* pcfic = GetDocument() ;
  209. CFontInfo *pcfi = pcfic->Font();
  210. // Save the UFM. Bail if this doesn't work for some reason.
  211. // If the UFM was loaded stand alone and there is a GTT to free, do it.
  212. // (Code pages loaded as GTTs are not freed here. That is done at program
  213. // exit.) Always clear the GTT pointer.
  214. if (!pcfic->m_bEmbedded && pcfi) {
  215. if (pcfi->m_pcgmTranslation && pcfi->m_lGlyphSetDataRCID != 0)
  216. delete pcfi->m_pcgmTranslation ;
  217. } ;
  218. pcfi->m_pcgmTranslation = NULL ;
  219. // If the UFM was loaded from a workspace, try to use the workspace data to
  220. // find and load a pointer to the new GTT and finish loading the font.
  221. if (pcfic->m_bEmbedded) {
  222. CDriverResources* pcdr = (CDriverResources*) pcfi->GetWorkspace() ;
  223. pcdr->LinkAndLoadFont(*pcfi, false, true ) ; // raid 0003
  224. // If the UFM was loaded stand alone the first time, reload it the same way
  225. // and let the load routine handle finding the GTT info.
  226. } else
  227. pcfi->Load(false) ;
  228. // If the widths page has been initialized already, reload the widths list
  229. // control with the updated data and reset the associated member variables.
  230. pcfi->CheckReloadWidths() ;
  231. pcfi->SetRCIDChanged(false) ;
  232. // check the widthtable existence instead initializ of the m_clcView
  233. // if (m_cfwp.m_bInitDone) { raid 0003
  234. if (m_cfwp.m_bInitDone) {
  235. m_cfwp.InitMemberVars() ;
  236. m_cfwp.m_clcView.DeleteAllItems() ;
  237. pcfi->FillWidths(m_cfwp.m_clcView) ;
  238. m_cfwp.m_clcView.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED,
  239. LVIS_SELECTED | LVIS_FOCUSED) ;
  240. } ;
  241. // If the kerning page has been initialized already, reload the kerning list
  242. // control with the updated data and reset the associated member variables.
  243. if (m_cfkp.m_bInitDone) {
  244. m_cfkp.InitMemberVars() ;
  245. m_cfkp.m_clcView.DeleteAllItems() ;
  246. pcfi->FillKern(m_cfkp.m_clcView) ;
  247. pcfi->MakeKernCopy() ;
  248. } ;
  249. // Check the state of the widths and kerning tables. Then display the
  250. // results.
  251. CWidthKernCheckResults cwkcr(pcfi) ;
  252. cwkcr.DoModal() ;
  253. }
  254. /******************************************************************************
  255. CheckUFMString, CheckUFMGrter0, CheckUFMNotEq0, CheckUFMBool
  256. These 4 routines are used to optimize UFM validation checks. Each one does
  257. a different kind of check. If the check fails, an error message is displayed.
  258. If the user wants to fix the problem, the routine will select the appropriate
  259. field and return true. Otherwise, they return false.
  260. CheckUFMBool is different in one respect. The comparison is maded in the
  261. calling function and the result is passed to CheckUFMBool as a parameter.
  262. ******************************************************************************/
  263. bool CheckUFMString(CString& csdata, CString& cspage, LPTSTR pstrfieldname,
  264. int nfld, CFullEditListCtrl& cfelc)
  265. {
  266. csdata.TrimLeft() ;
  267. csdata.TrimRight() ;
  268. if (csdata.GetLength() == 0) {
  269. CString csmsg ;
  270. csmsg.Format(IDS_EmptyStrError, cspage, pstrfieldname) ;
  271. if (AfxMessageBox(csmsg, MB_YESNO+MB_ICONEXCLAMATION) == IDYES) {
  272. cfelc.SingleSelect(nfld) ;
  273. cfelc.SetFocus() ;
  274. return true ;
  275. } ;
  276. } ;
  277. return false ;
  278. }
  279. bool CheckUFMGrter0(CString& csdata, CString& cspage, LPTSTR pstrfieldname,
  280. int nfld, CFullEditListCtrl& cfelc)
  281. {
  282. if (atoi(csdata) <= 0) {
  283. CString csmsg ;
  284. csmsg.Format(IDS_LessEqZeroError, cspage, pstrfieldname) ;
  285. if (AfxMessageBox(csmsg, MB_YESNO+MB_ICONEXCLAMATION) == IDYES) {
  286. cfelc.SingleSelect(nfld) ;
  287. cfelc.SetFocus() ;
  288. return true ;
  289. } ;
  290. } ;
  291. return false ;
  292. }
  293. bool CheckUFMNotEq0(int ndata, CString& cspage, LPTSTR pstrfieldname,
  294. int nfld, CFullEditListCtrl& cfelc)
  295. {
  296. if (ndata == 0) {
  297. CString csmsg ;
  298. csmsg.Format(IDS_EqualsZeroError, cspage, pstrfieldname) ;
  299. if (AfxMessageBox(csmsg, MB_YESNO+MB_ICONEXCLAMATION) == IDYES) {
  300. cfelc.SingleSelect(nfld) ;
  301. cfelc.SetFocus() ;
  302. return true ;
  303. } ;
  304. } ;
  305. return false ;
  306. }
  307. bool CheckUFMBool(bool bcompres, CString& cspage, LPTSTR pstrfieldname,
  308. int nfld, CFullEditListCtrl& cfelc, int nerrorid)
  309. {
  310. if (bcompres) {
  311. CString csmsg ;
  312. csmsg.Format(nerrorid, cspage, pstrfieldname) ;
  313. if (AfxMessageBox(csmsg, MB_YESNO+MB_ICONEXCLAMATION) == IDYES) {
  314. cfelc.SingleSelect(nfld) ;
  315. cfelc.SetFocus() ;
  316. return true ;
  317. } ;
  318. } ;
  319. return false ;
  320. }
  321. /******************************************************************************
  322. CFontWidthsPage property page class
  323. This class handles the UFM editor Character Widths page. It is derived from
  324. the Tool Tip Page class. The page consists of a list view control in which
  325. the code points and their associated widths are displayed.
  326. ******************************************************************************/
  327. /******************************************************************************
  328. CFontWidthsPage::Sort(LPARAM lp1, LPARAM lp2, LPARAM lp3)
  329. This is a private static member function- a callback for sorting the list.
  330. The first two parameters are the LPARAM members of two list view items- in
  331. this case, the indices of two code points. The final one is supplied by the
  332. caller of the sort routine. In this case, it is a pointer to the caller.
  333. Handling it is trivial- dereference the this pointer, and let the private
  334. member function for sorting handle it.
  335. ******************************************************************************/
  336. int CALLBACK CFontWidthsPage::Sort(LPARAM lp1, LPARAM lp2, LPARAM lp3) {
  337. CFontWidthsPage *pcfwp = (CFontWidthsPage *) lp3;
  338. _ASSERT(pcfwp);
  339. return pcfwp -> Sort(lp1, lp2);
  340. }
  341. /******************************************************************************
  342. CFontWidthsPage::Sort(unsigned id1, unsigned id2)
  343. This is a private member function which compares the two glyph handles at the
  344. two indices given by the established sort criteria.
  345. It returns negative for 1 < 2, positive for 1 > 2, and 0 for 1 = 2- pretty
  346. standard stuff.
  347. The sort column member determines the order of precedence in which the
  348. sorting is to be done, while the SortDescending member is a bitfield showing
  349. the sort direction in each column.
  350. *******************************************************************************/
  351. int CFontWidthsPage::Sort(UINT_PTR id1, UINT_PTR id2) {
  352. // If the Primnary sort is by widths- weed it out first.
  353. if (!m_iSortColumn)
  354. switch (m_pcfi -> CompareWidths((unsigned)id1, (unsigned)id2)) {
  355. case CFontInfo::More:
  356. return (m_bSortDescending & 1) ? -1 : 1;
  357. case CFontInfo::Less:
  358. return (m_bSortDescending & 1) ? 1 : -1;
  359. }
  360. // Sort is by Unicode point- this is always well-ordered
  361. // Furthermore, the glyph handles are always in ascending order, making
  362. // This test trivial.
  363. return (!(m_bSortDescending & 2) ^ (id1 < id2)) ? 1 : -1;
  364. }
  365. CFontWidthsPage::CFontWidthsPage() : CToolTipPage(CFontWidthsPage::IDD)
  366. {
  367. //{{AFX_DATA_INIT(CFontWidthsPage)
  368. // NOTE: the ClassWizard will add member initialization here
  369. //}}AFX_DATA_INIT
  370. m_bInitDone = false;
  371. m_uHelpID = HID_BASE_RESOURCE + IDR_FONT_VIEWER ;
  372. InitMemberVars() ;
  373. }
  374. /******************************************************************************
  375. CFontWidthsPage::InitMemberVars
  376. Initialize the member variables that must be initialized both during
  377. construction and when the UFM is reloaded because of a GTT or CP change.
  378. ******************************************************************************/
  379. void CFontWidthsPage::InitMemberVars()
  380. {
  381. m_bSortDescending = 0;
  382. m_iSortColumn = 1;
  383. }
  384. CFontWidthsPage::~CFontWidthsPage() {
  385. }
  386. void CFontWidthsPage::DoDataExchange(CDataExchange* pDX) {
  387. CPropertyPage::DoDataExchange(pDX);
  388. //{{AFX_DATA_MAP(CFontWidthsPage)
  389. DDX_Control(pDX, IDC_CharacterWidths, m_clcView);
  390. //}}AFX_DATA_MAP
  391. }
  392. /******************************************************************************
  393. CFontWidthsPage::OnSetActive
  394. This member will be called by the framework when the page is made active.
  395. The base class gets this first, and it will initialize everything the first
  396. time.
  397. This is here to update the view on subsequent activations, so we can
  398. seamlessly handle changes from fixed to variable pitch and back.
  399. ******************************************************************************/
  400. BOOL CFontWidthsPage::OnSetActive() {
  401. if (!CToolTipPage::OnSetActive())
  402. return FALSE;
  403. // IsVariableWidth is either 0 or 1, so == is safe, here
  404. if (m_pcfi -> IsVariableWidth() == !!m_clcView.GetItemCount())
  405. return TRUE; // Everything is copacetic
  406. if (m_clcView.GetItemCount())
  407. m_clcView.DeleteAllItems();
  408. else
  409. m_pcfi -> FillWidths(m_clcView);
  410. m_clcView.EnableWindow(m_pcfi -> IsVariableWidth());
  411. return TRUE;
  412. }
  413. BEGIN_MESSAGE_MAP(CFontWidthsPage, CToolTipPage)
  414. //{{AFX_MSG_MAP(CFontWidthsPage)
  415. ON_NOTIFY(LVN_ENDLABELEDIT, IDC_CharacterWidths, OnEndlabeleditCharacterWidths)
  416. ON_NOTIFY(LVN_COLUMNCLICK, IDC_CharacterWidths, OnColumnclickCharacterWidths)
  417. ON_NOTIFY(LVN_KEYDOWN, IDC_CharacterWidths, OnKeydownCharacterWidths)
  418. //}}AFX_MSG_MAP
  419. END_MESSAGE_MAP()
  420. /////////////////////////////////////////////////////////////////////////////
  421. // CFontWidthsPage message handlers
  422. /******************************************************************************
  423. CFontWidthsPage::OnInitDialog
  424. This member function initializes the list view and fills it with the font
  425. width information. Before doing this, check to see if the font's width info
  426. should be reloaded. (See CFontInfo::CheckReloadWidths() for more info.)
  427. ******************************************************************************/
  428. BOOL CFontWidthsPage::OnInitDialog()
  429. {
  430. CToolTipPage::OnInitDialog();
  431. m_pcfi->CheckReloadWidths() ; // Update font width info when necessary
  432. CString csWork;
  433. csWork.LoadString(IDS_WidthColumn0);
  434. m_clcView.InsertColumn(0, csWork, LVCFMT_CENTER,
  435. m_clcView.GetStringWidth(csWork) << 1, 0);
  436. csWork.LoadString(IDS_WidthColumn1);
  437. m_clcView.InsertColumn(1, csWork, LVCFMT_CENTER,
  438. m_clcView.GetStringWidth(csWork) << 1, 1);
  439. m_pcfi -> FillWidths(m_clcView);
  440. m_clcView.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED,
  441. LVIS_SELECTED | LVIS_FOCUSED);
  442. m_bInitDone = true ;
  443. return TRUE;
  444. }
  445. /******************************************************************************
  446. CFontWidthsPage::OnEndlabeleditCharacterWidths
  447. This is where we find out the user actually wanted to change the width of a
  448. character. So, not too surprisingly, we do just that (and also update the
  449. maximum and average widths if this isn't a DBCS font).
  450. ******************************************************************************/
  451. void CFontWidthsPage::OnEndlabeleditCharacterWidths(NMHDR* pnmh, LRESULT* plr)
  452. {
  453. LV_DISPINFO* plvdi = (LV_DISPINFO*) pnmh;
  454. *plr = 0; // Assume failure
  455. if (!plvdi -> item.pszText) // Editing canceled?
  456. return;
  457. // Get and trim the new width string.
  458. CString csNew(plvdi -> item.pszText);
  459. csNew.TrimRight();
  460. csNew.TrimLeft();
  461. // Complain if the new width contains invalid characters.
  462. if (csNew.SpanIncluding("1234567890").GetLength() != csNew.GetLength()) {
  463. AfxMessageBox(IDS_InvalidNumberFormat);
  464. return;
  465. }
  466. // Do not update the CFontInfo class now anymore. This should be done
  467. // later. We should mark the class as having changed so that we are
  468. // prompted to save this data later.
  469. //m_pcfi -> SetWidth(plvdi -> item.iItem, (WORD) atoi(csNew));
  470. m_pcfi -> Changed() ;
  471. *plr = TRUE;
  472. }
  473. /******************************************************************************
  474. CFontWidthsPage::OnColumnClickCharacterWidths
  475. This little ditty tells us one of the column headers was clicked. We
  476. obligingly either change sort direction or precednce to match, and then sort
  477. the list.
  478. ******************************************************************************/
  479. void CFontWidthsPage::OnColumnclickCharacterWidths(NMHDR* pnmh, LRESULT* plr) {
  480. NM_LISTVIEW* pnmlv = (NM_LISTVIEW*) pnmh;
  481. if (m_iSortColumn == pnmlv -> iSubItem)
  482. m_bSortDescending ^= 1 << m_iSortColumn; // Flip sort direction
  483. else
  484. m_iSortColumn = pnmlv -> iSubItem;
  485. m_clcView.SortItems(Sort, (LPARAM) this); // Sort the list!
  486. *plr = 0;
  487. }
  488. /******************************************************************************
  489. CFontWidthsPage::OnKeydownCharacterWidths
  490. I'd hoped to do thiw when ENTER was pressed, but finding out which class is
  491. eating the keystroke took too long. Here, we look for F2 as the key to
  492. signal the need to edit the width of interest.
  493. Pretty straightforward- find out who has the focus and is selected, and edit
  494. their label.
  495. ******************************************************************************/
  496. void CFontWidthsPage::OnKeydownCharacterWidths(NMHDR* pnmh, LRESULT* plr) {
  497. LV_KEYDOWN * plvkd = (LV_KEYDOWN *) pnmh;
  498. *plr = 0;
  499. if (plvkd -> wVKey != VK_F2)
  500. return;
  501. int idItem = m_clcView.GetNextItem(-1, LVIS_FOCUSED | LVIS_SELECTED);
  502. if (idItem == -1)
  503. return;
  504. CEdit *pce = m_clcView.EditLabel(idItem);
  505. if (pce)
  506. pce -> ModifyStyle(0, ES_NUMBER);
  507. }
  508. /******************************************************************************
  509. CFontWidthsPage::ValidateUFMFields
  510. Validate all specified fields managed by this page. Return true if the user
  511. wants to leave the UFM Editor open so that he can fix any problem. Otherwise,
  512. return true.
  513. ******************************************************************************/
  514. bool CFontWidthsPage::ValidateUFMFields()
  515. {
  516. // If the page was never initialize, its contents could not have changed
  517. // so no validation is needed in this case.
  518. if (!m_bInitDone)
  519. return false ;
  520. // Only verify widths if this is a variable pitch font.
  521. if (!m_pcfi->IsVariableWidth())
  522. return false ;
  523. // If there are no widths, there is nothing to validate.
  524. int numitems = m_clcView.GetItemCount() ;
  525. if (numitems == 0)
  526. return false ;
  527. // Loop through each width
  528. LV_ITEM lvi ;
  529. lvi.mask = LVIF_TEXT ;
  530. lvi.iSubItem = 0 ;
  531. char acitemtext[16] ;
  532. lvi.pszText = acitemtext ;
  533. lvi.cchTextMax = 15 ;
  534. CString csmsg ;
  535. for (int n = 0 ; n < numitems ; n++) {
  536. // Get info about the item
  537. lvi.iItem = n ;
  538. m_clcView.GetItem(&lvi) ;
  539. // Make sure each width is > 0.
  540. if (atoi(lvi.pszText) <= 0) {
  541. csmsg.Format(IDS_BadWidth, n) ;
  542. if (AfxMessageBox(csmsg, MB_YESNO+MB_ICONEXCLAMATION) == IDYES) {
  543. m_clcView.SetItemState(n, LVIS_SELECTED | LVIS_FOCUSED,
  544. LVIS_SELECTED | LVIS_FOCUSED) ;
  545. m_clcView.EnsureVisible(n, false) ;
  546. m_clcView.SetFocus() ;
  547. return true ;
  548. } ;
  549. } ;
  550. } ;
  551. // All tests passed or the user doesn't want to fix them so...
  552. return false ;
  553. }
  554. /******************************************************************************
  555. CFontWidthsPage::SavePageData
  556. Save the data in the widths page back into the CFontInfo class instance that
  557. was used to load this page. See CFontInfoContainer::OnSaveDocument() for
  558. more info.
  559. Return true if there was a problem saving the data. Otherwise, return false.
  560. ******************************************************************************/
  561. bool CFontWidthsPage::SavePageData()
  562. {
  563. // If the page was not initialized, nothing code have changed so do nothing.
  564. if (!m_bInitDone)
  565. return false ;
  566. // If there are no widths, there is nothing to save.
  567. int numitems = m_clcView.GetItemCount() ;
  568. if (numitems == 0)
  569. return false ;
  570. // Prepare to save the widths
  571. LV_ITEM lvi ;
  572. lvi.mask = LVIF_TEXT ;
  573. lvi.iSubItem = 0 ;
  574. char acitemtext[16] ;
  575. lvi.pszText = acitemtext ;
  576. lvi.cchTextMax = 15 ;
  577. numitems-- ;
  578. // Loop through each width
  579. for (int n = 0 ; n <= numitems ; n++) {
  580. // Get info about the item
  581. lvi.iItem = n ;
  582. m_clcView.GetItem(&lvi) ;
  583. // Save the current width. When the last width is saved, make sure that
  584. // the new average width is calculated.
  585. m_pcfi->SetWidth(n, (WORD) atoi(lvi.pszText), (n == numitems)) ;
  586. } ;
  587. // All went well so...
  588. return false ;
  589. }
  590. /******************************************************************************
  591. CAddKernPair dialog class
  592. This class handles the dialog displayed when the user wishes to add a kern
  593. pair to the kern pair array.
  594. This class is used by the CFontKerningPage class
  595. ******************************************************************************/
  596. class CAddKernPair : public CDialog {
  597. CSafeMapWordToOb &m_csmw2oFirst, &m_csmw2oSecond;
  598. CWordArray &m_cwaPoints;
  599. WORD m_wFirst, m_wSecond;
  600. // Construction
  601. public:
  602. CAddKernPair(CSafeMapWordToOb& cmsw2o1, CSafeMapWordToOb& cmsw2o2,
  603. CWordArray& cwaPoints, CWnd* pParent);
  604. WORD First() const { return m_wFirst; }
  605. WORD Second() const { return m_wSecond; }
  606. // Dialog Data
  607. //{{AFX_DATA(CAddKernPair)
  608. enum { IDD = IDD_AddKernPair };
  609. CButton m_cbOK;
  610. CComboBox m_ccbSecond;
  611. CComboBox m_ccbFirst;
  612. short m_sAmount;
  613. //}}AFX_DATA
  614. // Overrides
  615. // ClassWizard generated virtual function overrides
  616. //{{AFX_VIRTUAL(CAddKernPair)
  617. protected:
  618. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  619. //}}AFX_VIRTUAL
  620. // Implementation
  621. protected:
  622. // Generated message map functions
  623. //{{AFX_MSG(CAddKernPair)
  624. virtual BOOL OnInitDialog();
  625. afx_msg void OnSelchangeKernFirst();
  626. afx_msg void OnSelchangeKernSecond();
  627. afx_msg void OnChangeKernAmount();
  628. //}}AFX_MSG
  629. DECLARE_MESSAGE_MAP()
  630. };
  631. CAddKernPair::CAddKernPair(CSafeMapWordToOb& csmw2o1,
  632. CSafeMapWordToOb& csmw2o2, CWordArray& cwaPoints,
  633. CWnd* pParent)
  634. : CDialog(CAddKernPair::IDD, pParent), m_csmw2oFirst(csmw2o1),
  635. m_csmw2oSecond(csmw2o2), m_cwaPoints(cwaPoints) {
  636. //{{AFX_DATA_INIT(CAddKernPair)
  637. m_sAmount = 0;
  638. //}}AFX_DATA_INIT
  639. m_wFirst = m_wSecond = 0;
  640. }
  641. void CAddKernPair::DoDataExchange(CDataExchange* pDX) {
  642. CDialog::DoDataExchange(pDX);
  643. //{{AFX_DATA_MAP(CAddKernPair)
  644. DDX_Control(pDX, IDOK, m_cbOK);
  645. DDX_Control(pDX, IDC_KernSecond, m_ccbSecond);
  646. DDX_Control(pDX, IDC_KernFirst, m_ccbFirst);
  647. DDX_Text(pDX, IDC_KernAmount, m_sAmount);
  648. //}}AFX_DATA_MAP
  649. }
  650. BEGIN_MESSAGE_MAP(CAddKernPair, CDialog)
  651. //{{AFX_MSG_MAP(CAddKernPair)
  652. ON_CBN_SELCHANGE(IDC_KernFirst, OnSelchangeKernFirst)
  653. ON_CBN_SELCHANGE(IDC_KernSecond, OnSelchangeKernSecond)
  654. ON_EN_CHANGE(IDC_KernAmount, OnChangeKernAmount)
  655. //}}AFX_MSG_MAP
  656. END_MESSAGE_MAP()
  657. /////////////////////////////////////////////////////////////////////////////
  658. // CAddKernPair message handlers
  659. /******************************************************************************
  660. CAddKernPair::OnInitDialog
  661. This member function initializes the dialog box, by filling both combo boxes,
  662. and disabling the OK button.
  663. ******************************************************************************/
  664. BOOL CAddKernPair::OnInitDialog() {
  665. CDialog::OnInitDialog(); // Initialize everything
  666. // Fill in the first combo box
  667. CString csWork;
  668. int rm = (int)m_cwaPoints.GetSize(); // rm
  669. for (int i = 0; i < m_cwaPoints.GetSize(); i++) {
  670. csWork.Format("%4.4X", m_cwaPoints[i]);
  671. int id = m_ccbFirst.AddString(csWork);
  672. m_ccbFirst.SetItemData(id, m_cwaPoints[i]);
  673. }
  674. m_ccbFirst.SetCurSel(0);
  675. OnSelchangeKernFirst(); // Fill the second box with this code.
  676. m_cbOK.EnableWindow(FALSE);
  677. return TRUE;
  678. }
  679. /******************************************************************************
  680. CAddKernPair::OnSelchangeKernFirst
  681. This member is called whenever the selection changes in the first character
  682. combo box. It screens out any already paired characters from the second
  683. character combo box, while preserving the currently selected character (if
  684. possible).
  685. ******************************************************************************/
  686. void CAddKernPair::OnSelchangeKernFirst() {
  687. int id = m_ccbFirst.GetCurSel();
  688. if (id < 0)
  689. return;
  690. m_wFirst = (WORD) m_ccbFirst.GetItemData(id);
  691. // See which character is selected in the second box, so we can keep it
  692. // if it is still valid.
  693. id = m_ccbSecond.GetCurSel();
  694. m_wSecond = (id > -1) ? (WORD) m_ccbSecond.GetItemData(id) : 0;
  695. m_ccbSecond.ResetContent();
  696. CString csWork;
  697. for (id = 0; id < m_cwaPoints.GetSize(); id++) {
  698. union {
  699. CObject *pco;
  700. CMapWordToDWord *pcmw2dFirst;
  701. };
  702. DWORD dwIgnore;
  703. if (m_csmw2oFirst.Lookup(m_wFirst, pco) &&
  704. pcmw2dFirst -> Lookup(m_cwaPoints[id], dwIgnore)) {
  705. // There is already a kern pair for this second point
  706. // Don't include it in the list, and drop it if it is
  707. // the currently selected second point.
  708. if (m_wSecond == m_cwaPoints[id])
  709. m_wSecond = 0;
  710. continue;
  711. }
  712. csWork.Format("%4.4X", m_cwaPoints[id]);
  713. int id2 = m_ccbSecond.AddString(csWork);
  714. m_ccbSecond.SetItemData(id2, m_cwaPoints[id]);
  715. if (m_wSecond == m_cwaPoints[id])
  716. m_ccbSecond.SetCurSel(id2);
  717. }
  718. if (!m_wSecond) {
  719. m_ccbSecond.SetCurSel(0);
  720. m_wSecond = (WORD) m_ccbSecond.GetItemData(0);
  721. }
  722. }
  723. /******************************************************************************
  724. CAddKernPair::OnSelchangeKernSecond
  725. This member is called whenever the selection changes in the second character
  726. combo box. It screens out any already paired characters from the first
  727. character combo box, while preserving the currently selected character (if
  728. possible).
  729. ******************************************************************************/
  730. void CAddKernPair::OnSelchangeKernSecond() {
  731. int id = m_ccbSecond.GetCurSel();
  732. if (id < 0)
  733. return;
  734. m_wSecond = (WORD) m_ccbSecond.GetItemData(id);
  735. // See which character is selected in the first box, so we can keep it
  736. // if it is still valid.
  737. id = m_ccbFirst.GetCurSel();
  738. m_wFirst = (id > -1) ? (WORD) m_ccbFirst.GetItemData(id) : 0;
  739. m_ccbFirst.ResetContent();
  740. CString csWork;
  741. for (id = 0; id < m_cwaPoints.GetSize(); id++) {
  742. union {
  743. CObject *pco;
  744. CMapWordToDWord *pcmw2dSecond;
  745. };
  746. DWORD dwIgnore;
  747. if (m_csmw2oSecond.Lookup(m_wSecond, pco) &&
  748. pcmw2dSecond -> Lookup(m_cwaPoints[id], dwIgnore)) {
  749. // There is already a kern pair for this first point
  750. // Don't include it in the list, and drop it if it is
  751. // the currently selected first point.
  752. if (m_wFirst == m_cwaPoints[id])
  753. m_wFirst = 0;
  754. continue;
  755. }
  756. csWork.Format("%4.4X", m_cwaPoints[id]);
  757. int id2 = m_ccbFirst.AddString(csWork);
  758. m_ccbFirst.SetItemData(id2, m_cwaPoints[id]);
  759. if (m_wFirst == m_cwaPoints[id])
  760. m_ccbFirst.SetCurSel(id2);
  761. }
  762. if (!m_wFirst) {
  763. m_ccbFirst.SetCurSel(0);
  764. m_wFirst = (WORD) m_ccbFirst.GetItemData(0);
  765. }
  766. }
  767. /******************************************************************************
  768. CAddKernPair::OnChangeKernAmount
  769. This member gets called when a change is made to the amount edit box. It
  770. enables the OK button if a non-zero amount seems to be there. The DDX/DDV
  771. functions called from OnOK (by default) will handle any garbage that may
  772. have been entered, so this needn't be a complete screen.
  773. ******************************************************************************/
  774. void CAddKernPair::OnChangeKernAmount() {
  775. // Don't use DDX/DDV, as it will complain if the user's just typed a
  776. // minus sign. All we care about is the amount is non-zero, so we can
  777. // enable/disable the OK button, as needed.
  778. // raid 27265
  779. INT iValue = (INT) GetDlgItemInt(IDC_KernAmount);
  780. if (iValue < -32767 || iValue > 32767 )
  781. iValue = 0; // end raid
  782. m_cbOK.EnableWindow(!! iValue );// GetDlgItemInt(IDC_KernAmount));
  783. }
  784. /******************************************************************************
  785. CFontKerningPage class
  786. This class handles the font kerning page- the UI here consists of a list view
  787. showing the pairs- the view can be sorted several ways, and pairs can be
  788. added or deleted.
  789. ******************************************************************************/
  790. /******************************************************************************
  791. CFontKerningPage::Sort(LPARAM lp1, LPARAM lp2, LPARAM lpThis)
  792. This is a static private function used to interface the listview's sort
  793. callback requirements (to which this adheres) to the classes sort routine,
  794. which follows.
  795. ******************************************************************************/
  796. int CALLBACK CFontKerningPage::Sort(LPARAM lp1, LPARAM lp2, LPARAM lpThis) {
  797. CFontKerningPage *pcfkp = (CFontKerningPage *) lpThis;
  798. return pcfkp -> Sort((unsigned)lp1, (unsigned)lp2);
  799. }
  800. /******************************************************************************
  801. CFontKerningPage::Sort(unsigned u1, unsigned u2)
  802. This member returns -1, 0, 0r 1 to indiciate if the kern pair at index u1 is
  803. less than, equal to, or greater than the pair at u2, respectively. The sort
  804. criteria are based on the internal control members.
  805. ******************************************************************************/
  806. int CFontKerningPage::Sort(unsigned u1, unsigned u2) {
  807. for (unsigned u = 0; u < 3; u++) {
  808. switch (m_uPrecedence[u]) {
  809. case Amount:
  810. switch (m_pcfi -> CompareKernAmount(u1, u2)) {
  811. case CFontInfo::Less:
  812. return (m_ufDescending & 1) ? 1 : -1;
  813. case CFontInfo::More:
  814. return (m_ufDescending & 1) ? -1 : 1;
  815. }
  816. continue; // If they are equal
  817. case First:
  818. switch (m_pcfi -> CompareKernFirst(u1, u2)) {
  819. case CFontInfo::Less:
  820. return (m_ufDescending & 2) ? 1 : -1;
  821. case CFontInfo::More:
  822. return (m_ufDescending & 2) ? -1 : 1;
  823. }
  824. continue; // If they are equal
  825. default: // Assume this is always second
  826. switch (m_pcfi -> CompareKernSecond(u1, u2)) {
  827. case CFontInfo::Less:
  828. return (m_ufDescending & 4) ? 1 : -1;
  829. case CFontInfo::More:
  830. return (m_ufDescending & 4) ? -1 : 1;
  831. }
  832. continue; // If they are equal
  833. }
  834. }
  835. // Tell the user that there is something wrong with the kerning table
  836. // instead of asserting.
  837. //_ASSERT(FALSE);
  838. CString csmsg ;
  839. csmsg.Format(IDS_BadKernPairError, u1, m_pcfi->GetKernAmount(u1),
  840. m_pcfi->GetKernFirst(u1), m_pcfi->GetKernSecond(u1)) ;
  841. AfxMessageBox(csmsg, MB_ICONEXCLAMATION) ;
  842. return 0; // This should never happen- two items should never be equal
  843. }
  844. /******************************************************************************
  845. CFontKerningPage Constructor, destructor, message map, and DDX/DDV.
  846. Except for some trivial construction, all of this is pretty standard MFC
  847. wizard-maintained stuff.
  848. ******************************************************************************/
  849. CFontKerningPage::CFontKerningPage() : CToolTipPage(CFontKerningPage::IDD)
  850. {
  851. //{{AFX_DATA_INIT(CFontKerningPage)
  852. //}}AFX_DATA_INIT
  853. m_bInitDone = false;
  854. m_uHelpID = HID_BASE_RESOURCE + IDR_FONT_VIEWER ;
  855. InitMemberVars() ;
  856. }
  857. /******************************************************************************
  858. CFontKerningPage::InitMemberVars
  859. Initialize the member variables that must be initialized both during
  860. construction and when the UFM is reloaded because of a GTT or CP change.
  861. ******************************************************************************/
  862. void CFontKerningPage::InitMemberVars()
  863. {
  864. m_idSelected = -1;
  865. m_ufDescending = 0;
  866. m_uPrecedence[0] = Second; // This is the default precedence in UFM
  867. m_uPrecedence[1] = First;
  868. m_uPrecedence[2] = Amount;
  869. }
  870. CFontKerningPage::~CFontKerningPage() {
  871. }
  872. void CFontKerningPage::DoDataExchange(CDataExchange* pDX) {
  873. CPropertyPage::DoDataExchange(pDX);
  874. //{{AFX_DATA_MAP(CFontKerningPage)
  875. DDX_Control(pDX, IDC_KerningTree, m_clcView);
  876. //}}AFX_DATA_MAP
  877. }
  878. BEGIN_MESSAGE_MAP(CFontKerningPage, CToolTipPage)
  879. //{{AFX_MSG_MAP(CFontKerningPage)
  880. ON_WM_CONTEXTMENU()
  881. ON_NOTIFY(LVN_KEYDOWN, IDC_KerningTree, OnKeydownKerningTree)
  882. ON_NOTIFY(LVN_ENDLABELEDIT, IDC_KerningTree, OnEndlabeleditKerningTree)
  883. ON_NOTIFY(LVN_COLUMNCLICK, IDC_KerningTree, OnColumnclickKerningTree)
  884. //}}AFX_MSG_MAP
  885. ON_COMMAND(ID_AddItem, OnAddItem)
  886. ON_COMMAND(ID_DeleteItem, OnDeleteItem)
  887. ON_COMMAND(ID_ChangeAmount, OnChangeAmount)
  888. END_MESSAGE_MAP()
  889. /////////////////////////////////////////////////////////////////////////////
  890. // CFontKerningPage message handlers
  891. /******************************************************************************
  892. CFontKerningPage::OnSetActive
  893. Kerning only makes sense for variable pitch fonts, so if this font has
  894. changed, we will enable/disable, and change what we display accordingly.
  895. ******************************************************************************/
  896. BOOL CFontKerningPage::OnSetActive()
  897. {
  898. if (!CToolTipPage::OnSetActive())
  899. return FALSE ;
  900. int rm1 = m_pcfi->IsVariableWidth() ; // rm debugging only
  901. int rm2 = m_clcView.GetItemCount() ; // rm debugging only
  902. // Reworked code to fix Raid Bug 163816...
  903. // Enable the list control based on whether or not this is a variable
  904. // pitched font.
  905. m_clcView.EnableWindow(m_pcfi->IsVariableWidth()) ;
  906. // First time in this routine. Make sure the list is empty. Then load
  907. // it with this font's kerning info if the font has variable pitch.
  908. m_clcView.DeleteAllItems();
  909. if (m_pcfi->IsVariableWidth()) {
  910. m_pcfi -> FillKern(m_clcView) ;
  911. m_clcView.SortItems(Sort, (LPARAM) this) ;
  912. } ;
  913. return TRUE ;
  914. /* Rick's original code
  915. if (m_pcfi->IsVariableWidth() == !!m_clcView.GetItemCount()) // IsVariableWidth is either 0 or 1, so == is safe, here
  916. return TRUE; // Everything is copacetic
  917. m_clcView.EnableWindow(m_pcfi -> IsVariableWidth());
  918. if (m_clcView.GetItemCount())
  919. m_clcView.DeleteAllItems();
  920. else
  921. {
  922. m_pcfi -> FillKern(m_clcView);
  923. m_clcView.SortItems(Sort, (LPARAM) this);
  924. }
  925. return TRUE;
  926. */
  927. }
  928. /******************************************************************************
  929. CFontKerningPage::OnInitDialog
  930. This member handles initialization of the dialog. In this case, we format
  931. and fill in the kerning tree, if there is one to fill in. In addition, a
  932. copy is made of the kerning pairs table so that changes can be discarded
  933. when necessary.
  934. ******************************************************************************/
  935. BOOL CFontKerningPage::OnInitDialog()
  936. {
  937. CToolTipPage::OnInitDialog();
  938. CString csWork;
  939. csWork.LoadString(IDS_KernColumn0);
  940. m_clcView.InsertColumn(0, csWork, LVCFMT_CENTER,
  941. (3 * m_clcView.GetStringWidth(csWork)) >>
  942. 1, 0);
  943. csWork.LoadString(IDS_KernColumn1);
  944. m_clcView.InsertColumn(1, csWork, LVCFMT_CENTER,
  945. m_clcView.GetStringWidth(csWork) << 1, 1);
  946. csWork.LoadString(IDS_KernColumn2);
  947. m_clcView.InsertColumn(2, csWork, LVCFMT_CENTER,
  948. m_clcView.GetStringWidth(csWork) << 1, 2);
  949. m_pcfi -> FillKern(m_clcView);
  950. m_pcfi -> MakeKernCopy();
  951. m_bInitDone = true ;
  952. return TRUE;
  953. }
  954. /******************************************************************************
  955. CFontKerningPage::OnContextMenu
  956. This member function is called whenever the user right-clicks the mouse
  957. anywhere within the dialog. If it turns out not to have been within the list
  958. control, we ignore it. Otherwise, we put up an appropriate context menu.
  959. ******************************************************************************/
  960. void CFontKerningPage::OnContextMenu(CWnd* pcwnd, CPoint cpt)
  961. {
  962. if (pcwnd -> m_hWnd != m_clcView.m_hWnd) // Clicked with in the list?
  963. { // Note, will also fail if list is disabled
  964. CToolTipPage::OnContextMenu(pcwnd, cpt);
  965. return;
  966. }
  967. CPoint cptThis(cpt); // For hit test purposes, we will adjust this.
  968. m_clcView.ScreenToClient(&cptThis);
  969. cptThis.x = 5; // An arbitrary point sure to be within the label.
  970. m_idSelected = m_clcView.HitTest(cptThis);
  971. if (m_idSelected == -1) { // Nothing selected, allow the "Add" item
  972. CMenu cmThis;
  973. CString csWork;
  974. cmThis.CreatePopupMenu();
  975. csWork.LoadString(ID_AddItem);
  976. cmThis.AppendMenu(MF_STRING | MF_ENABLED, ID_AddItem, csWork);
  977. cmThis.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cpt.x, cpt.y,
  978. this);
  979. return;
  980. }
  981. // We'll draw our own selection rectangle covering the entire item
  982. CRect crItem;
  983. m_clcView.GetItemRect(m_idSelected, crItem, LVIR_BOUNDS);
  984. CDC *pcdc = m_clcView.GetDC();
  985. pcdc -> InvertRect(crItem);
  986. m_clcView.ReleaseDC(pcdc);
  987. CMenu cmThis;
  988. CString csWork;
  989. cmThis.CreatePopupMenu();
  990. csWork.LoadString(ID_ChangeAmount);
  991. cmThis.AppendMenu(MF_STRING | MF_ENABLED, ID_ChangeAmount, csWork);
  992. cmThis.AppendMenu(MF_SEPARATOR);
  993. csWork.LoadString(ID_AddItem);
  994. cmThis.AppendMenu(MF_STRING | MF_ENABLED, ID_AddItem, csWork);
  995. csWork.LoadString(ID_DeleteItem);
  996. cmThis.AppendMenu(MF_STRING | MF_ENABLED, ID_DeleteItem,
  997. csWork);
  998. cmThis.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cpt.x, cpt.y,
  999. this);
  1000. // Undo the selection rectangle
  1001. pcdc = m_clcView.GetDC();
  1002. pcdc -> InvertRect(crItem);
  1003. m_clcView.ReleaseDC(pcdc);
  1004. }
  1005. /******************************************************************************
  1006. CFontKerningPage::OnAddItem
  1007. This member will be called whenever the user asks to add an additional
  1008. kerning pair to the list.
  1009. ******************************************************************************/
  1010. void CFontKerningPage::OnAddItem() {
  1011. CSafeMapWordToOb csmw2oFirst, csmw2oSecond;
  1012. CWordArray cwaPoints;
  1013. m_pcfi -> MapKerning(csmw2oFirst, csmw2oSecond, cwaPoints);
  1014. CAddKernPair cakp(csmw2oFirst, csmw2oSecond, cwaPoints, this);
  1015. if (cakp.DoModal() == IDOK) {
  1016. m_pcfi -> AddKern(cakp.First(), cakp.Second(), cakp.m_sAmount,
  1017. m_clcView);
  1018. }
  1019. }
  1020. /******************************************************************************
  1021. CFontKerningPage::OnDeleteItem
  1022. This will be called if we try to delete an item from the context menu.
  1023. ******************************************************************************/
  1024. void CFontKerningPage::OnDeleteItem() {
  1025. if (m_idSelected < 0)
  1026. return; // Nothing to delete?
  1027. m_pcfi -> RemoveKern((unsigned)m_clcView.GetItemData(m_idSelected));
  1028. m_clcView.DeleteItem(m_idSelected);
  1029. m_idSelected = -1;
  1030. }
  1031. /******************************************************************************
  1032. CFontKerningPage::OnChangeAmount
  1033. This is called when the user selects the menu item stating they wish to
  1034. change the kerning amount. It just needs to initiate a label edit.
  1035. ******************************************************************************/
  1036. void CFontKerningPage::OnChangeAmount() {
  1037. if (m_idSelected < 0)
  1038. return;
  1039. m_clcView.EditLabel(m_idSelected);
  1040. m_idSelected = -1;
  1041. }
  1042. /******************************************************************************
  1043. CFontKerningPage::OnKeydownKerningTree
  1044. This is called most of the time when a key is pressed while the list control
  1045. has the keyboard focus. Unfortunately, the enter key is one of those we do
  1046. not get to see.
  1047. Currently, the F2, F10, and delete keys get special processing. F2 opens
  1048. an edit label on the current item, while F10 displays the context menu, and
  1049. the delete key deletes it.
  1050. ******************************************************************************/
  1051. void CFontKerningPage::OnKeydownKerningTree(NMHDR* pnmh, LRESULT* plr) {
  1052. LV_KEYDOWN *plvkd = (LV_KEYDOWN *) pnmh;
  1053. *plr = 0;
  1054. m_idSelected = m_clcView.GetNextItem(-1, LVIS_FOCUSED | LVIS_SELECTED);
  1055. if (m_idSelected < 0) {
  1056. if (plvkd -> wVKey == VK_F10) // Do an add item, in this case.
  1057. OnAddItem();
  1058. return;
  1059. }
  1060. switch (plvkd -> wVKey) {
  1061. case VK_F2:
  1062. m_clcView.EditLabel(m_idSelected);
  1063. break;
  1064. case VK_DELETE:
  1065. OnDeleteItem();
  1066. break;
  1067. case VK_F10:
  1068. {
  1069. CRect crItem;
  1070. m_clcView.GetItemRect(m_idSelected, crItem, LVIR_LABEL);
  1071. m_clcView.ClientToScreen(crItem);
  1072. OnContextMenu(&m_clcView, crItem.CenterPoint());
  1073. break;
  1074. }
  1075. }
  1076. }
  1077. /******************************************************************************
  1078. CFontKerningPage::OnEndLabelEdit
  1079. This method gets called when the user finishes editing a kern amount, either
  1080. by canceling it or pressing the enter key.
  1081. ******************************************************************************/
  1082. void CFontKerningPage::OnEndlabeleditKerningTree(NMHDR* pnmh, LRESULT* plr){
  1083. LV_DISPINFO *plvdi = (LV_DISPINFO*) pnmh;
  1084. *plr = 0; // Assume failure
  1085. if (!plvdi -> item.pszText) // Editing canceled?
  1086. return;
  1087. CString csNew(plvdi -> item.pszText);
  1088. csNew.TrimRight();
  1089. csNew.TrimLeft();
  1090. // A negative kerning amount is OK so csTemp is not needed. Use csNew in
  1091. // the following if statement instead of csTemp.
  1092. //
  1093. //CString csTemp = (csNew[1] == _T('-')) ? csNew.Mid(1) : csNew;
  1094. if (csNew.SpanIncluding("-1234567890").GetLength() != csNew.GetLength()) {
  1095. AfxMessageBox(IDS_InvalidNumberFormat);
  1096. return;
  1097. }
  1098. m_pcfi -> SetKernAmount((unsigned)plvdi -> item.lParam, (WORD) atoi(csNew));
  1099. *plr = TRUE;
  1100. }
  1101. /******************************************************************************
  1102. CFontKerningPage::OnColumnclikKerningTree
  1103. This member gets called whn one of the sort headers is clicked. If it is
  1104. already the primary column, we revers the sort order fot that column.
  1105. Otherwise, we retain the current order, and make this column the primary
  1106. column, moving the other columns down in precedence.
  1107. ******************************************************************************/
  1108. void CFontKerningPage::OnColumnclickKerningTree(NMHDR* pnmh, LRESULT* plr) {
  1109. NM_LISTVIEW *pnmlv = (NM_LISTVIEW*) pnmh;
  1110. *plr = 0;
  1111. if (m_uPrecedence[0] == (unsigned) pnmlv -> iSubItem)
  1112. m_ufDescending ^= (1 << pnmlv -> iSubItem);
  1113. else {
  1114. if (m_uPrecedence[2] == (unsigned) pnmlv -> iSubItem)
  1115. m_uPrecedence[2] = m_uPrecedence[1];
  1116. m_uPrecedence[1] = m_uPrecedence[0];
  1117. m_uPrecedence[0] = pnmlv -> iSubItem;
  1118. }
  1119. m_clcView.SortItems(Sort, (LPARAM) this);
  1120. }
  1121. /******************************************************************************
  1122. CFontKerningPage::ValidateUFMFields
  1123. Validate all specified fields managed by this page. Return true if the user
  1124. wants to leave the UFM Editor open so that he can fix any problem. Otherwise,
  1125. return true.
  1126. ******************************************************************************/
  1127. bool CFontKerningPage::ValidateUFMFields()
  1128. {
  1129. // All tests passed or the user doesn't want to fix them so...
  1130. return false ;
  1131. }
  1132. /******************************************************************************
  1133. CFontKerningPage::SavePageData
  1134. Save the data in the kerning page back into the CFontInfo class instance that
  1135. was used to load this page. See CFontInfoContainer::OnSaveDocument() for
  1136. more info.
  1137. In this particular case, no work needs to be done. Kerning pairs are kept in
  1138. CFontInfo in a more complex collection of classes and arrays than any of the
  1139. other data. Because of this, a backup copy of the kerning data is made so
  1140. that the editor can continue to update the main copy of the data. If the
  1141. user chooses not to save his changes, the backup is restored. See
  1142. CFontInfoContainer::SaveModified() for more information.
  1143. Return true if there was a problem saving the data. Otherwise, return false.
  1144. ******************************************************************************/
  1145. bool CFontKerningPage::SavePageData()
  1146. {
  1147. // All went well so...
  1148. return false ;
  1149. }
  1150. // Below are globals, definitions, and constants that are useful in
  1151. // CFontHeaderPage. They are put here so that others who include fontview.h
  1152. // don't get copies of them.
  1153. LPTSTR apstrUniWTypes[] = {
  1154. _T("DF_TYPE_HPINTELLIFONT"), _T("DF_TYPE_TRUETYPE"), _T("DF_TYPE_PST1"),
  1155. _T("DF_TYPE_CAPSL"), _T("DF_TYPE_OEM1"), _T("DF_TYPE_OEM2"), _T("UNDEFINED")
  1156. } ;
  1157. const int nNumValidWTypes = 6 ;
  1158. const CString csHex = _T("0x%x") ; // Format strings
  1159. const CString csDec = _T("%d") ;
  1160. const CString csPnt = _T("{%d, %d}") ;
  1161. #define HDR_GENFLAGS 0 // These definitions are used in the code and
  1162. #define HDR_TYPE 1 // data structures that refer to the 3 UFM
  1163. #define HDR_CAPS 2 // Header fields edited with sub dialog boxes.
  1164. static bool CALLBACK CHP_SubOrdDlgManager(CObject* pcoowner, int nrow, int ncol,
  1165. CString* pcscontents)
  1166. {
  1167. CDialog* pdlg =NULL; // Loaded with ptr to dialog box class to call
  1168. // Use the row number to determine the dialog box to invoke.
  1169. switch (nrow) {
  1170. case HDR_GENFLAGS:
  1171. pdlg = new CGenFlags(pcscontents) ;
  1172. break ;
  1173. case HDR_TYPE:
  1174. pdlg = new CHdrTypes(pcscontents) ;
  1175. break ;
  1176. case HDR_CAPS:
  1177. pdlg = new CHdrCaps(pcscontents) ;
  1178. break ;
  1179. default:
  1180. ASSERT(0) ;
  1181. } ;
  1182. //RAID 43540) Prefix
  1183. if(pdlg==NULL){
  1184. AfxMessageBox(IDS_ResourceError);
  1185. return false;
  1186. };
  1187. // END RAID
  1188. // Invoke the dialog box. The dlg will update scontents. Return true if
  1189. // the dlg returns true. Otherwise, return false.
  1190. if (pdlg->DoModal() == IDOK)
  1191. return true ;
  1192. else
  1193. return false ;
  1194. }
  1195. /////////////////////////////////////////////////////////////////////////////
  1196. // CFontHeaderPage property page
  1197. IMPLEMENT_DYNCREATE(CFontHeaderPage, CPropertyPage)
  1198. CFontHeaderPage::CFontHeaderPage() : CPropertyPage(CFontHeaderPage::IDD)
  1199. {
  1200. //{{AFX_DATA_INIT(CFontHeaderPage)
  1201. m_csDefaultCodePage = _T("");
  1202. m_csRCID = _T("");
  1203. //}}AFX_DATA_INIT
  1204. m_bInitDone = false ;
  1205. }
  1206. CFontHeaderPage::~CFontHeaderPage()
  1207. {
  1208. }
  1209. void CFontHeaderPage::DoDataExchange(CDataExchange* pDX)
  1210. {
  1211. CPropertyPage::DoDataExchange(pDX);
  1212. //{{AFX_DATA_MAP(CFontHeaderPage)
  1213. DDX_Control(pDX, IDC_UniDrvLst, m_cfelcUniDrv);
  1214. DDX_Text(pDX, IDC_DefaultCodepageBox, m_csDefaultCodePage);
  1215. DDV_MaxChars(pDX, m_csDefaultCodePage, 6);
  1216. DDX_Text(pDX, IDC_GlyphSetDataRCIDBox, m_csRCID);
  1217. //}}AFX_DATA_MAP
  1218. }
  1219. BEGIN_MESSAGE_MAP(CFontHeaderPage, CPropertyPage)
  1220. //{{AFX_MSG_MAP(CFontHeaderPage)
  1221. ON_EN_CHANGE(IDC_DefaultCodepageBox, OnChangeDefaultCodepageBox)
  1222. ON_EN_CHANGE(IDC_GlyphSetDataRCIDBox, OnChangeGlyphSetDataRCIDBox)
  1223. ON_EN_KILLFOCUS(IDC_DefaultCodepageBox, OnKillfocusDefaultCodepageBox)
  1224. ON_EN_KILLFOCUS(IDC_GlyphSetDataRCIDBox, OnKillfocusGlyphSetDataRCIDBox)
  1225. //}}AFX_MSG_MAP
  1226. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  1227. END_MESSAGE_MAP()
  1228. /////////////////////////////////////////////////////////////////////////////
  1229. // CFontHeaderPage message handlers
  1230. /******************************************************************************
  1231. CFontHeaderPage::OnInitDialog
  1232. Initialize this page of the editor's property sheet. This means loading UFM
  1233. header/UNIDRV info from the FontInfo class into the controls and configuring
  1234. the list control so that it will properly display and edit the data in it.
  1235. The list control is also told that the first 3 fields in the UNIDRV
  1236. structure are edited by subordinate dialog boxes.
  1237. ******************************************************************************/
  1238. BOOL CFontHeaderPage::OnInitDialog()
  1239. {
  1240. CPropertyPage::OnInitDialog() ;
  1241. // Load the code page and RC ID boxes with data from the FontInfo class
  1242. m_csDefaultCodePage.Format(csDec, m_pcfi->m_ulDefaultCodepage) ;
  1243. m_csRCID.Format(csDec, (int) (short) m_pcfi->m_lGlyphSetDataRCID) ; //raid 135627
  1244. // m_sRCID = (short) m_pcfi->m_lGlyphSetDataRCID ;
  1245. UpdateData(FALSE) ;
  1246. // Initialize the list control. We want full row select. There are 9 rows
  1247. // and 2 columns. Nothing is togglable and the max length of an entry is
  1248. // 256 characters. Send change notifications and ignore insert/delete
  1249. // characters.
  1250. const int numfields = 9 ;
  1251. m_cfelcUniDrv.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 256,
  1252. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  1253. // Init and load the field names column; col 0. Start by loading an array
  1254. // with the field names.
  1255. CStringArray csacoldata ; // Holds column data for list control
  1256. csacoldata.SetSize(numfields) ;
  1257. csacoldata[HDR_GENFLAGS] = _T("flGenFlags") ;
  1258. csacoldata[HDR_TYPE] = _T("wType") ;
  1259. csacoldata[HDR_CAPS] = _T("fCaps") ;
  1260. csacoldata[3] = _T("wXRes") ;
  1261. csacoldata[4] = _T("wYRes") ;
  1262. csacoldata[5] = _T("sYAdjust") ;
  1263. csacoldata[6] = _T("sYMoved") ;
  1264. csacoldata[7] = _T("SelectFont") ;
  1265. csacoldata[8] = _T("UnSelectFont") ;
  1266. m_cfelcUniDrv.InitLoadColumn(0, csField, COMPUTECOLWIDTH, 10, false, false,
  1267. COLDATTYPE_STRING, (CObArray*) &csacoldata) ;
  1268. // Tell the list control that some of the values must be editted with
  1269. // a subordinate dialog box; fields 0, 1, & 2.
  1270. CUIntArray cuia ;
  1271. cuia.SetSize(numfields) ;
  1272. cuia[HDR_GENFLAGS] = cuia[HDR_TYPE] = cuia[HDR_CAPS] = 1 ;
  1273. //cuia[3] = cuia[4] = cuia[5] = cuia[6] = cuia[7] = cuia[8] = 0 ;
  1274. m_cfelcUniDrv.ExtraInit_CustEditCol(1, this,
  1275. CEF_HASTOGGLECOLUMNS+CEF_CLICKONROW,
  1276. cuia, CHP_SubOrdDlgManager) ;
  1277. // Init and load the values column. The data must be pulled out of the
  1278. // FontInfo class and converted to strings so that they can be loaded
  1279. // into the list control.
  1280. int n ;
  1281. csacoldata[0].Format(csHex, m_pcfi->m_UNIDRVINFO.flGenFlags) ;
  1282. n = m_pcfi->m_UNIDRVINFO.wType ;
  1283. csacoldata[1] = (n < nNumValidWTypes) ?
  1284. apstrUniWTypes[n] : apstrUniWTypes[nNumValidWTypes] ;
  1285. csacoldata[2].Format(csHex, m_pcfi->m_UNIDRVINFO.fCaps) ;
  1286. csacoldata[3].Format(csDec, m_pcfi->m_UNIDRVINFO.wXRes) ;
  1287. csacoldata[4].Format(csDec, m_pcfi->m_UNIDRVINFO.wYRes) ;
  1288. csacoldata[5].Format(csDec, m_pcfi->m_UNIDRVINFO.sYAdjust) ;
  1289. csacoldata[6].Format(csDec, m_pcfi->m_UNIDRVINFO.sYMoved) ;
  1290. m_pcfi->Selector().GetInvocation(csacoldata[7]) ;
  1291. m_pcfi->Selector(FALSE).GetInvocation(csacoldata[8]) ;
  1292. m_cfelcUniDrv.InitLoadColumn(1, csValue, SETWIDTHTOREMAINDER, -11, true,
  1293. false, COLDATTYPE_CUSTEDIT,
  1294. (CObArray*) &csacoldata) ;
  1295. m_bInitDone = true ; // Initialization is done now
  1296. return TRUE; // return TRUE unless you set the focus to a control
  1297. // EXCEPTION: OCX Property Pages should return FALSE
  1298. }
  1299. void CFontHeaderPage::OnChangeDefaultCodepageBox()
  1300. {
  1301. // Do nothing if the page is not initialized yet.
  1302. if (!m_bInitDone)
  1303. return ;
  1304. // Mark the UFM as being dirty.
  1305. m_pcfi->Changed() ;
  1306. }
  1307. void CFontHeaderPage::OnChangeGlyphSetDataRCIDBox()
  1308. {
  1309. // Do nothing if the page is not initialized yet.
  1310. if (!m_bInitDone)
  1311. return ;
  1312. // Mark the UFM as being dirty.
  1313. m_pcfi->Changed() ;
  1314. // raid 0003 ; handle the load the width table when change the gttRCID
  1315. CString csRCID = m_csRCID ;
  1316. UpdateData() ;
  1317. if (csRCID != m_csRCID ) {
  1318. m_pcfi->SetRCIDChanged(true) ;
  1319. m_pcfi->SetTranslation((WORD)atoi(m_csRCID)) ;
  1320. }
  1321. }
  1322. LRESULT CFontHeaderPage::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  1323. {
  1324. // Do nothing if the page is not initialized yet.
  1325. if (!m_bInitDone)
  1326. return TRUE ;
  1327. // Mark the UFM as being dirty.
  1328. m_pcfi->Changed() ;
  1329. return TRUE ;
  1330. }
  1331. void CFontHeaderPage::OnKillfocusDefaultCodepageBox()
  1332. {
  1333. // Don't worry about a new cp if there is a GTT ID.
  1334. if (m_pcfi->m_lGlyphSetDataRCID != 0)
  1335. return ;
  1336. CheckHandleCPGTTChange(m_csDefaultCodePage, IDS_CPID) ;
  1337. }
  1338. // this method need to be changed ; just checke the RCID validity: is it
  1339. // exist or not ? don't do anything.
  1340. void CFontHeaderPage::OnKillfocusGlyphSetDataRCIDBox()
  1341. {
  1342. CString csRCID;
  1343. // csRCID.Format("%d",m_csRCID); // raid 135627 , raid 0003
  1344. CheckHandleCPGTTChange(m_csRCID, IDS_GTTID) ;
  1345. }
  1346. /******************************************************************************
  1347. CFontHeaderPage::CheckHandleCPGTTChange
  1348. Determine if the fonts code page / GTT RC ID has changed. If it has, ask
  1349. the user if he wants to update the data based on the change. If he does,
  1350. call the UFM Editor's view class instance to manage UFM saving, reloading,
  1351. and kerning/widths table checking.
  1352. ******************************************************************************/
  1353. void CFontHeaderPage::CheckHandleCPGTTChange(CString& csfieldstr, UINT ustrid)
  1354. {
  1355. // There is nothing to do if the UFM hasn't changed.
  1356. if (!m_pcfic->IsModified())
  1357. return ;
  1358. // Do nothing if the UFM does not describe a variable width font. (In this
  1359. // case, there is no valid kerning or width data.)
  1360. if (!m_pcfi->IsVariableWidth())
  1361. return ;
  1362. // Do nothing if the cp/gtt has not really changed.
  1363. CString cs(csfieldstr) ;
  1364. UpdateData() ;
  1365. if (cs == csfieldstr)
  1366. return ;
  1367. // Tell the user that some or all of the data in the widths and kerning
  1368. // tables may have been invalidated by the CP/GTT ID change. Ask them if
  1369. // they want the tables updated.
  1370. CString csmsg ;
  1371. cs.LoadString(ustrid) ;
  1372. csmsg.Format(IDS_GTTCPChangedMsg, cs) ;
  1373. if (AfxMessageBox(csmsg, MB_ICONINFORMATION+MB_YESNO) == IDNO)
  1374. return ;
  1375. // Call the view class to manage the table updating.
  1376. m_pcfv->HandleCPGTTChange(ustrid == IDS_GTTID) ;
  1377. }
  1378. /******************************************************************************
  1379. CFontHeaderPage::ValidateUFMFields
  1380. Validate all specified fields managed by this page. Return true if the user
  1381. wants to leave the UFM Editor open so that he can fix any problem. Otherwise,
  1382. return true.
  1383. DEAD_BUG
  1384. The UFM Field Validation doc says that the codepage and GTT ID should be
  1385. validated. I have not done this for two reason. First, these checks are
  1386. made by the workspace consistency checking code. Second, the information
  1387. needed to validate these fields are not currently available to this class and
  1388. it would take a lot of work to make the information available.
  1389. ******************************************************************************/
  1390. bool CFontHeaderPage::ValidateUFMFields()
  1391. {
  1392. // If the page was never initialize, its contents could not have changed
  1393. // so no validation is needed in this case.
  1394. if (!m_bInitDone)
  1395. return false ;
  1396. // Get the column of data that contains the fields we need to validate.
  1397. CStringArray csadata ;
  1398. m_cfelcUniDrv.GetColumnData((CObArray*) &csadata, 1) ;
  1399. CString csmsg ; // Holds error messages
  1400. CString cspage(_T("UNIDRVINFO")) ;
  1401. // wXRes must be > 0
  1402. if (CheckUFMGrter0(csadata[3], cspage, _T("wXRes"), 3, m_cfelcUniDrv))
  1403. return true ;
  1404. // wYRes must be > 0
  1405. if (CheckUFMGrter0(csadata[4], cspage, _T("wYRes"), 4, m_cfelcUniDrv))
  1406. return true ;
  1407. // SelectFont cannot be blank/empty.
  1408. if (CheckUFMString(csadata[7], cspage, _T("SelectFont"), 7, m_cfelcUniDrv))
  1409. return true ;
  1410. // All tests passed or the user doesn't want to fix them so...
  1411. return false ;
  1412. }
  1413. /******************************************************************************
  1414. CFontHeaderPage::SavePageData
  1415. Save the data in the header page back into the CFontInfo class instance that
  1416. was used to load this page. See CFontInfoContainer::OnSaveDocument() for
  1417. more info.
  1418. Return true if there was a problem saving the data. Otherwise, return false.
  1419. ******************************************************************************/
  1420. bool CFontHeaderPage::SavePageData()
  1421. {
  1422. // If the page was not initialized, nothing code have changed so do nothing.
  1423. if (!m_bInitDone)
  1424. return false ;
  1425. // Save the default CP and GTT RCID.
  1426. UpdateData() ;
  1427. m_pcfi->m_ulDefaultCodepage = (ULONG) atol(m_csDefaultCodePage) ;
  1428. m_pcfi->m_lGlyphSetDataRCID = (WORD) atoi(m_csRCID) ; // raid 135627
  1429. // m_pcfi->m_lGlyphSetDataRCID = (WORD) m_sRCID;
  1430. // Get the rest of the data out of the list control.
  1431. CStringArray csadata ;
  1432. m_cfelcUniDrv.GetColumnData((CObArray*) &csadata, 1) ;
  1433. // Save the UNIDRVINFO data.
  1434. UNIDRVINFO* pudi = &m_pcfi->m_UNIDRVINFO ;
  1435. LPTSTR pstr2 ;
  1436. pudi->flGenFlags = strtoul(csadata[0].Mid(2), &pstr2, 16) ;
  1437. CString cs = csadata[1] ;
  1438. for (int n = 0 ; n < nNumValidWTypes ; n++) {
  1439. if (apstrUniWTypes[n] == csadata[1])
  1440. pudi->wType = (WORD) n ;
  1441. } ;
  1442. pudi->fCaps = (WORD) strtoul(csadata[2].Mid(2), &pstr2, 16) ;
  1443. pudi->wXRes = (WORD) atoi(csadata[3]) ;
  1444. pudi->wYRes = (WORD) atoi(csadata[4]) ;
  1445. pudi->sYAdjust = (SHORT) atoi(csadata[5]) ;
  1446. pudi->sYMoved = (SHORT) atoi(csadata[6]) ;
  1447. m_pcfi->Selector().SetInvocation(csadata[7]) ;
  1448. m_pcfi->Selector(FALSE).SetInvocation(csadata[8]) ;
  1449. // All went well so...
  1450. return false ;
  1451. }
  1452. /******************************************************************************
  1453. CFontHeaderPage::PreTranslateMessage
  1454. Looks for and process the context sensistive help key (F1).
  1455. ******************************************************************************/
  1456. BOOL CFontHeaderPage::PreTranslateMessage(MSG* pMsg)
  1457. {
  1458. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) {
  1459. AfxGetApp()->WinHelp(HID_BASE_RESOURCE + IDR_FONT_VIEWER) ;
  1460. return TRUE ;
  1461. } ;
  1462. return CPropertyPage::PreTranslateMessage(pMsg);
  1463. }
  1464. // Below are globals, definitions, and constants that are useful in
  1465. // CFontIFIMetricsPage. They are put here so that others who include fontview.h
  1466. // don't get copies of them.
  1467. #define IFI_FAMILYNAME 0 // These definitions are used in the code and
  1468. #define IFI_FONTSIM 4 // data structures that refer to the 12 UFM
  1469. #define IFI_WINCHARSET 5 // IFIMetrics fields edited with subordinate
  1470. #define IFI_WINPITCHFAM 6 // dialog boxes.
  1471. #define IFI_INFO 8
  1472. #define IFI_SELECTION 9
  1473. #define IFI_BASELINE 38
  1474. #define IFI_ASPECT 39
  1475. #define IFI_CARET 40
  1476. #define IFI_FONTBOX 41
  1477. #define IFI_PANOSE 44
  1478. // RAID : add extra charset (from johab_charset), change symbo-charset as 2.
  1479. LPTSTR apstrWinCharSet[] = {
  1480. _T("ANSI_CHARSET"), _T("SYMBOL_CHARSET"), _T("SHIFTJIS_CHARSET"),
  1481. _T("HANGEUL_CHARSET"),_T("CHINESEBIG5_CHARSET"),_T("GB2312_CHARSET"),
  1482. _T("OEM_CHARSET"), _T("JOHAB_CHARSET"), _T("HEBREW_CHARSET"),
  1483. _T("ARABIC_CHARSET"), _T("GREEK_CHARSET"), _T("TURKISH_CHARSET"),
  1484. _T("VIETNAMESE_CHARSET"),_T("THAI_CHARSET"), _T("EASTEUROPE_CHARSET"),
  1485. _T("RUSSIAN_CHARSET"), _T("BALTIC_CHARSET"), _T("UNDEFINED")
  1486. } ;
  1487. int anWinCharSetVals[] = {0, 2, 128, 129, 136,134,255,130,177,178,161,
  1488. 162,163,222,238,204,186,1} ;
  1489. const int nWinCharSet = 18 ;
  1490. // The first array contains the base control IDs for each of the groups of edit
  1491. // controls that contain font simulation data. The second array indicates the
  1492. // number of edit boxes in each group.
  1493. static unsigned auBaseFontSimCtrlID[] =
  1494. {IDC_ItalicWeight, IDC_BoldWeight, IDC_BIWeight} ;
  1495. static unsigned auNumFontSimCtrls[] = {4, 3, 4} ;
  1496. /******************************************************************************
  1497. ParseCompoundNumberString
  1498. There are several IFIMetrics fields that are displayed as strings in the form
  1499. "{x, y, ...z}". This routine parses out the individual numbers (in string
  1500. form) and saves them in a string array.
  1501. Args:
  1502. csaindvnums The individual numeric strings
  1503. pcscompnumstr Pointer to the compound number string that is parsed
  1504. ncount The number of numbers to parse out of pcscompnumstr
  1505. ******************************************************************************/
  1506. void ParseCompoundNumberString(CStringArray& csaindvnums,
  1507. CString* pcscompnumstr, int ncount)
  1508. {
  1509. // Make sure the string array has the right number of entries in it.
  1510. csaindvnums.SetSize(ncount) ;
  1511. // Make a copy of pcscompnumstr that can be torn apart. (Do no include
  1512. // the first curly brace in the string.
  1513. CString cs(pcscompnumstr->Mid(1)) ;
  1514. // Get the first ncount - 1 number strings.
  1515. int n, npos ;
  1516. for (n = 0 ; n < ncount - 1 ; n++) {
  1517. npos = cs.Find(_T(',')) ;
  1518. csaindvnums[n] = cs.Left(npos) ;
  1519. cs = cs.Mid(npos + 2) ;
  1520. } ;
  1521. // Save the last number in the compound string.
  1522. csaindvnums[n] = cs.Left(cs.Find(_T('}'))) ;
  1523. }
  1524. static bool CALLBACK CIP_SubOrdDlgManager(CObject* pcoowner, int nrow, int ncol,
  1525. CString* pcscontents)
  1526. {
  1527. CDialog* pdlg = NULL ; // Loaded with ptr to dialog box class to call
  1528. // Use the row number to determine the dialog box to invoke.
  1529. switch (nrow) {
  1530. case IFI_FAMILYNAME:
  1531. pdlg = new CFIFIFamilyNames(pcscontents,
  1532. (CFontIFIMetricsPage*) pcoowner) ;
  1533. break ;
  1534. case IFI_FONTSIM:
  1535. pdlg = new CFIFIFontSims(pcscontents,
  1536. (CFontIFIMetricsPage*) pcoowner) ;
  1537. break ;
  1538. case IFI_WINCHARSET:
  1539. pdlg = new CFIFIWinCharSet(pcscontents) ;
  1540. break ;
  1541. case IFI_WINPITCHFAM:
  1542. pdlg = new CFIFIWinPitchFamily(pcscontents) ;
  1543. break ;
  1544. case IFI_INFO:
  1545. pdlg = new CFIFIInfo(pcscontents) ;
  1546. break ;
  1547. case IFI_SELECTION:
  1548. pdlg = new CFIFISelection(pcscontents) ;
  1549. break ;
  1550. case IFI_BASELINE:
  1551. case IFI_ASPECT:
  1552. case IFI_CARET:
  1553. pdlg = new CFIFIPoint(pcscontents) ;
  1554. break ;
  1555. case IFI_FONTBOX:
  1556. pdlg = new CFIFIRectangle(pcscontents) ;
  1557. break ;
  1558. case IFI_PANOSE:
  1559. pdlg = new CFIFIPanose(pcscontents) ;
  1560. break ;
  1561. default:
  1562. ASSERT(0) ;
  1563. } ;
  1564. // raid 43541 Prefix
  1565. if(pdlg == NULL){
  1566. AfxMessageBox(IDS_ResourceError);
  1567. return false;
  1568. }
  1569. // Invoke the dialog box. The dlg will update pscontents. Return true if
  1570. // the dlg returns IDOK. Otherwise, return false.
  1571. if (pdlg->DoModal() == IDOK)
  1572. return true ;
  1573. else
  1574. return false ;
  1575. }
  1576. /////////////////////////////////////////////////////////////////////////////
  1577. // CFontIFIMetricsPage property page
  1578. IMPLEMENT_DYNCREATE(CFontIFIMetricsPage, CPropertyPage)
  1579. CFontIFIMetricsPage::CFontIFIMetricsPage() : CPropertyPage(CFontIFIMetricsPage::IDD)
  1580. {
  1581. //{{AFX_DATA_INIT(CFontIFIMetricsPage)
  1582. // NOTE: the ClassWizard will add member initialization here
  1583. //}}AFX_DATA_INIT
  1584. m_bInitDone = false ;
  1585. // Initialize as no enabled font simulations
  1586. m_cuiaFontSimStates.SetSize(3) ;
  1587. m_cuiaSimTouched.SetSize(3) ;
  1588. for (int n = 0 ; n < 3 ; n++)
  1589. m_cuiaFontSimStates[n] = m_cuiaSimTouched[n] = 0 ;
  1590. }
  1591. CFontIFIMetricsPage::~CFontIFIMetricsPage()
  1592. {
  1593. }
  1594. void CFontIFIMetricsPage::DoDataExchange(CDataExchange* pDX)
  1595. {
  1596. CPropertyPage::DoDataExchange(pDX);
  1597. //{{AFX_DATA_MAP(CFontIFIMetricsPage)
  1598. DDX_Control(pDX, IDC_IFIMetricsLst, m_cfelcIFIMetrics);
  1599. //}}AFX_DATA_MAP
  1600. }
  1601. BEGIN_MESSAGE_MAP(CFontIFIMetricsPage, CPropertyPage)
  1602. //{{AFX_MSG_MAP(CFontIFIMetricsPage)
  1603. //}}AFX_MSG_MAP
  1604. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  1605. END_MESSAGE_MAP()
  1606. /////////////////////////////////////////////////////////////////////////////
  1607. // CFontIFIMetricsPage message handlers
  1608. BOOL CFontIFIMetricsPage::OnInitDialog()
  1609. {
  1610. CPropertyPage::OnInitDialog();
  1611. // Initialize the list control. We want full row select. There are 45 rows
  1612. // and 2 columns. Nothing is togglable and the max length of an entry is
  1613. // 256 characters. Send change notifications and ignore insert/delete
  1614. // characters.
  1615. const int numfields = 45 ;
  1616. m_cfelcIFIMetrics.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 256,
  1617. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  1618. // Init and load the field names column; col 0. Start by loading an array
  1619. // with the field names.
  1620. CStringArray csacoldata ; // Holds column data for list control
  1621. csacoldata.SetSize(numfields) ;
  1622. IFILoadNamesData(csacoldata) ;
  1623. m_cfelcIFIMetrics.InitLoadColumn(0, csField, COMPUTECOLWIDTH, 20, false,
  1624. false, COLDATTYPE_STRING,
  1625. (CObArray*) &csacoldata) ;
  1626. // Tell the list control that some of the values must be editted with
  1627. // a subordinate dialog box.
  1628. CUIntArray cuia ;
  1629. cuia.SetSize(numfields) ;
  1630. cuia[IFI_FAMILYNAME] = cuia[IFI_FONTSIM] = 1 ;
  1631. cuia[IFI_WINCHARSET] = cuia[IFI_WINPITCHFAM] = cuia[IFI_INFO] = 1 ;
  1632. cuia[IFI_SELECTION] = cuia[IFI_BASELINE] = cuia[IFI_ASPECT] = 1 ;
  1633. cuia[IFI_CARET] = cuia[IFI_FONTBOX] = cuia[IFI_PANOSE] = 1 ;
  1634. m_cfelcIFIMetrics.ExtraInit_CustEditCol(1, this,
  1635. CEF_HASTOGGLECOLUMNS+CEF_CLICKONROW,
  1636. cuia, CIP_SubOrdDlgManager) ;
  1637. // Init and load the values column. The data must be pulled out of the
  1638. // FontInfo class / IFIMETRICS structure and converted to strings so that
  1639. // they can be loaded into the list control.
  1640. IFILoadValuesData(csacoldata) ;
  1641. m_cfelcIFIMetrics.InitLoadColumn(1, csValue, SETWIDTHTOREMAINDER, -37, true,
  1642. false, COLDATTYPE_CUSTEDIT,
  1643. (CObArray*) &csacoldata) ;
  1644. m_bInitDone = true ; // Initialization is done now
  1645. return TRUE; // return TRUE unless you set the focus to a control
  1646. // EXCEPTION: OCX Property Pages should return FALSE
  1647. }
  1648. void CFontIFIMetricsPage::IFILoadNamesData(CStringArray& csacoldata)
  1649. {
  1650. csacoldata[IFI_FAMILYNAME] = _T("dpwszFamilyName") ;
  1651. csacoldata[1] = _T("dpwszStyleName") ;
  1652. csacoldata[2] = _T("dpwszFaceName") ;
  1653. csacoldata[3] = _T("dpwszUniqueName") ;
  1654. csacoldata[IFI_FONTSIM] = _T("dpFontSim") ;
  1655. csacoldata[IFI_WINCHARSET] = _T("jWinCharSet") ;
  1656. csacoldata[IFI_WINPITCHFAM] = _T("jWinPitchAndFamily") ;
  1657. csacoldata[7] = _T("usWinWeight") ;
  1658. csacoldata[IFI_INFO] = _T("flInfo") ;
  1659. csacoldata[IFI_SELECTION] = _T("fsSelection") ;
  1660. csacoldata[10] = _T("fwdUnitsPerEm") ;
  1661. csacoldata[11] = _T("fwdLowestPPEm") ;
  1662. csacoldata[12] = _T("fwdWinAscender") ;
  1663. csacoldata[13] = _T("fwdWinDescender") ;
  1664. csacoldata[14] = _T("fwdAveCharWidth") ;
  1665. csacoldata[15] = _T("fwdMaxCharInc") ;
  1666. csacoldata[16] = _T("fwdCapHeight") ;
  1667. csacoldata[17] = _T("fwdXHeight") ;
  1668. csacoldata[18] = _T("fwdSubscriptXSize") ;
  1669. csacoldata[19] = _T("fwdSubscriptYSize") ;
  1670. csacoldata[20] = _T("fwdSubscriptXOffset") ;
  1671. csacoldata[21] = _T("fwdSubscriptYOffset") ;
  1672. csacoldata[22] = _T("fwdSuperscriptXSize") ;
  1673. csacoldata[23] = _T("fwdSuperscriptYSize") ;
  1674. csacoldata[24] = _T("fwdSuperscriptXOffset") ;
  1675. csacoldata[25] = _T("fwdSuperscriptYOffset") ;
  1676. csacoldata[26] = _T("fwdUnderscoreSize") ;
  1677. csacoldata[27] = _T("fwdUnderscorePosition") ;
  1678. csacoldata[28] = _T("fwdStrikeoutSize") ;
  1679. csacoldata[29] = _T("fwdStrikeoutPosition") ;
  1680. csacoldata[30] = _T("chFirstChar") ;
  1681. csacoldata[31] = _T("chLastChar") ;
  1682. csacoldata[32] = _T("chDefaultChar") ;
  1683. csacoldata[33] = _T("chBreakChar") ;
  1684. csacoldata[34] = _T("wcFirstChar") ;
  1685. csacoldata[35] = _T("wcLastChar") ;
  1686. csacoldata[36] = _T("wcDefaultChar") ;
  1687. csacoldata[37] = _T("wcBreakChar") ;
  1688. csacoldata[IFI_BASELINE] = _T("ptlBaseline") ;
  1689. csacoldata[IFI_ASPECT] = _T("ptlAspect") ;
  1690. csacoldata[IFI_CARET] = _T("ptlCaret") ;
  1691. csacoldata[IFI_FONTBOX] = _T("rclFontBox { L T R B }") ;
  1692. csacoldata[42] = _T("achVendId") ;
  1693. csacoldata[43] = _T("ulPanoseCulture") ;
  1694. csacoldata[IFI_PANOSE] = _T("panose") ;
  1695. }
  1696. void CFontIFIMetricsPage::IFILoadValuesData(CStringArray& csacoldata)
  1697. {
  1698. // Only the first family name is displayed on the IFI page
  1699. //raid 104822
  1700. if (m_pcfi->m_csaFamily.GetSize())
  1701. csacoldata[IFI_FAMILYNAME] = m_pcfi->m_csaFamily.GetAt(0) ;
  1702. csacoldata[1] = m_pcfi->m_csStyle ;
  1703. csacoldata[2] = m_pcfi->m_csFace ;
  1704. csacoldata[3] = m_pcfi->m_csUnique ;
  1705. // There is too much fontsim data to display on the IFI page so just
  1706. // describe it. A subordinate dialog box is used to display/edit the data.
  1707. csacoldata[IFI_FONTSIM] = _T("Font Simulation Dialog") ;
  1708. IFIMETRICS* pifi = &m_pcfi->m_IFIMETRICS ; // Minor optimization
  1709. // Translate jWinCharSet into a descriptive string that can be displayed.
  1710. csacoldata[IFI_WINCHARSET] = apstrWinCharSet[nWinCharSet - 1] ;
  1711. for (int n = 0 ; n < (nWinCharSet - 1) ; n++)
  1712. if (pifi->jWinCharSet == anWinCharSetVals[n]) {
  1713. csacoldata[IFI_WINCHARSET] = apstrWinCharSet[n] ;
  1714. break ;
  1715. } ;
  1716. // Before saving the WinPitch value, make sure that at least one of the FF
  1717. // flags is set. Use FF_DONTCARE (4) when none are set.
  1718. n = pifi->jWinPitchAndFamily ;
  1719. //raid 32675 : kill 2 lines
  1720. // if (n < 4)
  1721. // n |= 4 ;
  1722. csacoldata[IFI_WINPITCHFAM].Format(csHex, n) ;
  1723. csacoldata[7].Format("%hu", pifi->usWinWeight) ;
  1724. csacoldata[IFI_INFO].Format(csHex, pifi->flInfo) ;
  1725. csacoldata[IFI_SELECTION].Format(csHex, pifi->fsSelection) ;
  1726. // Format and save fwdUnitsPerEm, fwdLowestPPEm, fwdWinAscender,
  1727. // fwdWinDescender.
  1728. short* ps = &pifi->fwdUnitsPerEm ;
  1729. for (n = 0 ; n < 4 ; n++)
  1730. csacoldata[10+n].Format(csDec, *ps++) ;
  1731. ps = &pifi->fwdAveCharWidth;
  1732. for (n = 0 ; n < 16 ; n++)
  1733. csacoldata[14+n].Format(csDec, *ps++) ;
  1734. BYTE* pb = (BYTE*) &pifi->chFirstChar ;
  1735. for (n = 0 ; n < 4 ; n++)
  1736. csacoldata[30+n].Format(csDec, *pb++) ;
  1737. unsigned short* pus = (unsigned short*) &pifi->wcFirstChar ;
  1738. for (n = 0 ; n < 4 ; n++)
  1739. csacoldata[34+n].Format(csHex, *pus++) ;
  1740. // Format and save the points
  1741. csacoldata[IFI_BASELINE].Format(csPnt,
  1742. pifi->ptlBaseline.x, pifi->ptlBaseline.y) ;
  1743. csacoldata[IFI_ASPECT].Format(csPnt, pifi->ptlAspect.x, pifi->ptlAspect.y) ;
  1744. csacoldata[IFI_CARET].Format(csPnt, pifi->ptlCaret.x, pifi->ptlCaret.y) ;
  1745. csacoldata[IFI_FONTBOX].Format("{%d, %d, %d, %d}", pifi->rclFontBox.left,
  1746. pifi->rclFontBox.top, pifi->rclFontBox.right, pifi->rclFontBox.bottom) ;
  1747. csacoldata[42].Format("%c%c%c%c", pifi->achVendId[0], pifi->achVendId[1],
  1748. pifi->achVendId[2], pifi->achVendId[3]) ;
  1749. csacoldata[43].Format("%lu", pifi->ulPanoseCulture) ;
  1750. csacoldata[IFI_PANOSE].Format("{%d, %d, %d, %d, %d, %d, %d, %d, %d, %d}",
  1751. pifi->panose.bFamilyType, pifi->panose.bSerifStyle,
  1752. pifi->panose.bWeight, pifi->panose.bProportion,
  1753. pifi->panose.bContrast, pifi->panose.bStrokeVariation,
  1754. pifi->panose.bArmStyle, pifi->panose.bLetterform,
  1755. pifi->panose.bMidline, pifi->panose.bXHeight) ;
  1756. }
  1757. LRESULT CFontIFIMetricsPage::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  1758. {
  1759. // Do nothing if the page is not initialized yet.
  1760. if (!m_bInitDone)
  1761. return TRUE ;
  1762. // Mark the UFM as being dirty.
  1763. m_pcfi->Changed() ;
  1764. return TRUE ;
  1765. }
  1766. CWordArray* CFontIFIMetricsPage::GetFontSimDataPtr(int nid)
  1767. {
  1768. // Return a pointer to the requested font simulation data.
  1769. switch (nid) {
  1770. case CFontInfo::ItalicDiff:
  1771. return &m_cwaBold ;
  1772. case CFontInfo::BoldDiff:
  1773. return &m_cwaItalic ;
  1774. case CFontInfo::BothDiff:
  1775. return &m_cwaBoth ;
  1776. default:
  1777. ASSERT(0) ;
  1778. } ;
  1779. // This point should never be reached.
  1780. return &m_cwaBold ;
  1781. }
  1782. /******************************************************************************
  1783. CFontIFIMetricsPage::ValidateUFMFields
  1784. Validate all specified fields managed by this page. Return true if the user
  1785. wants to leave the UFM Editor open so that he can fix any problem. Otherwise,
  1786. return false.
  1787. ******************************************************************************/
  1788. bool CFontIFIMetricsPage::ValidateUFMFields()
  1789. {
  1790. // If the page was never initialize, its contents could not have changed
  1791. // so no validation is needed in this case.
  1792. if (!m_bInitDone)
  1793. return false ;
  1794. // Get the column of data that contains the fields we need to validate.
  1795. CStringArray csadata ;
  1796. m_cfelcIFIMetrics.GetColumnData((CObArray*) &csadata, 1) ;
  1797. CString csmsg ; // Holds error messages
  1798. CString cspage(_T("IFIMETRICS")) ;
  1799. LPTSTR apstrsflds[] = { // These string fields are checked below
  1800. _T("dpwszFamilyName"), _T("dpwszStyleName"), _T("dpwszFaceName"),
  1801. _T("dpwszUniqueName")
  1802. } ;
  1803. // Check to see if any of the string entries are blank/empty.
  1804. for (int n = 0 ; n < 4 ; n++) {
  1805. if (CheckUFMString(csadata[n],cspage,apstrsflds[n],n,m_cfelcIFIMetrics))
  1806. return true ;
  1807. } ;
  1808. // If this UFM describes a variable pitch font, make sure that
  1809. // fwdUnitsPerEm > 0.
  1810. if (m_pcfi->IsVariableWidth())
  1811. if (CheckUFMGrter0(csadata[10], cspage, _T("fwdUnitsPerEm"), 10,
  1812. m_cfelcIFIMetrics))
  1813. return true ;
  1814. LPTSTR apstrgflds[] = { // These fields are checked below
  1815. _T("fwdWinAscender"), _T("fwdWinDescender"), _T("fwdAveCharWidth"),
  1816. _T("fwdMaxCharInc"), _T("fwdUnderscoreSize"), _T("fwdStrikeoutSize")
  1817. } ;
  1818. int angfidxs[] = {12, 13, 14, 15, 26, 28} ;
  1819. // All of the following fields must be > 0.
  1820. LPTSTR pstr, pstr2 ;
  1821. for (int n2 = 0 ; n2 < 6 ; n2++) {
  1822. n = angfidxs[n2] ;
  1823. pstr = apstrgflds[n2] ;
  1824. if (CheckUFMGrter0(csadata[n], cspage, pstr, n, m_cfelcIFIMetrics))
  1825. return true ;
  1826. } ;
  1827. // fwdUnderscorePosition must be < 0
  1828. bool bres = atoi(csadata[27]) >= 0 ;
  1829. if (CheckUFMBool(bres, cspage, _T("fwdUnderscorePosition"), 27,
  1830. m_cfelcIFIMetrics, IDS_GrterEqZeroError))
  1831. return true ;
  1832. // fwdStrikeoutPosition must be >= 0
  1833. bres = atoi(csadata[29]) < 0 ;
  1834. if (CheckUFMBool(bres, cspage, _T("fwdStrikeoutPosition"), 29,
  1835. m_cfelcIFIMetrics, IDS_LessZeroError))
  1836. return true ;
  1837. LPTSTR apstrnzflds[] = { // These fields are checked below
  1838. _T("chFirstChar"), _T("chLastChar"), _T("chDefaultChar"),
  1839. _T("chBreakChar"), _T("wcFirstChar"), _T("wcLastChar"),
  1840. _T("wcDefaultChar"), _T("wcBreakChar")
  1841. } ;
  1842. // All of the following fields must be != 0.
  1843. int nfval ;
  1844. for (n = 30, n2 = 0 ; n <= 37 ; n++, n2++) {
  1845. pstr = csadata[n].GetBuffer(16) ;
  1846. if (*(pstr+1) != _T('x'))
  1847. nfval = atoi(pstr) ;
  1848. else
  1849. nfval = strtoul((pstr+2), &pstr2, 16) ;
  1850. pstr = apstrnzflds[n2] ;
  1851. if (CheckUFMNotEq0(nfval, cspage, pstr, n, m_cfelcIFIMetrics))
  1852. return true ;
  1853. } ;
  1854. // All tests passed or the user doesn't want to fix them so...
  1855. return false ;
  1856. }
  1857. /******************************************************************************
  1858. CFontIFIMetricsPage::SavePageData
  1859. Save the data in the IFIMETRICS page back into the CFontInfo class instance
  1860. that was used to load this page. See CFontInfoContainer::OnSaveDocument()
  1861. for more info.
  1862. Return true if there was a problem saving the data. Otherwise, return false.
  1863. ******************************************************************************/
  1864. bool CFontIFIMetricsPage::SavePageData()
  1865. {
  1866. // If the page was not initialized, nothing code have changed so do nothing.
  1867. if (!m_bInitDone)
  1868. return false ;
  1869. // Save the family name(s) if there are new ones.
  1870. int n, numents = (int)m_csaFamilyNames.GetSize() ;
  1871. if (numents > 0) {
  1872. m_pcfi->m_csaFamily.RemoveAll() ;
  1873. for (n = 0 ; n < numents ; n++)
  1874. m_pcfi->AddFamily(m_csaFamilyNames[n]) ;
  1875. } ;
  1876. // Get the contents of the values contents. This isn't needed for all
  1877. // fields but most of it will be needed.
  1878. CStringArray csadata ;
  1879. m_cfelcIFIMetrics.GetColumnData((CObArray*) &csadata, 1) ;
  1880. m_pcfi->m_csStyle = csadata[1] ;
  1881. m_pcfi->m_csFace = csadata[2] ;
  1882. m_pcfi->m_csUnique = csadata[3] ;
  1883. SaveFontSimulations() ; // Do just that
  1884. IFIMETRICS* pifi = &m_pcfi->m_IFIMETRICS ; // Minor optimization
  1885. LPTSTR pstr ;
  1886. // For the time being, dpCharSets should always be 0.
  1887. pifi->dpCharSets = 0 ;
  1888. // Set jWinCharSet. Don't change it if the setting is unknown.
  1889. for (n = 0 ; n < (nWinCharSet - 1) ; n++)
  1890. if (csadata[IFI_WINCHARSET] == apstrWinCharSet[n]) {
  1891. pifi->jWinCharSet = (BYTE)anWinCharSetVals[n] ;
  1892. break ;
  1893. } ;
  1894. pifi->jWinPitchAndFamily = (UCHAR) strtoul(csadata[IFI_WINPITCHFAM].Mid(2), &pstr, 16) ;
  1895. pifi->usWinWeight = (USHORT)atoi(csadata[7]) ;
  1896. pifi->flInfo = strtoul(csadata[IFI_INFO].Mid(2), &pstr, 16) ;
  1897. pifi->fsSelection = (USHORT) strtoul(csadata[IFI_SELECTION].Mid(2), &pstr, 16) ;
  1898. short* ps = &pifi->fwdUnitsPerEm ;
  1899. for (n = 0 ; n < 4 ; n++)
  1900. *ps++ = (SHORT)atoi(csadata[10+n]) ;
  1901. ps = &pifi->fwdAveCharWidth;
  1902. for (n = 0 ; n < 16 ; n++)
  1903. *ps++ = (SHORT)atoi(csadata[14+n]) ;
  1904. BYTE* pb = (BYTE*) &pifi->chFirstChar ;
  1905. for (n = 0 ; n < 4 ; n++)
  1906. *pb++ = (BYTE)atoi(csadata[30+n]) ;
  1907. unsigned short* pus = (unsigned short*) &pifi->wcFirstChar ;
  1908. for (n = 0 ; n < 4 ; n++)
  1909. *pus++ = (USHORT) strtoul(csadata[34+n].Mid(2), &pstr, 16) ;
  1910. // Format and save the points
  1911. CStringArray csa ;
  1912. POINTL* ppl = &pifi->ptlBaseline ;
  1913. for (n = 0 ; n < 3 ; n++, ppl++) {
  1914. ParseCompoundNumberString(csa, &csadata[IFI_BASELINE+n], 2) ;
  1915. ppl->x = atoi(csa[0]) ;
  1916. ppl->y = atoi(csa[1]) ;
  1917. } ;
  1918. ParseCompoundNumberString(csa, &csadata[IFI_FONTBOX], 4) ;
  1919. pifi->rclFontBox.left = atoi(csa[0]) ;
  1920. pifi->rclFontBox.top = atoi(csa[1]) ;
  1921. pifi->rclFontBox.right = atoi(csa[2]) ;
  1922. pifi->rclFontBox.bottom = atoi(csa[3]) ;
  1923. for (n = 0 ; n < 4 ; n++)
  1924. pifi->achVendId[n] = csadata[42].GetAt(n) ;
  1925. pifi->ulPanoseCulture = atoi(csadata[43]) ;
  1926. ParseCompoundNumberString(csa, &csadata[IFI_PANOSE], 10) ;
  1927. pb = (BYTE*) &pifi->panose ;
  1928. for (n = 0 ; n < 10 ; n++)
  1929. *pb++ = (BYTE)atoi(csa[n]) ;
  1930. // All went well so...
  1931. return false ;
  1932. }
  1933. void CFontIFIMetricsPage::SaveFontSimulations()
  1934. {
  1935. unsigned udataidx, unumdata, u2 ; // Each var defined below
  1936. CWordArray* pcwasimdata ;
  1937. CFontDifference* pcfdxx ;
  1938. CFontDifference*& pcfd = pcfdxx ;
  1939. // Loop through each simulation in the dialog box.
  1940. for (unsigned u = IDC_EnableItalicSim ; u <= IDC_EnableBISim ; u++) {
  1941. // Turn the control id into a data index that can be used to reference
  1942. // font simulation data in this and other class instances.
  1943. udataidx = u - IDC_EnableItalicSim ;
  1944. ASSERT(udataidx <= CFontInfo::BothDiff) ;
  1945. // If this simulation was not touched, it does not need to change.
  1946. //u2 = m_cuiaSimTouched[udataidx] ;
  1947. if (!m_cuiaSimTouched[udataidx])
  1948. continue ;
  1949. // Get a pointer to the current simulation in the CFontInfo class
  1950. // instance.
  1951. pcfd = NULL ;
  1952. m_pcfi->EnableSim(udataidx, TRUE, pcfd) ;
  1953. // If the simulation is enabled, make sure the CFontInfo class
  1954. // instance's simulation is loaded with the most up to date data.
  1955. if (m_cuiaFontSimStates[udataidx]) {
  1956. unumdata = auNumFontSimCtrls[udataidx] ;
  1957. pcwasimdata = GetFontSimDataPtr(udataidx) ;
  1958. for (u2 = 0 ; u2 < unumdata ; u2++)
  1959. pcfd->SetMetric(u2, (*pcwasimdata)[u2]) ;
  1960. // If the simulation is disabled, make sure the CFontInfo class instance
  1961. // gets rid of its pointer to this simulation and then free the memory
  1962. // allocated for it.
  1963. } else {
  1964. m_pcfi->EnableSim(udataidx, FALSE, pcfd) ;
  1965. delete pcfd ;
  1966. } ;
  1967. } ;
  1968. }
  1969. /////////////////////////////////////////////////////////////////////////////
  1970. // CFontExtMetricPage property page
  1971. IMPLEMENT_DYNCREATE(CFontExtMetricPage, CPropertyPage)
  1972. CFontExtMetricPage::CFontExtMetricPage() : CPropertyPage(CFontExtMetricPage::IDD)
  1973. {
  1974. //{{AFX_DATA_INIT(CFontExtMetricPage)
  1975. m_bSaveOnClose = FALSE;
  1976. //}}AFX_DATA_INIT
  1977. m_bInitDone = false ;
  1978. }
  1979. CFontExtMetricPage::~CFontExtMetricPage()
  1980. {
  1981. }
  1982. void CFontExtMetricPage::DoDataExchange(CDataExchange* pDX)
  1983. {
  1984. CPropertyPage::DoDataExchange(pDX);
  1985. //{{AFX_DATA_MAP(CFontExtMetricPage)
  1986. DDX_Control(pDX, IDC_ExtMetricsLst, m_cfelcExtMetrics);
  1987. DDX_Check(pDX, IDC_SaveCloseChk, m_bSaveOnClose);
  1988. //}}AFX_DATA_MAP
  1989. }
  1990. BEGIN_MESSAGE_MAP(CFontExtMetricPage, CPropertyPage)
  1991. //{{AFX_MSG_MAP(CFontExtMetricPage)
  1992. ON_BN_CLICKED(IDC_SaveCloseChk, OnSaveCloseChk)
  1993. //}}AFX_MSG_MAP
  1994. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  1995. END_MESSAGE_MAP()
  1996. /////////////////////////////////////////////////////////////////////////////
  1997. // CFontExtMetricPage message handlers
  1998. BOOL CFontExtMetricPage::OnInitDialog()
  1999. {
  2000. CPropertyPage::OnInitDialog();
  2001. // Initialize the list control. We want full row select. There are 24 rows
  2002. // and 2 columns. Nothing is togglable and the max length of an entry is
  2003. // 256 characters. Send change notifications and ignore insert/delete
  2004. // characters.
  2005. const int numfields = 24 ;
  2006. m_cfelcExtMetrics.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 256,
  2007. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  2008. // Init and load the field names column; col 0. Start by loading an array
  2009. // with the field names.
  2010. CStringArray csacoldata ; // Holds column data for list control
  2011. csacoldata.SetSize(numfields) ;
  2012. EXTLoadNamesData(csacoldata) ;
  2013. m_cfelcExtMetrics.InitLoadColumn(0, csField, COMPUTECOLWIDTH, 10, false,
  2014. false, COLDATTYPE_STRING,
  2015. (CObArray*) &csacoldata) ;
  2016. // Init and load the values column. The data must be pulled out of the
  2017. // FontInfo class / EXTMETRICS structure so that they can be loaded into
  2018. // the list control.
  2019. //
  2020. // The first (emSize) and last (emKernTracks) EXTMETRICS fields are not
  2021. // displayed. EmSize is not user editable and emKernTracks is not
  2022. // supported under NT.
  2023. CUIntArray cuiacoldata ;
  2024. cuiacoldata.SetSize(numfields) ;
  2025. PSHORT ps = &m_pcfi->m_EXTTEXTMETRIC.emPointSize ;
  2026. for (int n = 0 ; n < numfields ; n++, ps++)
  2027. cuiacoldata[n] = (unsigned) (int) *ps ;
  2028. m_cfelcExtMetrics.InitLoadColumn(1, csValue, SETWIDTHTOREMAINDER, -28, true,
  2029. false, COLDATTYPE_INT,
  2030. (CObArray*) &cuiacoldata) ;
  2031. // Determine if the ExtTextMetrics data is valid. Use this info to set or
  2032. // clear the "Save On Close" checkbox and also use it enable or disable the
  2033. // data list box.
  2034. m_bSaveOnClose = (m_pcfi->m_fEXTTEXTMETRIC != 0) ;
  2035. UpdateData(false) ;
  2036. m_cfelcExtMetrics.EnableWindow(m_bSaveOnClose) ;
  2037. m_bInitDone = true ; // Initialization is done now
  2038. return TRUE; // return TRUE unless you set the focus to a control
  2039. // EXCEPTION: OCX Property Pages should return FALSE
  2040. }
  2041. void CFontExtMetricPage::EXTLoadNamesData(CStringArray& csacoldata)
  2042. {
  2043. csacoldata[0] = _T("emPointSize") ;
  2044. csacoldata[1] = _T("emOrientation") ;
  2045. csacoldata[2] = _T("emMasterHeight") ;
  2046. csacoldata[3] = _T("emMinScale") ;
  2047. csacoldata[4] = _T("emMaxScale") ;
  2048. csacoldata[5] = _T("emMasterUnits") ;
  2049. csacoldata[6] = _T("emCapHeight") ;
  2050. csacoldata[7] = _T("emXHeight") ;
  2051. csacoldata[8] = _T("emLowerCaseAscent") ;
  2052. csacoldata[9] = _T("emLowerCaseDescent") ;
  2053. csacoldata[10] = _T("emSlant") ;
  2054. csacoldata[11] = _T("emSuperScript") ;
  2055. csacoldata[12] = _T("emSubScript") ;
  2056. csacoldata[13] = _T("emSuperScriptSize") ;
  2057. csacoldata[14] = _T("emSubScriptSize") ;
  2058. csacoldata[15] = _T("emUnderlineOffset") ;
  2059. csacoldata[16] = _T("emUnderlineWidth") ;
  2060. csacoldata[17] = _T("emDoubleUpperUnderlineOffset") ;
  2061. csacoldata[18] = _T("emDoubleLowerUnderlineOffset") ;
  2062. csacoldata[19] = _T("emDoubleUpperUnderlineWidth") ;
  2063. csacoldata[20] = _T("emDoubleLowerUnderlineWidth") ;
  2064. csacoldata[21] = _T("emStrikeOutOffset") ;
  2065. csacoldata[22] = _T("emStrikeOutWidth") ;
  2066. csacoldata[23] = _T("emKernPairs") ;
  2067. }
  2068. void CFontExtMetricPage::OnSaveCloseChk()
  2069. {
  2070. // Do nothing if the page is not initialized yet.
  2071. if (!m_bInitDone)
  2072. return ;
  2073. // Get the new state of the check box and use it to enable/disable the data
  2074. // list control.
  2075. UpdateData() ;
  2076. m_cfelcExtMetrics.EnableWindow(m_bSaveOnClose) ;
  2077. // Mark the UFM as being dirty.
  2078. m_pcfi->Changed() ;
  2079. }
  2080. LRESULT CFontExtMetricPage::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  2081. {
  2082. // Do nothing if the page is not initialized yet.
  2083. if (!m_bInitDone)
  2084. return TRUE ;
  2085. // Mark the UFM as being dirty.
  2086. m_pcfi->Changed() ;
  2087. return TRUE ;
  2088. }
  2089. /******************************************************************************
  2090. CFontExtMetricPage::ValidateUFMFields
  2091. Validate all specified fields managed by this page. Return true if the user
  2092. wants to leave the UFM Editor open so that he can fix any problem. Otherwise,
  2093. return true.
  2094. ******************************************************************************/
  2095. bool CFontExtMetricPage::ValidateUFMFields()
  2096. {
  2097. // If the page was never initialize, its contents could not have changed
  2098. // so no validation is needed in this case.
  2099. if (!m_bInitDone)
  2100. return false ;
  2101. // There is nothing that needs to be checked if the data on this page will
  2102. // not be saved.
  2103. UpdateData() ;
  2104. if (!m_bSaveOnClose)
  2105. return false ;
  2106. // Get the column of data that contains the fields we need to validate.
  2107. CUIntArray cuiadata ;
  2108. m_cfelcExtMetrics.GetColumnData((CObArray*) &cuiadata, 1) ;
  2109. CString csmsg ; // Holds error messages
  2110. CString cspage(_T("EXTMETRICS")) ;
  2111. // There are three fields that should only be validated if this is a
  2112. // variable pitch font.
  2113. if (m_pcfi->IsVariableWidth()) {
  2114. LPTSTR apstrsnzflds[] = {
  2115. _T("emMinScale"), _T("emMaxScale"), _T("emMasterUnits")
  2116. } ;
  2117. // Make sure that emMinScale != emMaxScale.
  2118. bool bres = ((int) cuiadata[3]) == ((int) cuiadata[4]) ;
  2119. CString cs = cspage + _T(" ") ;
  2120. cs += apstrsnzflds[0] ;
  2121. if (CheckUFMBool(bres, cs, apstrsnzflds[1], 3, m_cfelcExtMetrics,
  2122. IDS_EqFieldsError))
  2123. return true ;
  2124. // Now make sure that the apstrsnzflds fields are nonzero.
  2125. int n, n2 ;
  2126. for (n = 3, n2 = 0 ; n <= 5 ; n++, n2++) {
  2127. if (CheckUFMNotEq0(cuiadata[n], cspage, apstrsnzflds[n2], n,
  2128. m_cfelcExtMetrics))
  2129. return true ;
  2130. } ;
  2131. } ;
  2132. // emUnderLineOffset must be < 0
  2133. bool bres = ((int) cuiadata[15]) >= 0 ;
  2134. if (CheckUFMBool(bres, cspage, _T("emUnderLineOffset"), 15,
  2135. m_cfelcExtMetrics, IDS_GrterEqZeroError))
  2136. return true ;
  2137. // emUnderLineOffset must be nonzero
  2138. int ndata = (int) cuiadata[16] ;
  2139. if (CheckUFMNotEq0(ndata, cspage, _T("emUnderlineWidth"), 16,
  2140. m_cfelcExtMetrics))
  2141. return true ;
  2142. // emStrikeOutOffset must be > 0
  2143. CString cs ;
  2144. cs.Format("%d", (int) cuiadata[21]) ;
  2145. if (CheckUFMGrter0(cs, cspage, _T("emStrikeOutOffset"), 21,
  2146. m_cfelcExtMetrics))
  2147. return true ;
  2148. // emStrikeOutWidth must be > 0
  2149. cs.Format("%d", (int) cuiadata[22]) ;
  2150. if (CheckUFMGrter0(cs, cspage, _T("emStrikeOutWidth"), 22,
  2151. m_cfelcExtMetrics))
  2152. return true ;
  2153. // All tests passed or the user doesn't want to fix them so...
  2154. return false ;
  2155. }
  2156. /******************************************************************************
  2157. CFontExtMetricPage::SavePageData
  2158. Save the data in the EXTMETRICS page back into the CFontInfo class instance
  2159. that was used to load this page. See CFontInfoContainer::OnSaveDocument()
  2160. for more info.
  2161. Return true if there was a problem saving the data. Otherwise, return false.
  2162. ******************************************************************************/
  2163. bool CFontExtMetricPage::SavePageData()
  2164. {
  2165. // If the page was not initialized, nothing code have changed so do nothing.
  2166. if (!m_bInitDone)
  2167. return false ;
  2168. // Get the data out of the control and save it into the 24, editable
  2169. // EXTMETRICS fields.
  2170. CUIntArray cuiadata ;
  2171. m_cfelcExtMetrics.GetColumnData((CObArray*) &cuiadata, 1) ;
  2172. PSHORT ps = &m_pcfi->m_EXTTEXTMETRIC.emPointSize ;
  2173. for (int n = 0 ; n < 24 ; n++, ps++)
  2174. *ps = (short) cuiadata[n] ;
  2175. // All went well so...
  2176. return false ;
  2177. }
  2178. /******************************************************************************
  2179. CFontExtMetricPage::PreTranslateMessage
  2180. Looks for and process the context sensistive help key (F1).
  2181. ******************************************************************************/
  2182. BOOL CFontExtMetricPage::PreTranslateMessage(MSG* pMsg)
  2183. {
  2184. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) {
  2185. AfxGetApp()->WinHelp(HID_BASE_RESOURCE + IDR_FONT_VIEWER) ;
  2186. return TRUE ;
  2187. } ;
  2188. return CPropertyPage::PreTranslateMessage(pMsg);
  2189. }
  2190. /////////////////////////////////////////////////////////////////////////////
  2191. // CGenFlags dialog
  2192. CGenFlags::CGenFlags(CWnd* pParent /*=NULL*/)
  2193. : CDialog(CGenFlags::IDD, pParent)
  2194. {
  2195. ASSERT(0) ; // This routine should not be called
  2196. }
  2197. CGenFlags::CGenFlags(CString* pcsflags, CWnd* pParent /*= NULL*/)
  2198. : CDialog(CGenFlags::IDD, pParent)
  2199. {
  2200. //{{AFX_DATA_INIT(CGenFlags)
  2201. // NOTE: the ClassWizard will add member initialization here
  2202. //}}AFX_DATA_INIT
  2203. // Save the flags string pointer
  2204. m_pcsFlags = pcsflags ;
  2205. }
  2206. void CGenFlags::DoDataExchange(CDataExchange* pDX)
  2207. {
  2208. CDialog::DoDataExchange(pDX);
  2209. //{{AFX_DATA_MAP(CGenFlags)
  2210. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2211. //}}AFX_DATA_MAP
  2212. }
  2213. BEGIN_MESSAGE_MAP(CGenFlags, CDialog)
  2214. //{{AFX_MSG_MAP(CGenFlags)
  2215. //}}AFX_MSG_MAP
  2216. END_MESSAGE_MAP()
  2217. /////////////////////////////////////////////////////////////////////////////
  2218. // CGenFlags message handlers
  2219. BOOL CGenFlags::OnInitDialog()
  2220. {
  2221. CDialog::OnInitDialog() ;
  2222. // Allocate and load the field names array
  2223. CStringArray csafieldnames ;
  2224. csafieldnames.SetSize(3) ;
  2225. csafieldnames[0] = _T("UFM_SOFT") ;
  2226. csafieldnames[1] = _T("UFM_CART") ;
  2227. csafieldnames[2] = _T("UFM_SCALABLE") ;
  2228. // Allocate and fill the flag groupings array. There are 2 flag groups in
  2229. // this flag dword.
  2230. CUIntArray cuiaflaggroupings ;
  2231. cuiaflaggroupings.SetSize(4) ;
  2232. cuiaflaggroupings[0] = 0 ;
  2233. cuiaflaggroupings[1] = 1 ;
  2234. cuiaflaggroupings[2] = 2 ;
  2235. cuiaflaggroupings[3] = 2 ;
  2236. // Initialize and load the flags list.
  2237. m_cflbFlags.Init2(csafieldnames, m_pcsFlags, cuiaflaggroupings, 2,
  2238. lptstrSet, 105, false) ;
  2239. return TRUE ; // return TRUE unless you set the focus to a control
  2240. // EXCEPTION: OCX Property Pages should return FALSE
  2241. }
  2242. void CGenFlags::OnOK()
  2243. {
  2244. // Update the flag string.
  2245. m_cflbFlags.GetNewFlagString(m_pcsFlags) ;
  2246. CDialog::OnOK();
  2247. }
  2248. /////////////////////////////////////////////////////////////////////////////
  2249. // CHdrTypes dialog
  2250. CHdrTypes::CHdrTypes(CWnd* pParent /*=NULL*/)
  2251. : CDialog(CHdrTypes::IDD, pParent)
  2252. {
  2253. ASSERT(0) ; // This routine should not be called
  2254. }
  2255. CHdrTypes::CHdrTypes(CString* pcsflags, CWnd* pParent /*=NULL*/)
  2256. : CDialog(CHdrTypes::IDD, pParent)
  2257. {
  2258. //{{AFX_DATA_INIT(CHdrTypes)
  2259. // NOTE: the ClassWizard will add member initialization here
  2260. //}}AFX_DATA_INIT
  2261. // Save the flags string pointer
  2262. m_pcsFlags = pcsflags ;
  2263. }
  2264. void CHdrTypes::DoDataExchange(CDataExchange* pDX)
  2265. {
  2266. CDialog::DoDataExchange(pDX);
  2267. //{{AFX_DATA_MAP(CHdrTypes)
  2268. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2269. //}}AFX_DATA_MAP
  2270. }
  2271. BEGIN_MESSAGE_MAP(CHdrTypes, CDialog)
  2272. //{{AFX_MSG_MAP(CHdrTypes)
  2273. //}}AFX_MSG_MAP
  2274. END_MESSAGE_MAP()
  2275. /////////////////////////////////////////////////////////////////////////////
  2276. // CHdrTypes message handlers
  2277. BOOL CHdrTypes::OnInitDialog()
  2278. {
  2279. CDialog::OnInitDialog();
  2280. // Allocate and load the field names array. While doing this, determine the
  2281. // current (single) flag setting.
  2282. CStringArray csafieldnames ;
  2283. csafieldnames.SetSize(nNumValidWTypes) ;
  2284. DWORD dwsettings, dwbit = 1 ;
  2285. for (int n = 0 ; n < nNumValidWTypes ; n++, dwbit <<= 1) {
  2286. csafieldnames[n] = apstrUniWTypes[n] ;
  2287. if (csafieldnames[n] == *m_pcsFlags)
  2288. dwsettings = dwbit ;
  2289. } ;
  2290. // Allocate and fill the flag groupings array. There is only one flag
  2291. // group.
  2292. CUIntArray cuiaflaggroupings ;
  2293. cuiaflaggroupings.SetSize(2) ;
  2294. cuiaflaggroupings[0] = 0 ;
  2295. cuiaflaggroupings[1] = nNumValidWTypes - 1 ;
  2296. // Initialize the flags list.
  2297. m_cflbFlags.Init(csafieldnames, dwsettings, cuiaflaggroupings, 1, lptstrSet,
  2298. 110, true) ;
  2299. return TRUE; // return TRUE unless you set the focus to a control
  2300. // EXCEPTION: OCX Property Pages should return FALSE
  2301. }
  2302. void CHdrTypes::OnOK()
  2303. {
  2304. // Get the value of the single flag that was selected.
  2305. DWORD dwflag = m_cflbFlags.GetNewFlagDWord() ;
  2306. // Use the selected flag to determine the new flag name to display.
  2307. DWORD dwbit = 1 ;
  2308. for (int n = 0 ; n < nNumValidWTypes ; n++, dwbit <<= 1) {
  2309. if (dwbit == dwflag) {
  2310. *m_pcsFlags = apstrUniWTypes[n] ;
  2311. break ;
  2312. } ;
  2313. } ;
  2314. // Blow if a matching flag was not found. This should never happen.
  2315. ASSERT(n < nNumValidWTypes) ;
  2316. CDialog::OnOK();
  2317. }
  2318. /////////////////////////////////////////////////////////////////////////////
  2319. // CHdrCaps dialog
  2320. CHdrCaps::CHdrCaps(CWnd* pParent /*=NULL*/)
  2321. : CDialog(CHdrCaps::IDD, pParent)
  2322. {
  2323. ASSERT(0) ; // This routine should not be called
  2324. }
  2325. CHdrCaps::CHdrCaps(CString* pcsflags, CWnd* pParent /*=NULL*/)
  2326. : CDialog(CHdrCaps::IDD, pParent)
  2327. {
  2328. //{{AFX_DATA_INIT(CHdrCaps)
  2329. // NOTE: the ClassWizard will add member initialization here
  2330. //}}AFX_DATA_INIT
  2331. // Save the flags string pointer
  2332. m_pcsFlags = pcsflags ;
  2333. }
  2334. void CHdrCaps::DoDataExchange(CDataExchange* pDX)
  2335. {
  2336. CDialog::DoDataExchange(pDX);
  2337. //{{AFX_DATA_MAP(CHdrCaps)
  2338. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2339. //}}AFX_DATA_MAP
  2340. }
  2341. BEGIN_MESSAGE_MAP(CHdrCaps, CDialog)
  2342. //{{AFX_MSG_MAP(CHdrCaps)
  2343. //}}AFX_MSG_MAP
  2344. END_MESSAGE_MAP()
  2345. /////////////////////////////////////////////////////////////////////////////
  2346. // CHdrCaps message handlers
  2347. BOOL CHdrCaps::OnInitDialog()
  2348. {
  2349. CDialog::OnInitDialog();
  2350. // Allocate and load the field names array
  2351. CStringArray csafieldnames ;
  2352. csafieldnames.SetSize(7) ;
  2353. csafieldnames[0] = _T("DF_NOITALIC") ;
  2354. csafieldnames[1] = _T("DF_NOUNDER") ;
  2355. csafieldnames[2] = _T("DF_XM_CR") ;
  2356. csafieldnames[3] = _T("DF_NO_BOLD") ;
  2357. csafieldnames[4] = _T("DF_NO_DOUBLE_UNDERLINE") ;
  2358. csafieldnames[5] = _T("DF_NO_STRIKETHRU") ;
  2359. csafieldnames[6] = _T("DF_BKSP_OK") ;
  2360. // Allocate flag groupings array. Don't put anything in it because any
  2361. // combination of flags can be set.
  2362. CUIntArray cuiaflaggroupings ;
  2363. // Initialize and load the flags list.
  2364. m_cflbFlags.Init2(csafieldnames, m_pcsFlags, cuiaflaggroupings, 0,
  2365. lptstrSet, 123, false) ;
  2366. return TRUE; // return TRUE unless you set the focus to a control
  2367. // EXCEPTION: OCX Property Pages should return FALSE
  2368. }
  2369. void CHdrCaps::OnOK()
  2370. {
  2371. // Update the flag string.
  2372. m_cflbFlags.GetNewFlagString(m_pcsFlags) ;
  2373. CDialog::OnOK();
  2374. }
  2375. /////////////////////////////////////////////////////////////////////////////
  2376. // CFIFIFamilyNames dialog
  2377. CFIFIFamilyNames::CFIFIFamilyNames(CWnd* pParent /*=NULL*/)
  2378. : CDialog(CFIFIFamilyNames::IDD, pParent)
  2379. {
  2380. ASSERT(0) ; // This routine should not be called
  2381. }
  2382. CFIFIFamilyNames::CFIFIFamilyNames(CString* pcsfirstname,
  2383. CFontIFIMetricsPage* pcfimp,
  2384. CWnd* pParent /*=NULL*/)
  2385. : CDialog(CFIFIFamilyNames::IDD, pParent)
  2386. {
  2387. //{{AFX_DATA_INIT(CFIFIFamilyNames)
  2388. // NOTE: the ClassWizard will add member initialization here
  2389. //}}AFX_DATA_INIT
  2390. m_bInitDone = m_bChanged = false ;
  2391. m_pcsFirstName = pcsfirstname ;
  2392. m_pcfimp = pcfimp ;
  2393. }
  2394. void CFIFIFamilyNames::DoDataExchange(CDataExchange* pDX)
  2395. {
  2396. CDialog::DoDataExchange(pDX);
  2397. //{{AFX_DATA_MAP(CFIFIFamilyNames)
  2398. DDX_Control(pDX, IDC_NamesLst, m_cfelcFamilyNames);
  2399. //}}AFX_DATA_MAP
  2400. }
  2401. BEGIN_MESSAGE_MAP(CFIFIFamilyNames, CDialog)
  2402. //{{AFX_MSG_MAP(CFIFIFamilyNames)
  2403. //}}AFX_MSG_MAP
  2404. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  2405. END_MESSAGE_MAP()
  2406. /////////////////////////////////////////////////////////////////////////////
  2407. // CFIFIFamilyNames message handlers
  2408. BOOL CFIFIFamilyNames::OnInitDialog()
  2409. {
  2410. CDialog::OnInitDialog();
  2411. // Get the current list of family names. If the names have been changed
  2412. // before in this editting session, the names will be in this dialog's
  2413. // parent page. If not, the names are in the associated UFM.
  2414. CStringArray csadata, *pcsadata ;
  2415. if (m_pcfimp->m_csaFamilyNames.GetSize())
  2416. pcsadata = &m_pcfimp->m_csaFamilyNames ;
  2417. else
  2418. pcsadata = &m_pcfimp->m_pcfi->m_csaFamily ;
  2419. int numfields = (int)pcsadata->GetSize() ;
  2420. // Initialize the list control. We want full row select. Nothing is
  2421. // togglable and the max length of an entry is 256 characters.
  2422. m_cfelcFamilyNames.InitControl(LVS_EX_FULLROWSELECT, numfields, 1, 0, 256,
  2423. MF_SENDCHANGEMESSAGE) ;
  2424. // Init and load the family names column.
  2425. m_cfelcFamilyNames.InitLoadColumn(0, _T("Name"), SETWIDTHTOREMAINDER, 0,
  2426. true, true, COLDATTYPE_STRING,
  2427. (CObArray*) pcsadata) ;
  2428. m_bInitDone = true ; // Initialization is done now
  2429. return TRUE; // return TRUE unless you set the focus to a control
  2430. // EXCEPTION: OCX Property Pages should return FALSE
  2431. }
  2432. void CFIFIFamilyNames::OnOK()
  2433. {
  2434. // If nothing changed, just shut down the dialog box.
  2435. if (!m_bChanged)
  2436. CDialog::OnOK() ;
  2437. // Get the new names out of the list control and delete any empty entries.
  2438. CStringArray csa ;
  2439. m_cfelcFamilyNames.GetColumnData((CObArray*) &csa, 0) ;
  2440. for (int n = (int)csa.GetSize() - 1 ; n >= 0 ; n--)
  2441. if (csa[n].IsEmpty())
  2442. csa.RemoveAt(n) ;
  2443. // If there are no names left in the list, complain, and return without
  2444. // closing the dialog.
  2445. if (csa.GetSize() == 0) {
  2446. AfxMessageBox(IDS_NoFamilyNamesError, MB_ICONEXCLAMATION) ;
  2447. return ;
  2448. } ;
  2449. // Save the new array of family names into the IFI page's member variable.
  2450. // (The new data is saved there instead of in the UFM because the user may
  2451. // decide later that he doesn't want to save his UFM changes.) Then update
  2452. // the string containing the first family name so that it can be displayed
  2453. // on the IFI page.
  2454. m_pcfimp->m_csaFamilyNames.RemoveAll() ;
  2455. m_pcfimp->m_csaFamilyNames.Copy(csa) ;
  2456. *m_pcsFirstName = csa[0] ;
  2457. // Mark the UFM dirty and wrap things up.
  2458. m_pcfimp->m_pcfi->Changed() ;
  2459. CDialog::OnOK();
  2460. }
  2461. LRESULT CFIFIFamilyNames::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  2462. {
  2463. // Do nothing if the page is not initialized yet.
  2464. if (!m_bInitDone)
  2465. return TRUE ;
  2466. // Note that the family names list has changed.
  2467. m_bChanged = true ;
  2468. return TRUE ;
  2469. }
  2470. /////////////////////////////////////////////////////////////////////////////
  2471. // CFIFIFontSims dialog
  2472. CFIFIFontSims::CFIFIFontSims(CWnd* pParent /*=NULL*/)
  2473. : CDialog(CFIFIFontSims::IDD, pParent)
  2474. {
  2475. ASSERT(0) ;
  2476. }
  2477. CFIFIFontSims::CFIFIFontSims(CString* pcsfontsimdata,
  2478. CFontIFIMetricsPage* pcfimp,
  2479. CWnd* pParent /*=NULL*/)
  2480. : CDialog(CFIFIFontSims::IDD, pParent)
  2481. {
  2482. //{{AFX_DATA_INIT(CFIFIFontSims)
  2483. // NOTE: the ClassWizard will add member initialization here
  2484. //}}AFX_DATA_INIT
  2485. m_pcsFontSimData = pcsfontsimdata ;
  2486. m_pcfimp = pcfimp ;
  2487. m_bInitDone = m_bChanged = false ;
  2488. // Initialze the "font sim groups have been loaded" flags array.
  2489. int numgrps = CFontInfo::BothDiff - CFontInfo::ItalicDiff + 1 ;
  2490. m_cuiaFontSimGrpLoaded.SetSize(numgrps) ;
  2491. for (int n = 0 ; n < numgrps ; n++)
  2492. m_cuiaFontSimGrpLoaded[n] = 0 ;
  2493. }
  2494. void CFIFIFontSims::DoDataExchange(CDataExchange* pDX)
  2495. {
  2496. CDialog::DoDataExchange(pDX);
  2497. //{{AFX_DATA_MAP(CFIFIFontSims)
  2498. // NOTE: the ClassWizard will add DDX and DDV calls here
  2499. //}}AFX_DATA_MAP
  2500. }
  2501. BEGIN_MESSAGE_MAP(CFIFIFontSims, CDialog)
  2502. //{{AFX_MSG_MAP(CFIFIFontSims)
  2503. //}}AFX_MSG_MAP
  2504. ON_CONTROL_RANGE(BN_CLICKED, IDC_EnableItalicSim, IDC_EnableBISim, OnSetAnySimState)
  2505. ON_CONTROL_RANGE(EN_CHANGE, IDC_ItalicWeight, IDC_BoldItalicSlant, OnChangeAnyNumber)
  2506. END_MESSAGE_MAP()
  2507. /////////////////////////////////////////////////////////////////////////////
  2508. // CFIFIFontSims message handlers
  2509. BOOL CFIFIFontSims::OnInitDialog()
  2510. {
  2511. CDialog::OnInitDialog();
  2512. // Loop through each set of font simulation controls to enable/disable
  2513. // them and load them from the appropriate source when necessary.
  2514. for (int n = IDC_EnableItalicSim ; n <= IDC_EnableBISim ; n++) {
  2515. InitSetCheckBox(n) ;
  2516. OnSetAnySimState(n) ; // DEAD_BUG - May not be necessary.
  2517. }
  2518. m_bInitDone = true ; // Initialization done now
  2519. return TRUE; // return TRUE unless you set the focus to a control
  2520. // EXCEPTION: OCX Property Pages should return FALSE
  2521. }
  2522. void CFIFIFontSims::OnOK()
  2523. {
  2524. unsigned udataidx, ufirstdataid, unumdata, u2 ; // Each var defined below
  2525. CWordArray* pcwasimdata ;
  2526. // If nothing changed, call OnCancel() to close just the dialog box so
  2527. // that the program doesn't think that any of the font simulations changed.
  2528. // This will keep the programming from prompting the user to save the UFM
  2529. // even though nothing has actually changed.
  2530. if (!m_bChanged) {
  2531. CDialog::OnCancel() ;
  2532. return ;
  2533. } ;
  2534. // Loop through each simulation in the dialog box.
  2535. for (unsigned u = IDC_EnableItalicSim ; u <= IDC_EnableBISim ; u++) {
  2536. // Turn the control id into a data index that can be used to reference
  2537. // font simulation data in this and other class instances.
  2538. udataidx = u - IDC_EnableItalicSim ;
  2539. ASSERT(udataidx <= CFontInfo::BothDiff) ;
  2540. // Save the state of this simulation but don't save any of its data if
  2541. // it is disabled.
  2542. m_pcfimp->m_cuiaFontSimStates[udataidx] = IsDlgButtonChecked(u) ;
  2543. if (m_pcfimp->m_cuiaFontSimStates[udataidx] == 0)
  2544. continue ;
  2545. // Get the ID of the first edit box in the simulation and the number of
  2546. // pieces of data (ie, edit boxes) in this simulation.
  2547. ufirstdataid = auBaseFontSimCtrlID[udataidx] ;
  2548. unumdata = auNumFontSimCtrls[udataidx] ;
  2549. // The data is saved in the class' parent so that the CFontInfo data is
  2550. // not changed before the user has agreed that the new data should be
  2551. // saved. Get a pointer to the appropriate array and make sure it is
  2552. // sized correctly.
  2553. pcwasimdata = m_pcfimp->GetFontSimDataPtr(udataidx) ;
  2554. pcwasimdata->SetSize(unumdata) ;
  2555. // Get the data in this font simulation group.
  2556. for (u2 = 0 ; u2 < unumdata ; u2++)
  2557. (*pcwasimdata)[u2] = (USHORT)GetDlgItemInt(ufirstdataid + u2, NULL, false) ;
  2558. } ;
  2559. CDialog::OnOK() ;
  2560. }
  2561. /******************************************************************************
  2562. CFIFIFontSims::OnSetAnySimState
  2563. Called when any simulation is enabled or disabled. Updates the UI
  2564. appropriately. Decode which simulation it is, and init any values we
  2565. ought to.
  2566. ******************************************************************************/
  2567. void CFIFIFontSims::OnSetAnySimState(unsigned ucontrolid)
  2568. {
  2569. // Get the state of the check box.
  2570. unsigned ucheckboxstate = IsDlgButtonChecked(ucontrolid) ;
  2571. // Turn the control id into a data index that can be used to reference font
  2572. // simulation data in this and other class instances.
  2573. unsigned udataidx = ucontrolid - IDC_EnableItalicSim ;
  2574. ASSERT(udataidx <= CFontInfo::BothDiff) ;
  2575. // Get the ID of the first edit box in the simulation whose state has
  2576. // changed and the number of pieces of data (ie, edit boxes) in this
  2577. // simulation.
  2578. unsigned ufirstdataid = auBaseFontSimCtrlID[udataidx] ;
  2579. unsigned unumdata = auNumFontSimCtrls[udataidx] ;
  2580. // Set the state of the corresponding edit boxes to that of their check
  2581. // box.
  2582. for (unsigned u = 0 ; u < unumdata ; u++)
  2583. GetDlgItem(ufirstdataid + u)->EnableWindow(ucheckboxstate) ;
  2584. // If this dialog box has been initialized, set the changed flag and set the
  2585. // touched flag for this simulation.
  2586. if (m_bInitDone) {
  2587. m_bChanged = true ;
  2588. m_pcfimp->m_cuiaSimTouched[udataidx] = 1 ;
  2589. } ;
  2590. // Nothing else needs to be done in one of two cases. First, if the
  2591. // controls were just disabled. Second, if the controls have already
  2592. // been loaded. Return if either is the case.
  2593. if (ucheckboxstate == 0 || m_cuiaFontSimGrpLoaded[udataidx] != 0)
  2594. return ;
  2595. // Note that the font sim group is about to be loaded so that it won't
  2596. // happen again.
  2597. m_cuiaFontSimGrpLoaded[udataidx] = 1 ;
  2598. // Determine where to get the data for this font sim group. The data in this
  2599. // class' parent class (CFontIFIMetricsPage) always takes precedence if it
  2600. // is there because it will be the most up to date. It is possible that
  2601. // there is no data to load. In this case, load the sim group with default
  2602. // data from the IFIMETRICS structure and then return.
  2603. CWordArray* pcwasimdata = m_pcfimp->GetFontSimDataPtr(udataidx) ;
  2604. if (pcwasimdata->GetSize() == 0) {
  2605. if (m_pcfimp->m_pcfi->Diff(udataidx) == NULL) {
  2606. IFIMETRICS* pim = &m_pcfimp->m_pcfi->m_IFIMETRICS ;
  2607. SetDlgItemInt(ufirstdataid + 0, pim->usWinWeight) ;
  2608. SetDlgItemInt(ufirstdataid + 1, pim->fwdMaxCharInc) ;
  2609. SetDlgItemInt(ufirstdataid + 2, pim->fwdAveCharWidth) ;
  2610. if (ucontrolid != IDC_EnableBoldSim)
  2611. SetDlgItemInt(ufirstdataid + 3, 175) ;
  2612. return ;
  2613. } ;
  2614. pcwasimdata = m_pcfimp->m_pcfi->GetFontSimDataPtr(udataidx) ;
  2615. } ;
  2616. // Load the controls that will display the font sim group's data with
  2617. // the existing font sim data.
  2618. //RAID 43542) PREFIX
  2619. if(pcwasimdata == NULL ){
  2620. AfxMessageBox(IDS_ResourceError);
  2621. return ;
  2622. }
  2623. // END RAID
  2624. for (u = 0 ; u < unumdata ; u++)
  2625. SetDlgItemInt(ufirstdataid + u, (*pcwasimdata)[u]) ;
  2626. // We're done now so...
  2627. return ;
  2628. }
  2629. void CFIFIFontSims::OnChangeAnyNumber(unsigned ucontrolid)
  2630. {
  2631. // Do nothing if this dialog box has not been initialized.
  2632. if (!m_bInitDone)
  2633. return ;
  2634. // Set the changed flag.
  2635. m_bChanged = true ;
  2636. // Determine which simulation was just changed and set its touched flag.
  2637. int n = 0 ;
  2638. if (ucontrolid >= auBaseFontSimCtrlID[1])
  2639. n++ ;
  2640. if (ucontrolid >= auBaseFontSimCtrlID[2])
  2641. n++ ;
  2642. m_pcfimp->m_cuiaSimTouched[n] = 1 ;
  2643. }
  2644. /////////////////////////////////////////////////////////////////////////////
  2645. // CFIFIFontSims implementation
  2646. void CFIFIFontSims::InitSetCheckBox(int ncontrolid)
  2647. {
  2648. // Turn the control id into a data index that can be used to reference font
  2649. // simulation data in this and other class instances.
  2650. int ndataidx = ncontrolid - IDC_EnableItalicSim ;
  2651. // Determine what data to use to set/clear this check box. The data in this
  2652. // class' parent class (CFontIFIMetricsPage) always takes precedence if it
  2653. // is there because it will be the most up to date.
  2654. int ncheckboxstate ;
  2655. CWordArray* pcwasimdata = m_pcfimp->GetFontSimDataPtr(ndataidx) ;
  2656. if (pcwasimdata->GetSize() > 0)
  2657. ncheckboxstate = (int) m_pcfimp->m_cuiaFontSimStates[ndataidx] ;
  2658. else
  2659. ncheckboxstate = m_pcfimp->m_pcfi->Diff(ndataidx) != NULL ;
  2660. // Now that the check box's state is known, set it.
  2661. CheckDlgButton(ncontrolid, ncheckboxstate) ;
  2662. }
  2663. /******************************************************************************
  2664. CFontIFIMetricsPage::PreTranslateMessage
  2665. Looks for and process the context sensistive help key (F1).
  2666. ******************************************************************************/
  2667. BOOL CFontIFIMetricsPage::PreTranslateMessage(MSG* pMsg)
  2668. {
  2669. if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) {
  2670. AfxGetApp()->WinHelp(HID_BASE_RESOURCE + IDR_FONT_VIEWER) ;
  2671. return TRUE ;
  2672. } ;
  2673. return CPropertyPage::PreTranslateMessage(pMsg);
  2674. }
  2675. /////////////////////////////////////////////////////////////////////////////
  2676. // CFIFIWinCharSet dialog
  2677. CFIFIWinCharSet::CFIFIWinCharSet(CWnd* pParent /*=NULL*/)
  2678. : CDialog(CHdrTypes::IDD, pParent)
  2679. {
  2680. ASSERT(0) ; // This routine should not be called
  2681. }
  2682. CFIFIWinCharSet::CFIFIWinCharSet(CString* pcsflags, CWnd* pParent /*=NULL*/)
  2683. : CDialog(CFIFIWinCharSet::IDD, pParent)
  2684. {
  2685. //{{AFX_DATA_INIT(CFIFIWinCharSet)
  2686. // NOTE: the ClassWizard will add member initialization here
  2687. //}}AFX_DATA_INIT
  2688. // Save the flags string pointer
  2689. m_pcsFlags = pcsflags ;
  2690. }
  2691. void CFIFIWinCharSet::DoDataExchange(CDataExchange* pDX)
  2692. {
  2693. CDialog::DoDataExchange(pDX);
  2694. //{{AFX_DATA_MAP(CFIFIWinCharSet)
  2695. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2696. //}}AFX_DATA_MAP
  2697. }
  2698. BEGIN_MESSAGE_MAP(CFIFIWinCharSet, CDialog)
  2699. //{{AFX_MSG_MAP(CFIFIWinCharSet)
  2700. //}}AFX_MSG_MAP
  2701. END_MESSAGE_MAP()
  2702. /////////////////////////////////////////////////////////////////////////////
  2703. // CFIFIWinCharSet message handlers
  2704. BOOL CFIFIWinCharSet::OnInitDialog()
  2705. {
  2706. CDialog::OnInitDialog();
  2707. // Don't display the unknown field name. Compute a new count to make this
  2708. // happen.
  2709. int numfields = nWinCharSet - 1 ;
  2710. // Allocate and load the field names array. While doing this, determine the
  2711. // current (single) flag setting.
  2712. CStringArray csafieldnames ;
  2713. csafieldnames.SetSize(numfields) ;
  2714. DWORD dwsettings, dwbit = 1 ;
  2715. bool bmatchfound = false ;
  2716. for (int n = 0 ; n < numfields ; n++, dwbit <<= 1) {
  2717. csafieldnames[n] = apstrWinCharSet[n] ;
  2718. if (csafieldnames[n] == *m_pcsFlags) {
  2719. dwsettings = dwbit ;
  2720. bmatchfound = true ;
  2721. } ;
  2722. } ;
  2723. // Assert if no matching setting was found.
  2724. ASSERT(bmatchfound) ; //delte the line : raid 104822
  2725. // Allocate and fill the flag groupings array. There is only one flag
  2726. // group.
  2727. CUIntArray cuiaflaggroupings ;
  2728. cuiaflaggroupings.SetSize(2) ;
  2729. cuiaflaggroupings[0] = 0 ;
  2730. cuiaflaggroupings[1] = numfields - 1 ;
  2731. // Initialize the flags list.
  2732. m_cflbFlags.Init(csafieldnames, dwsettings, cuiaflaggroupings, 1, lptstrSet,
  2733. 109, true) ;
  2734. return TRUE; // return TRUE unless you set the focus to a control
  2735. // EXCEPTION: OCX Property Pages should return FALSE
  2736. }
  2737. void CFIFIWinCharSet::OnOK()
  2738. {
  2739. // Get the value of the single flag that was selected.
  2740. DWORD dwflag = m_cflbFlags.GetNewFlagDWord() ;
  2741. // Use the selected flag to determine the new flag name to display.
  2742. DWORD dwbit = 1 ;
  2743. for (int n = 0 ; n < nWinCharSet ; n++, dwbit <<= 1) {
  2744. if (dwbit == dwflag) {
  2745. *m_pcsFlags = apstrWinCharSet[n] ;
  2746. break ;
  2747. } ;
  2748. } ;
  2749. // Blow if a matching flag was not found. This should never happen.
  2750. ASSERT(n < nWinCharSet) ;
  2751. CDialog::OnOK();
  2752. }
  2753. /////////////////////////////////////////////////////////////////////////////
  2754. // CFIFIWinPitchFamily dialog
  2755. CFIFIWinPitchFamily::CFIFIWinPitchFamily(CWnd* pParent /*=NULL*/)
  2756. : CDialog(CFIFIWinPitchFamily::IDD, pParent)
  2757. {
  2758. ASSERT(0) ; // This routine should not be called
  2759. }
  2760. CFIFIWinPitchFamily::CFIFIWinPitchFamily(CString* pcsflags,
  2761. CWnd* pParent /*=NULL*/)
  2762. : CDialog(CFIFIWinPitchFamily::IDD, pParent)
  2763. {
  2764. //{{AFX_DATA_INIT(CFIFIWinPitchFamily)
  2765. // NOTE: the ClassWizard will add member initialization here
  2766. //}}AFX_DATA_INIT
  2767. // Save the flags string pointer
  2768. m_pcsFlags = pcsflags ;
  2769. }
  2770. void CFIFIWinPitchFamily::DoDataExchange(CDataExchange* pDX)
  2771. {
  2772. CDialog::DoDataExchange(pDX);
  2773. //{{AFX_DATA_MAP(CFIFIWinPitchFamily)
  2774. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2775. //}}AFX_DATA_MAP
  2776. }
  2777. BEGIN_MESSAGE_MAP(CFIFIWinPitchFamily, CDialog)
  2778. //{{AFX_MSG_MAP(CFIFIWinPitchFamily)
  2779. //}}AFX_MSG_MAP
  2780. END_MESSAGE_MAP()
  2781. /////////////////////////////////////////////////////////////////////////////
  2782. // CFIFIWinPitchFamily message handlers
  2783. BOOL CFIFIWinPitchFamily::OnInitDialog()
  2784. {
  2785. CDialog::OnInitDialog();
  2786. // Allocate and load the field names array
  2787. CStringArray csafieldnames ;
  2788. csafieldnames.SetSize(8) ;
  2789. csafieldnames[0] = _T("FIXED_PITCH") ;
  2790. csafieldnames[1] = _T("VARIABLE_PITCH") ;
  2791. csafieldnames[2] = _T("FF_DONTCARE") ;
  2792. csafieldnames[3] = _T("FF_ROMAN") ;
  2793. csafieldnames[4] = _T("FF_SWISS") ;
  2794. csafieldnames[5] = _T("FF_MODERN") ;
  2795. csafieldnames[6] = _T("FF_SCRIPT") ;
  2796. csafieldnames[7] = _T("FF_DECORATIVE") ;
  2797. // Allocate flag groupings array. Allocate space for and initialize the
  2798. // two flag groups.
  2799. CUIntArray cuiaflaggroupings ;
  2800. cuiaflaggroupings.SetSize(4) ;
  2801. cuiaflaggroupings[0] = 0 ;
  2802. cuiaflaggroupings[1] = -1 ;
  2803. cuiaflaggroupings[2] = 2 ;
  2804. cuiaflaggroupings[3] = 7 ;
  2805. // The FlagsListBox used to display and edit values is not exactly right
  2806. // for this field because the high half of jWinPitchAndFamily contains a
  2807. // value; NOT a single bit flag. So, the value sent to m_cflbFlags.Init2()
  2808. // must be converted into a flag that the function can display correctly.
  2809. // (This is easier than writing a new class that understands value fields
  2810. // instead of flag fields.)
  2811. DWORD dwv1, dwv2 ;
  2812. LPTSTR lptstr, lptstr2 ;
  2813. lptstr = m_pcsFlags->GetBuffer(16) ;
  2814. int n = m_pcsFlags->GetLength() ;
  2815. *(lptstr + n) = 0 ;
  2816. if (*(lptstr + 1) == 'x')
  2817. lptstr += 2 ;
  2818. dwv2 = strtoul(lptstr, &lptstr2, 16) ;
  2819. dwv1 = dwv2 & 3 ;
  2820. dwv2 -= dwv1 ;
  2821. dwv2 >>= 4 ;
  2822. dwv2++ ;
  2823. //dwv2 += 2 ;
  2824. dwv2 = (2 << dwv2) + dwv1 ;
  2825. // Initialize and load the flags list.
  2826. m_cflbFlags.Init(csafieldnames, dwv2, cuiaflaggroupings, 2,
  2827. lptstrSet, 108, true, 1) ;
  2828. return TRUE; // return TRUE unless you set the focus to a control
  2829. // EXCEPTION: OCX Property Pages should return FALSE
  2830. }
  2831. void CFIFIWinPitchFamily::OnOK()
  2832. {
  2833. // The FlagsListBox used to display and edit values is not exactly right
  2834. // for this field because the high half of jWinPitchAndFamily contains a
  2835. // value; NOT a single bit flag. So, the value returned by
  2836. // m_cflbFlags.GetNewFlagDWord() is not right for this field. Isolate the
  2837. // Family bit and turn it into the correct Family value.
  2838. DWORD dwv, dwv1, dwv2 ;
  2839. dwv = m_cflbFlags.GetNewFlagDWord() ;
  2840. dwv1 = dwv & 3 ;
  2841. dwv >>= 3 ;
  2842. dwv2 = 0 ;
  2843. if (dwv >= 1) {
  2844. for (dwv2 = 1 ; dwv > 1 ; dwv2++)
  2845. dwv >>= 1 ;
  2846. } ;
  2847. dwv = dwv1 + (dwv2 << 4) ;
  2848. m_pcsFlags->Format("0x%02x", dwv) ;
  2849. CDialog::OnOK();
  2850. }
  2851. /////////////////////////////////////////////////////////////////////////////
  2852. // CFIFIInfo dialog
  2853. CFIFIInfo::CFIFIInfo(CWnd* pParent /*=NULL*/)
  2854. : CDialog(CFIFIInfo::IDD, pParent)
  2855. {
  2856. ASSERT(0) ; // This routine should not be called
  2857. }
  2858. CFIFIInfo::CFIFIInfo(CString* pcsflags, CWnd* pParent /*=NULL*/)
  2859. : CDialog(CFIFIInfo::IDD, pParent)
  2860. {
  2861. //{{AFX_DATA_INIT(CFIFIInfo)
  2862. // NOTE: the ClassWizard will add member initialization here
  2863. //}}AFX_DATA_INIT
  2864. // Save the flags string pointer
  2865. m_pcsFlags = pcsflags ;
  2866. }
  2867. void CFIFIInfo::DoDataExchange(CDataExchange* pDX)
  2868. {
  2869. CDialog::DoDataExchange(pDX);
  2870. //{{AFX_DATA_MAP(CFIFIInfo)
  2871. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2872. //}}AFX_DATA_MAP
  2873. }
  2874. BEGIN_MESSAGE_MAP(CFIFIInfo, CDialog)
  2875. //{{AFX_MSG_MAP(CFIFIInfo)
  2876. //}}AFX_MSG_MAP
  2877. END_MESSAGE_MAP()
  2878. /////////////////////////////////////////////////////////////////////////////
  2879. // CFIFIInfo message handlers
  2880. BOOL CFIFIInfo::OnInitDialog()
  2881. {
  2882. CDialog::OnInitDialog();
  2883. // Allocate and load the field names array
  2884. CStringArray csafieldnames ;
  2885. InfoLoadNamesData(csafieldnames) ;
  2886. // Allocate flag groupings array. Don't put anything in it because any
  2887. // combination of flags can be set.
  2888. CUIntArray cuiaflaggroupings ;
  2889. // Initialize and load the flags list.
  2890. m_cflbFlags.Init2(csafieldnames, m_pcsFlags, cuiaflaggroupings, 0,
  2891. lptstrSet, 168, false) ;
  2892. return TRUE; // return TRUE unless you set the focus to a control
  2893. // EXCEPTION: OCX Property Pages should return FALSE
  2894. }
  2895. void CFIFIInfo::OnOK()
  2896. {
  2897. // Update the flag string.
  2898. m_cflbFlags.GetNewFlagString(m_pcsFlags) ;
  2899. CDialog::OnOK();
  2900. }
  2901. void CFIFIInfo::InfoLoadNamesData(CStringArray& csafieldnames)
  2902. {
  2903. csafieldnames.SetSize(32) ;
  2904. csafieldnames[0] = _T("FM_INFO_TECH_TRUETYPE") ;
  2905. csafieldnames[1] = _T("FM_INFO_TECH_BITMAP") ;
  2906. csafieldnames[2] = _T("FM_INFO_TECH_STROKE") ;
  2907. csafieldnames[3] = _T("FM_INFO_TECH_OUTLINE_NOT_TRUETYPE") ;
  2908. csafieldnames[4] = _T("FM_INFO_ARB_XFORMS") ;
  2909. csafieldnames[5] = _T("FM_INFO_1BPP") ;
  2910. csafieldnames[6] = _T("FM_INFO_4BPP") ;
  2911. csafieldnames[7] = _T("FM_INFO_8BPP") ;
  2912. csafieldnames[8] = _T("FM_INFO_16BPP") ;
  2913. csafieldnames[9] = _T("FM_INFO_24BPP") ;
  2914. csafieldnames[10] = _T("FM_INFO_32BPP") ;
  2915. csafieldnames[11] = _T("FM_INFO_INTEGER_WIDTH") ;
  2916. csafieldnames[12] = _T("FM_INFO_CONSTANT_WIDTH") ;
  2917. csafieldnames[13] = _T("FM_INFO_NOT_CONTIGUOUS") ;
  2918. csafieldnames[14] = _T("FM_INFO_TECH_MM") ;
  2919. csafieldnames[15] = _T("FM_INFO_RETURNS_OUTLINES") ;
  2920. csafieldnames[16] = _T("FM_INFO_RETURNS_STROKES") ;
  2921. csafieldnames[17] = _T("FM_INFO_RETURNS_BITMAPS") ;
  2922. csafieldnames[18] = _T("FM_INFO_DSIG") ;
  2923. csafieldnames[19] = _T("FM_INFO_RIGHT_HANDED") ;
  2924. csafieldnames[20] = _T("FM_INFO_INTEGRAL_SCALING") ;
  2925. csafieldnames[21] = _T("FM_INFO_90DEGREE_ROTATIONS") ;
  2926. csafieldnames[22] = _T("FM_INFO_OPTICALLY_FIXED_PITCH") ;
  2927. csafieldnames[23] = _T("FM_INFO_DO_NOT_ENUMERATE") ;
  2928. csafieldnames[24] = _T("FM_INFO_ISOTROPIC_SCALING_ONLY") ;
  2929. csafieldnames[25] = _T("FM_INFO_ANISOTROPIC_SCALING_ONLY") ;
  2930. csafieldnames[26] = _T("FM_INFO_MM_INSTANCE") ;
  2931. csafieldnames[27] = _T("FM_INFO_FAMILY_EQUIV") ;
  2932. csafieldnames[28] = _T("FM_INFO_DBCS_FIXED_PITCH") ;
  2933. csafieldnames[29] = _T("FM_INFO_NONNEGATIVE_AC") ;
  2934. csafieldnames[30] = _T("FM_INFO_IGNORE_TC_RA_ABLE") ;
  2935. csafieldnames[31] = _T("FM_INFO_TECH_TYPE1") ;
  2936. }
  2937. /////////////////////////////////////////////////////////////////////////////
  2938. // CFIFISelection dialog
  2939. CFIFISelection::CFIFISelection(CWnd* pParent /*=NULL*/)
  2940. : CDialog(CFIFISelection::IDD, pParent)
  2941. {
  2942. ASSERT(0) ; // This routine should not be called
  2943. }
  2944. CFIFISelection::CFIFISelection(CString* pcsflags, CWnd* pParent /*=NULL*/)
  2945. : CDialog(CFIFISelection::IDD, pParent)
  2946. {
  2947. //{{AFX_DATA_INIT(CFIFISelection)
  2948. // NOTE: the ClassWizard will add member initialization here
  2949. //}}AFX_DATA_INIT
  2950. // Save the flags string pointer
  2951. m_pcsFlags = pcsflags ;
  2952. }
  2953. void CFIFISelection::DoDataExchange(CDataExchange* pDX)
  2954. {
  2955. CDialog::DoDataExchange(pDX);
  2956. //{{AFX_DATA_MAP(CFIFISelection)
  2957. DDX_Control(pDX, IDC_FlagsLst, m_cflbFlags);
  2958. //}}AFX_DATA_MAP
  2959. }
  2960. BEGIN_MESSAGE_MAP(CFIFISelection, CDialog)
  2961. //{{AFX_MSG_MAP(CFIFISelection)
  2962. //}}AFX_MSG_MAP
  2963. END_MESSAGE_MAP()
  2964. /////////////////////////////////////////////////////////////////////////////
  2965. // CFIFISelection message handlers
  2966. BOOL CFIFISelection::OnInitDialog()
  2967. {
  2968. CDialog::OnInitDialog();
  2969. // Allocate and load the field names array
  2970. CStringArray csafieldnames ;
  2971. csafieldnames.SetSize(7) ;
  2972. csafieldnames[0] = _T("FM_SEL_ITALIC") ;
  2973. csafieldnames[1] = _T("FM_SEL_UNDERSCORE") ;
  2974. csafieldnames[2] = _T("FM_SEL_NEGATIVE") ;
  2975. csafieldnames[3] = _T("FM_SEL_OUTLINED") ;
  2976. csafieldnames[4] = _T("FM_SEL_STRIKEOUT") ;
  2977. csafieldnames[5] = _T("FM_SEL_BOLD") ;
  2978. csafieldnames[6] = _T("FM_SEL_REGULAR") ;
  2979. // Allocate flag groupings array. Put info on one group in it; the last two
  2980. // flags. The first five can be ignored in the groupings array because any
  2981. // combination of them can be set.
  2982. CUIntArray cuiaflaggroupings ;
  2983. cuiaflaggroupings.SetSize(2) ;
  2984. cuiaflaggroupings[0] = -5 ;
  2985. cuiaflaggroupings[1] = -6 ;
  2986. // Initialize and load the flags list.
  2987. m_cflbFlags.Init2(csafieldnames, m_pcsFlags, cuiaflaggroupings, 1,
  2988. lptstrSet, 109, false) ;
  2989. return TRUE; // return TRUE unless you set the focus to a control
  2990. // EXCEPTION: OCX Property Pages should return FALSE
  2991. }
  2992. void CFIFISelection::OnOK()
  2993. {
  2994. // Update the flag string.
  2995. m_cflbFlags.GetNewFlagString(m_pcsFlags) ;
  2996. CDialog::OnOK();
  2997. }
  2998. /////////////////////////////////////////////////////////////////////////////
  2999. // CFIFIPoint dialog
  3000. CFIFIPoint::CFIFIPoint(CWnd* pParent /*=NULL*/)
  3001. : CDialog(CFIFIPoint::IDD, pParent)
  3002. {
  3003. ASSERT(0) ; // This routine should not be called
  3004. }
  3005. CFIFIPoint::CFIFIPoint(CString* pcspoint, CWnd* pParent /*=NULL*/)
  3006. : CDialog(CFIFIPoint::IDD, pParent)
  3007. {
  3008. //{{AFX_DATA_INIT(CFIFIPoint)
  3009. // NOTE: the ClassWizard will add member initialization here
  3010. //}}AFX_DATA_INIT
  3011. m_bInitDone = m_bChanged = false ;
  3012. m_pcsPoint = pcspoint ;
  3013. }
  3014. void CFIFIPoint::DoDataExchange(CDataExchange* pDX)
  3015. {
  3016. CDialog::DoDataExchange(pDX);
  3017. //{{AFX_DATA_MAP(CFIFIPoint)
  3018. DDX_Control(pDX, IDC_PointsLst, m_cfelcPointLst);
  3019. //}}AFX_DATA_MAP
  3020. }
  3021. BEGIN_MESSAGE_MAP(CFIFIPoint, CDialog)
  3022. //{{AFX_MSG_MAP(CFIFIPoint)
  3023. //}}AFX_MSG_MAP
  3024. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  3025. END_MESSAGE_MAP()
  3026. /////////////////////////////////////////////////////////////////////////////
  3027. // CFIFIPoint message handlers
  3028. BOOL CFIFIPoint::OnInitDialog()
  3029. {
  3030. CDialog::OnInitDialog();
  3031. const int numfields = 2 ;
  3032. // Initialize the list control. We want full row select. Nothing is
  3033. // togglable and the max length of an entry is 16 characters. We also
  3034. // want change notification and to suppress acting on INS/DEL keys.
  3035. m_cfelcPointLst.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 16,
  3036. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  3037. // Load the point field names into an array and use them to initialize the
  3038. // first column.
  3039. CStringArray csadata ;
  3040. csadata.SetSize(numfields) ;
  3041. csadata[0] = _T("X") ;
  3042. csadata[1] = _T("Y") ;
  3043. m_cfelcPointLst.InitLoadColumn(0, _T("Point"), COMPUTECOLWIDTH, 20, false,
  3044. false, COLDATTYPE_STRING,
  3045. (CObArray*) &csadata) ;
  3046. // Parse the X and Y values out of the string from the IFI page.
  3047. ParseCompoundNumberString(csadata, m_pcsPoint, numfields) ;
  3048. // Init and load the point values column.
  3049. m_cfelcPointLst.InitLoadColumn(1, csValue, SETWIDTHTOREMAINDER, -20, true,
  3050. false, COLDATTYPE_STRING,
  3051. (CObArray*) &csadata) ;
  3052. m_bInitDone = true ; // Initialization is done now
  3053. return TRUE; // return TRUE unless you set the focus to a control
  3054. // EXCEPTION: OCX Property Pages should return FALSE
  3055. }
  3056. void CFIFIPoint::OnOK()
  3057. {
  3058. // If nothing changed, just shut down the dialog box.
  3059. if (!m_bChanged)
  3060. CDialog::OnOK() ;
  3061. // Get the new point values out of the list control.
  3062. CStringArray csadata ;
  3063. m_cfelcPointLst.GetColumnData((CObArray*) &csadata, 1) ;
  3064. // If either value is blank, complain and return without closing the
  3065. // dialog.
  3066. if (csadata[0].GetLength() == 0 || csadata[1].GetLength() == 0) {
  3067. AfxMessageBox(IDS_MissingFieldError, MB_ICONEXCLAMATION) ;
  3068. return ;
  3069. } ;
  3070. // Format the new point values for display.
  3071. m_pcsPoint->Format("{%s, %s}", csadata[0], csadata[1]) ;
  3072. // Wrap things up.
  3073. CDialog::OnOK();
  3074. }
  3075. LRESULT CFIFIPoint::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  3076. {
  3077. // Do nothing if the dialog box is not initialized yet.
  3078. if (!m_bInitDone)
  3079. return TRUE ;
  3080. // Note that the a point value has changed.
  3081. m_bChanged = true ;
  3082. return TRUE ;
  3083. }
  3084. /////////////////////////////////////////////////////////////////////////////
  3085. // CFIFIRectangle dialog
  3086. CFIFIRectangle::CFIFIRectangle(CWnd* pParent /*=NULL*/)
  3087. : CDialog(CFIFIRectangle::IDD, pParent)
  3088. {
  3089. ASSERT(0) ; // This routine should not be called
  3090. }
  3091. CFIFIRectangle::CFIFIRectangle(CString* pcsrect, CWnd* pParent /*=NULL*/)
  3092. : CDialog(CFIFIRectangle::IDD, pParent)
  3093. {
  3094. //{{AFX_DATA_INIT(CFIFIRectangle)
  3095. // NOTE: the ClassWizard will add member initialization here
  3096. //}}AFX_DATA_INIT
  3097. m_bInitDone = m_bChanged = false ;
  3098. m_pcsRect = pcsrect ;
  3099. }
  3100. void CFIFIRectangle::DoDataExchange(CDataExchange* pDX)
  3101. {
  3102. CDialog::DoDataExchange(pDX);
  3103. //{{AFX_DATA_MAP(CFIFIRectangle)
  3104. DDX_Control(pDX, IDC_RectLst, m_cfelcSidesLst);
  3105. //}}AFX_DATA_MAP
  3106. }
  3107. BEGIN_MESSAGE_MAP(CFIFIRectangle, CDialog)
  3108. //{{AFX_MSG_MAP(CFIFIRectangle)
  3109. //}}AFX_MSG_MAP
  3110. ON_MESSAGE(WM_LISTCELLCHANGED, OnListCellChanged)
  3111. END_MESSAGE_MAP()
  3112. /////////////////////////////////////////////////////////////////////////////
  3113. // CFIFIRectangle message handlers
  3114. BOOL CFIFIRectangle::OnInitDialog()
  3115. {
  3116. CDialog::OnInitDialog();
  3117. const int numfields = 4 ;
  3118. // Initialize the list control. We want full row select. Nothing is
  3119. // togglable and the max length of an entry is 16 characters. We also
  3120. // want change notification and to suppress acting on INS/DEL keys.
  3121. m_cfelcSidesLst.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 16,
  3122. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  3123. // Load the point field names into an array and use them to initialize the
  3124. // first column.
  3125. CStringArray csadata ;
  3126. csadata.SetSize(numfields) ;
  3127. csadata[0] = _T("Left") ;
  3128. csadata[1] = _T("Top") ;
  3129. csadata[2] = _T("Right") ;
  3130. csadata[3] = _T("Bottom") ;
  3131. m_cfelcSidesLst.InitLoadColumn(0, _T("Side"), COMPUTECOLWIDTH, 20, false,
  3132. false, COLDATTYPE_STRING,
  3133. (CObArray*) &csadata) ;
  3134. // Parse the side values out of the string from the IFI page.
  3135. ParseCompoundNumberString(csadata, m_pcsRect, numfields) ;
  3136. // Init and load the side values column.
  3137. m_cfelcSidesLst.InitLoadColumn(1, csValue, SETWIDTHTOREMAINDER, -20, true,
  3138. false, COLDATTYPE_STRING,
  3139. (CObArray*) &csadata) ;
  3140. m_bInitDone = true ; // Initialization is done now
  3141. return TRUE; // return TRUE unless you set the focus to a control
  3142. // EXCEPTION: OCX Property Pages should return FALSE
  3143. }
  3144. void CFIFIRectangle::OnOK()
  3145. {
  3146. // If nothing changed, just shut down the dialog box.
  3147. if (!m_bChanged)
  3148. CDialog::OnOK() ;
  3149. // Get the new rectangle values out of the list control.
  3150. CStringArray csadata ;
  3151. m_cfelcSidesLst.GetColumnData((CObArray*) &csadata, 1) ;
  3152. // If any value is blank, complain and return without closing the
  3153. // dialog.
  3154. int numentries = (int)csadata.GetSize() ;
  3155. for (int n = 0 ; n < numentries ; n++) {
  3156. if (csadata[n].GetLength() == 0) {
  3157. AfxMessageBox(IDS_MissingFieldError, MB_ICONEXCLAMATION) ;
  3158. return ;
  3159. } ;
  3160. } ;
  3161. // Format the new point values for display.
  3162. m_pcsRect->Format("{%s, %s, %s, %s}", csadata[0], csadata[1], csadata[2],
  3163. csadata[3]) ;
  3164. // Wrap things up.
  3165. CDialog::OnOK();
  3166. }
  3167. LRESULT CFIFIRectangle::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  3168. {
  3169. // Do nothing if the dialog box is not initialized yet.
  3170. if (!m_bInitDone)
  3171. return TRUE ;
  3172. // Note that the a rectange value has changed.
  3173. m_bChanged = true ;
  3174. return TRUE ;
  3175. }
  3176. /////////////////////////////////////////////////////////////////////////////
  3177. // CFIFIPanose dialog
  3178. CFIFIPanose::CFIFIPanose(CWnd* pParent /*=NULL*/)
  3179. : CDialog(CFIFIPanose::IDD, pParent)
  3180. {
  3181. ASSERT(0) ; // This routine should not be called
  3182. }
  3183. CFIFIPanose::CFIFIPanose(CString* pcspanose, CWnd* pParent /*=NULL*/)
  3184. : CDialog(CFIFIPanose::IDD, pParent)
  3185. {
  3186. //{{AFX_DATA_INIT(CFIFIPanose)
  3187. // NOTE: the ClassWizard will add member initialization here
  3188. //}}AFX_DATA_INIT
  3189. m_bInitDone = m_bChanged = false ;
  3190. m_pcsPanose = pcspanose ;
  3191. }
  3192. void CFIFIPanose::DoDataExchange(CDataExchange* pDX)
  3193. {
  3194. CDialog::DoDataExchange(pDX);
  3195. //{{AFX_DATA_MAP(CFIFIPanose)
  3196. DDX_Control(pDX, IDC_PanoseLst, m_cfelcPanoseLst);
  3197. //}}AFX_DATA_MAP
  3198. }
  3199. BEGIN_MESSAGE_MAP(CFIFIPanose, CDialog)
  3200. //{{AFX_MSG_MAP(CFIFIPanose)
  3201. //}}AFX_MSG_MAP
  3202. END_MESSAGE_MAP()
  3203. /////////////////////////////////////////////////////////////////////////////
  3204. // CFIFIPanose message handlers
  3205. BOOL CFIFIPanose::OnInitDialog()
  3206. {
  3207. CDialog::OnInitDialog();
  3208. const int numfields = 10 ;
  3209. // Initialize the list control. We want full row select. Nothing is
  3210. // togglable and the max length of an entry is 3 characters. We also
  3211. // want change notification and to suppress acting on INS/DEL keys.
  3212. m_cfelcPanoseLst.InitControl(LVS_EX_FULLROWSELECT, numfields, 2, 0, 3,
  3213. MF_SENDCHANGEMESSAGE+MF_IGNOREINSDEL) ;
  3214. // Load the point field names into an array and use them to initialize the
  3215. // first column.
  3216. CStringArray csadata ;
  3217. csadata.SetSize(numfields) ;
  3218. csadata[0] = _T("bFamilyType") ;
  3219. csadata[1] = _T("bSerifStyle") ;
  3220. csadata[2] = _T("bWeight") ;
  3221. csadata[3] = _T("bProportion") ;
  3222. csadata[4] = _T("bContrast") ;
  3223. csadata[5] = _T("bStrokeVariation") ;
  3224. csadata[6] = _T("bArmStyle") ;
  3225. csadata[7] = _T("bLetterform") ;
  3226. csadata[8] = _T("bMidline") ;
  3227. csadata[9] = _T("bXHeight") ;
  3228. m_cfelcPanoseLst.InitLoadColumn(0, csField, COMPUTECOLWIDTH, 15, false,
  3229. false, COLDATTYPE_STRING,
  3230. (CObArray*) &csadata) ;
  3231. // Parse the panose values out of the string from the IFI page.
  3232. ParseCompoundNumberString(csadata, m_pcsPanose, numfields) ;
  3233. // Init and load the side values column.
  3234. m_cfelcPanoseLst.InitLoadColumn(1, _T("Value (0 - 255)"),
  3235. SETWIDTHTOREMAINDER, -16, true, false,
  3236. COLDATTYPE_STRING, (CObArray*) &csadata) ;
  3237. m_bInitDone = true ; // Initialization is done now
  3238. return TRUE; // return TRUE unless you set the focus to a control
  3239. // EXCEPTION: OCX Property Pages should return FALSE
  3240. }
  3241. void CFIFIPanose::OnOK()
  3242. {
  3243. // If nothing changed, just shut down the dialog box.
  3244. if (!m_bChanged)
  3245. CDialog::OnOK() ;
  3246. // Get the new panose values out of the list control.
  3247. CStringArray csadata ;
  3248. m_cfelcPanoseLst.GetColumnData((CObArray*) &csadata, 1) ;
  3249. // If any value is blank, complain and return without closing the
  3250. // dialog.
  3251. int numentries = (int)csadata.GetSize() ;
  3252. for (int n = 0 ; n < numentries ; n++) {
  3253. if (csadata[n].GetLength() == 0) {
  3254. AfxMessageBox(IDS_MissingFieldError, MB_ICONEXCLAMATION) ;
  3255. return ;
  3256. } ;
  3257. } ;
  3258. // Format the new panose values for display.
  3259. m_pcsPanose->Format("{%s, %s, %s, %s, %s, %s, %s, %s, %s, %s}", csadata[0],
  3260. csadata[1], csadata[2], csadata[3], csadata[4],
  3261. csadata[5], csadata[6], csadata[7], csadata[8],
  3262. csadata[9]) ;
  3263. // Wrap things up.
  3264. CDialog::OnOK();
  3265. }
  3266. LRESULT CFIFIPanose::OnListCellChanged(WPARAM wParam, LPARAM lParam)
  3267. {
  3268. // Do nothing if the dialog box is not initialized yet.
  3269. if (!m_bInitDone)
  3270. return TRUE ;
  3271. // Note that the a panose value has changed.
  3272. m_bChanged = true ;
  3273. return TRUE ;
  3274. }
  3275. /////////////////////////////////////////////////////////////////////////////
  3276. // CWidthKernCheckResults dialog
  3277. CWidthKernCheckResults::CWidthKernCheckResults(CWnd* pParent /*=NULL*/)
  3278. : CDialog(CWidthKernCheckResults::IDD, pParent)
  3279. {
  3280. ASSERT(0) ; // This routine should not be called
  3281. }
  3282. CWidthKernCheckResults::CWidthKernCheckResults(CFontInfo* pcfi,
  3283. CWnd* pParent /*=NULL*/)
  3284. : CDialog(CWidthKernCheckResults::IDD, pParent)
  3285. {
  3286. //{{AFX_DATA_INIT(CWidthKernCheckResults)
  3287. m_csKernChkResults = _T("");
  3288. m_csWidthChkResults = _T("");
  3289. //}}AFX_DATA_INIT
  3290. // Save the pointer to the font info class
  3291. m_pcfi = pcfi ;
  3292. }
  3293. void CWidthKernCheckResults::DoDataExchange(CDataExchange* pDX)
  3294. {
  3295. CDialog::DoDataExchange(pDX);
  3296. //{{AFX_DATA_MAP(CWidthKernCheckResults)
  3297. DDX_Control(pDX, IDC_BadKerningPairs, m_clcBadKernPairs);
  3298. DDX_Text(pDX, IDC_KernTblResults, m_csKernChkResults);
  3299. DDX_Text(pDX, IDC_WidthTblResults, m_csWidthChkResults);
  3300. //}}AFX_DATA_MAP
  3301. }
  3302. BEGIN_MESSAGE_MAP(CWidthKernCheckResults, CDialog)
  3303. //{{AFX_MSG_MAP(CWidthKernCheckResults)
  3304. //}}AFX_MSG_MAP
  3305. END_MESSAGE_MAP()
  3306. /////////////////////////////////////////////////////////////////////////////
  3307. // CWidthKernCheckResults message handlers
  3308. /******************************************************************************
  3309. CWidthKernCheckResults::OnInitDialog
  3310. Perform what consistency checks there are that can easily be done on the
  3311. widths and kerning tables. Then display the results in this dialog box.
  3312. ******************************************************************************/
  3313. BOOL CWidthKernCheckResults::OnInitDialog()
  3314. {
  3315. CDialog::OnInitDialog() ;
  3316. // Load the appropriate message depending on the state of the widths table.
  3317. if (m_pcfi->WidthsTableIsOK())
  3318. m_csWidthChkResults.LoadString(IDS_WidthsTableOK) ;
  3319. else
  3320. m_csWidthChkResults.LoadString(IDS_WidthsTableTooBig) ;
  3321. // Initialize the bad kerning info list control.
  3322. CString csWork ;
  3323. csWork.LoadString(IDS_KernColumn0) ;
  3324. m_clcBadKernPairs.InsertColumn(0, csWork, LVCFMT_CENTER,
  3325. (3 * m_clcBadKernPairs.GetStringWidth(csWork)) >> 1, 0) ;
  3326. csWork.LoadString(IDS_KernColumn1) ;
  3327. m_clcBadKernPairs.InsertColumn(1, csWork, LVCFMT_CENTER,
  3328. m_clcBadKernPairs.GetStringWidth(csWork) << 1, 1) ;
  3329. csWork.LoadString(IDS_KernColumn2) ;
  3330. m_clcBadKernPairs.InsertColumn(2, csWork, LVCFMT_CENTER,
  3331. m_clcBadKernPairs.GetStringWidth(csWork) << 1, 2) ;
  3332. // Load any bad kerning info in the list control for display and use the
  3333. // existence of this data to determine the appropriate message to display.
  3334. if (m_pcfi->LoadBadKerningInfo(m_clcBadKernPairs))
  3335. m_csKernChkResults.LoadString(IDS_KerningTableBadEnts) ;
  3336. else
  3337. m_csKernChkResults.LoadString(IDS_KerningTableOK) ;
  3338. UpdateData(FALSE) ;
  3339. return TRUE; // return TRUE unless you set the focus to a control
  3340. // EXCEPTION: OCX Property Pages should return FALSE
  3341. }
  3342.