diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/fontedit | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/sdktools/fontedit')
28 files changed, 8991 insertions, 0 deletions
diff --git a/private/sdktools/fontedit/apl.fnt b/private/sdktools/fontedit/apl.fnt Binary files differnew file mode 100644 index 000000000..d03925310 --- /dev/null +++ b/private/sdktools/fontedit/apl.fnt diff --git a/private/sdktools/fontedit/atrm1111.f20 b/private/sdktools/fontedit/atrm1111.f20 Binary files differnew file mode 100644 index 000000000..24b40b9fa --- /dev/null +++ b/private/sdktools/fontedit/atrm1111.f20 diff --git a/private/sdktools/fontedit/atrm1111.fnt b/private/sdktools/fontedit/atrm1111.fnt Binary files differnew file mode 100644 index 000000000..d78beaa7c --- /dev/null +++ b/private/sdktools/fontedit/atrm1111.fnt diff --git a/private/sdktools/fontedit/fcntl.h b/private/sdktools/fontedit/fcntl.h new file mode 100644 index 000000000..1e04d4752 --- /dev/null +++ b/private/sdktools/fontedit/fcntl.h @@ -0,0 +1,23 @@ +/* + * fcntl.h + * + * defines file control options used by the open system call. + * + * Copyright (C) Microsoft Corporation, 1984 + */ + +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_APPEND 0x0008 /* writes done at eof */ + +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_EXCL 0x0400 /* exclusive open */ + +/* O_TEXT files have <cr><lf> sequences translated to <lf> on read()'s, +** and <lf> sequences translated to <cr><lf> on write()'s +*/ + +#define O_TEXT 0x4000 /* file mode is text (translated) */ +#define O_BINARY 0x8000 /* file mode is binary (untranslated) */ diff --git a/private/sdktools/fontedit/fillclr.cur b/private/sdktools/fontedit/fillclr.cur Binary files differnew file mode 100644 index 000000000..95009c3e3 --- /dev/null +++ b/private/sdktools/fontedit/fillclr.cur diff --git a/private/sdktools/fontedit/fillcpy.cur b/private/sdktools/fontedit/fillcpy.cur Binary files differnew file mode 100644 index 000000000..338f6af50 --- /dev/null +++ b/private/sdktools/fontedit/fillcpy.cur diff --git a/private/sdktools/fontedit/fillhat.cur b/private/sdktools/fontedit/fillhat.cur Binary files differnew file mode 100644 index 000000000..ca5300892 --- /dev/null +++ b/private/sdktools/fontedit/fillhat.cur diff --git a/private/sdktools/fontedit/fillinv.cur b/private/sdktools/fontedit/fillinv.cur Binary files differnew file mode 100644 index 000000000..acc9db318 --- /dev/null +++ b/private/sdktools/fontedit/fillinv.cur diff --git a/private/sdktools/fontedit/filllft.cur b/private/sdktools/fontedit/filllft.cur Binary files differnew file mode 100644 index 000000000..6a1c07f56 --- /dev/null +++ b/private/sdktools/fontedit/filllft.cur diff --git a/private/sdktools/fontedit/fillpst.cur b/private/sdktools/fontedit/fillpst.cur Binary files differnew file mode 100644 index 000000000..860dab603 --- /dev/null +++ b/private/sdktools/fontedit/fillpst.cur diff --git a/private/sdktools/fontedit/fillsol.cur b/private/sdktools/fontedit/fillsol.cur Binary files differnew file mode 100644 index 000000000..c45599560 --- /dev/null +++ b/private/sdktools/fontedit/fillsol.cur diff --git a/private/sdktools/fontedit/filltop.cur b/private/sdktools/fontedit/filltop.cur Binary files differnew file mode 100644 index 000000000..e3c20c8ca --- /dev/null +++ b/private/sdktools/fontedit/filltop.cur diff --git a/private/sdktools/fontedit/fontchar.c b/private/sdktools/fontedit/fontchar.c new file mode 100644 index 000000000..587dacc26 --- /dev/null +++ b/private/sdktools/fontedit/fontchar.c @@ -0,0 +1,1569 @@ +#include "windows.h" +#include <port1632.h> +#include "fontedit.h" +#include "fcntl.h" +#include <stdio.h> + +/****************************************************************************/ +/* Shared Variables */ +/****************************************************************************/ + +POINT SnapPointToGrid(POINT Pt); +LONG APIENTRY FontEditWndProc(HWND, WORD, WPARAM, LONG); +BOOL APIENTRY AboutDlg( + HWND hDlg, + WORD message, + WPARAM wParam, + LONG lParam + ); +BOOL NewFile; /* flag indicating that NEW menu + item was selected */ +extern DLGPROC lpHeaderProc; /* Pointer to Dialog Box Procedure */ +extern DLGPROC lpReSizeProc; /* Pointer to Dialog Box Procedure */ +extern DLGPROC lpWidthProc; /* Pointer to Dialog Box Procedure */ + +extern FontHeaderType font; /* Structure of Font File Header */ +extern CHAR matBox [wBoxLim] [kBoxLim]; /* array to hold Box */ +extern HCURSOR hCross; /* handle to "+" shaped cursor(displayed + when in ROW or COLUMN menus */ +extern BOOL fReadOnly; +extern HANDLE hInst; /* Module Handle */ +extern HBRUSH hbrBackGround; +extern HWND hFont; +extern HWND hBox; +extern RECT rectWin; /* Client Rectangle */ +extern BOOL fLoaded; /* Set if a file loaded */ +extern BOOL fChanged; /* Anything has changed */ +extern BOOL fEdited; /* This character changed */ +extern DWORD kBox; /* height of character */ +extern DWORD wBox; /* Width of character */ +extern DWORD kStuff; /* Width of Show Header */ +extern INT swH; /* Position in Show Window 0-100 */ +extern BYTE iChar; /* Character being edited */ +extern BYTE jChar; /* Last Char. of edit block */ +extern CHAR szNewFile[]; /* Name of New File */ +extern CHAR szFontFile[]; /* Name of Font File */ +extern CHAR szFontFileFull[]; /* Name of Font File */ +extern CHAR szFileNameTemp[]; +extern CHAR *szFileNameSave; +extern INT cSysHeight; + +extern CHAR *vrgsz[]; /* total number of strings */ +extern OFSTRUCT ofstrFile; +extern CHAR szExt[]; /* default extension */ +extern CHAR szAppName[]; +extern CHAR szSCC[]; +extern HCURSOR hOldCursor; /* handle to old arrow shaped cursor */ +extern CHAR gszHelpFile[]; +/****************************************************************************/ +/* Local Variables */ +/****************************************************************************/ + +HBRUSH hbrWhite; +HBRUSH hbrBlack; +HBRUSH hbrGray; +HBRUSH hbrDkGray; +HBRUSH hNullBrush; +HPEN hWhitePen; +DWORD colors[3] = {WHITENESS, BLACKNESS, PATCOPY}; + + +CHAR matBackup [wBoxLim] [kBoxLim]; /* Backup for UNDO */ +DWORD wBoxBackup; + +LONG scale = 7; /* height/width of squares in box */ +WORD cursor = 0; /* Add/Del cursor */ + +BOOL fAll = TRUE; /* Redraw all if TRUE */ +POINT ptBox = {10, 5}; /* where edit box is */ + +RECT rectRubber; /* Rubber banding rectangle */ +HDC hDst; /* Rubber banding dc */ + +POINT ptA; /* Start of draw/rectangle */ +POINT ptB; /* End of rectangle */ +POINT ptC; /* Current square */ +CHAR colorA; /* Color at/under point A */ +DWORD newWidth; /* Width set in WIDER option */ +BOOL FillingRect = FALSE; +BOOL fRubberBanding = FALSE; /* flag indicating if rubberbanding in + progress for row/column add/delete */ +BOOL fStartRubberBand = FALSE; /* flag indicating that rubberbanding + can start */ +BOOL fCaptured = FALSE; /* set if mouse is caputred */ +BOOL fJustZapped = FALSE; /* Set on row/col add/delete */ +RECT FontRect; /* rectangle bounding font pattern */ + +/****************************************************************************/ +/* Local Functions */ +/****************************************************************************/ + +VOID ClearFill(DWORD col, DWORD row, WORD mode); +VOID FontEditCommand(HWND hBox, WORD id); +VOID BoxRestore(VOID); +VOID CharRectDimensions(LPRECT Rect); +VOID BoxPaint(VOID); +VOID DrawBox(HDC, DWORD, DWORD, DWORD, DWORD, INT, DWORD); +VOID DrawRubberBand(HDC hDst, LPRECT lpRect, DWORD rop); +VOID FontEditPaint(HWND hBox, HDC hDC); +BOOL CheckSave(VOID); +VOID DupCol(DWORD col, DWORD row); +VOID DupRow(DWORD col, DWORD row); +VOID ZapCol(DWORD col, DWORD row); +VOID ZapRow(DWORD col, DWORD row); +VOID AddDel(DWORD col, DWORD row, WORD mode); +VOID MouseInBox(HWND hBox, WORD message, POINT ptMouse); +VOID BoxBackup(VOID); +VOID ReadRect(VOID); + +/*****************************************************************************/ +VOID +BoxPaint( + VOID + ) /* Our call to FontEditPaint */ +{ + HDC hDC; + + hDC = GetDC(hBox); + FontEditPaint(hBox, hDC); + ReleaseDC(hBox, hDC); + if (fRubberBanding) + DrawRubberBand(hDst, &rectRubber, R2_XORPEN); +} + + +/****************************************************************************** + * FontEditPaint(hBox, hDC) + * + * purpose: calculates coordinates for text in main window and repaints edit + * box,small character boxes and text + * + * params: HWND hBox : handle to main window + * HDC hDC I handle to display context + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +FontEditPaint( + HWND hBox, + HDC hDC + ) +{ + CHAR szTemp[20]; + DWORD len, yText, xText; + + if (!fLoaded) /* Must load font first */ + return; + + /* Here the application paints its window. */ + if (fAll) { /* Draw box setting */ + GetClientRect(hBox, (LPRECT)&rectWin); + scale = (rectWin.bottom-rectWin.top-kStuff-20) / (kBox+1); + scale = min(scale, (min(320, rectWin.right - rectWin.left) - + 90) / (LONG)(wBox + 1)); + scale = max(scale, 4); + xText = ptBox.x + scale * wBox + 16; + + SelectObject(hDC, hbrDkGray); + Rectangle(hDC, + ptBox.x - 2, + ptBox.y - 2, + ptBox.x + 3 + wBox * scale, + ptBox.y + 5 + kBox * scale); + SelectObject(hDC, hbrGray); + + Rectangle(hDC, /* Surround for font displays */ + xText, + ptBox.y - 2, + xText + wBox + 8, + ptBox.y + 3 + kBox * 2 + font.ExtLeading); + + /* Now put up the text */ + yText = 14 + 2 * kBox + font.ExtLeading; + len = (DWORD) sprintf(szTemp, vszCHAR, iChar); + TextOut(hDC, xText, yText, (LPSTR)szTemp, len); + len = (DWORD) sprintf(szTemp, vszWIDTH, wBox); + TextOut(hDC, xText, yText + cSysHeight, (LPSTR)szTemp, len); + len = (DWORD) sprintf(szTemp, vszHEIGHT, kBox); + TextOut(hDC, xText, yText + cSysHeight + cSysHeight, + (LPSTR)szTemp, len); + } + + /* Draw Character Box */ + DrawBox(hDC, ptBox.x, ptBox.y, wBox, kBox, scale, 1); + + /* Draw small character */ + xText = ptBox.x + scale * wBox + 16; + DrawBox(hDC, + xText + 4, + ptBox.y, + wBox, + kBox, + 1, 0); + + /* Draw another small character to show leading */ + DrawBox(hDC, + xText + 4, + ptBox.y + kBox + font.ExtLeading, + wBox, + kBox, + 1, 0); + fAll = TRUE; +} + + +/****************************************************************************** + * DrawBox(hDC, xChar, yChar, wChar, kChar, scale, htSep) + * + * purpose: draws the edit box for the character being edited and colors the + * grid squares according to the pixels set for the character. + * + * params: HDC hDC : handle to display context + * DWORD xChar : x-location of char box. + * DWORD yChar : y-location of char box + * DWORD wChar : width of char box + * DWORD kChar : height of char + * INT wScale : Scale of the squares. + * DWORD htSep : height of square separators + * + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +DrawBox( + HDC hDC, + DWORD xChar, /* x-location of char. */ + DWORD yChar, /* y-location of char. */ + DWORD wChar, /* width of char. */ + DWORD kChar, /* height of char */ + INT wScale, /* scale of the squares. */ + DWORD htSep /* hgt of square separators */ + ) +/* draw a character of separate squares of height 'scale' with sep. 'htSep' */ +{ + DWORD i, j, sep; + + if (fAll) { /* redraw them all */ + for (j = 0; j < kChar; j++) { + sep = (j >= font.Ascent) ? htSep : 0; + for (i = 0; i < wChar; i++) { + if (wScale == 1) + SetPixel(hDC, xChar + i, yChar + j, + matBox[i][j] == TRUE ? BLACK : WHITE); + else + PatBlt(hDC, + xChar + wScale * i, + yChar + wScale * j + sep, + wScale - htSep, + wScale - htSep, + colors[matBox[i][j] == TRUE ? 1 : 0]); + } + } + } + else { /* redraw one just flipped */ + if (wScale == 1) + SetPixel(hDC, + xChar + ptC.x, + yChar + ptC.y, + matBox[ptC.x][ptC.y] == TRUE ? BLACK : WHITE); + else { + sep = (((DWORD) ptC.y >= font.Ascent) ? htSep : 0L); + SelectObject(hDC, hbrGray); + PatBlt(hDC, + xChar + wScale * ptC.x, + yChar + wScale * ptC.y + sep, + wScale - htSep, + wScale - htSep, + colors[matBox[ptC.x][ptC.y]]); + } + } + +} + + +/****************************************************************************** + * FontEditCommand(hBox, id) + * + * purpose: interprets menu id and calls appropriate function to do the task + * + * params: HWND hBox : handle to main window + * WORD id : menu command id + * returns: none + * + * side effects: plenty + * + *****************************************************************************/ +VOID +FontEditCommand( + HWND hBox, + WORD id + ) +{ + CHAR * szError; /* String for error messages */ + LONG w; + DWORD y, i, j; + BOOL fRepaint = FALSE; + HMENU hMenu; + DLGPROC lpprocAboutDlg; + MSG message; + + szError = ""; /* No Errors yet */ + + switch (id) { + case FONT_EXIT: + if (!CheckSave()) /* See if any files need saving */ + break; + /* Window's being destroyed. */ + if (fLoaded) /* 4/8/87 Linsh added */ + DeleteBitmap(); /* Get rid of memory DC */ + PostQuitMessage(0); /* Cause application to be terminated */ + break; + + case FONT_HELP_CONTENTS: + WinHelp(hFont, gszHelpFile, HELP_CONTENTS, 0L); + break; + + case FONT_HELP_SEARCH: + /* + * Tell winhelp to be sure this app's help file is current, + * then invoke a search with an empty starting key. + */ + WinHelp(hFont, gszHelpFile, HELP_FORCEFILE, 0); + WinHelp(hFont, gszHelpFile, HELP_PARTIALKEY, (DWORD)(LPSTR)""); + break; + + case FONT_ABOUT: + lpprocAboutDlg = (DLGPROC)AboutDlg; + DialogBox (hInst, vszABOUT, hBox, lpprocAboutDlg); + FreeProcInstance (lpprocAboutDlg); + break; + + case FONT_LOAD: /* Check File Name */ + case FONT_NEW : + if (!CheckSave()) /* See if current font needs saving */ + return; + /* to prevent scrambling of Show window chars, Bring back Show + ** window to parent window's client area before invoking the dialog */ + + if (CommDlgOpen(hBox,&ofstrFile,szNewFile,szExt,szFontFile,id) + == FALSE) { + + InvalidateRect(hFont, (LPRECT)NULL, FALSE); + UpdateWindow(hFont); + return; + } + /* else drop thru */ + + case FONT_START: /* Here if file name passed as argument */ + InvalidateRect(hFont, (LPRECT)NULL, FALSE); + UpdateWindow(hFont); + + szError = FontLoad (szNewFile, &ofstrFile); + + /* Hack : needed to remove umwanted WM_MOUSEMOVE messages from the + * queue. + * Apparently, Windows needs to reposition the mouse after a dialog + * is ended with a mouse double-click (releases mouse capture?) for + * which a couple of WM_MOUSEMOVEs may get sent to parent app. + * These mess with the edit box below the dialog if they happen to + * overlap. + */ + PeekMessage((LPMSG) &message, hBox, WM_MOUSEMOVE, WM_MOUSEMOVE, + PM_REMOVE); + + if (fLoaded) /* If loaded then do a few things */ { + jChar = iChar = 65; /* Show an A */ + if ((BYTE)iChar > (BYTE)font.LastChar) + jChar = iChar = font.FirstChar; /* .. if we can */ + swH = 15; /* Good bet to make A visible */ + fEdited = fChanged = FALSE; + ResizeShow(); /* Set Box to proper size */ + ScrollFont(); /* Set thumb */ + CharToBox(iChar); + } + FontRename(szError); + SetFocus(hBox); + return; + + case FONT_SAVE: + if (!NewFile) { + if (fLoaded && fChanged) { + lstrcpy((LPSTR)szNewFile, (LPSTR)szFontFileFull); + BoxToChar(iChar); /* Just in case */ + szError = FontSave (szNewFile, &ofstrFile); + FontRename(szError); /* Rename or Print Error */ + return; + } + else + return; + } + /* else file has been opened by selecting NEW... on menu. + * Fall thro' and bring up SaveAs dialog minus default + * filename in edit window */ + + case FONT_SAVEAS: + BoxToChar(iChar); /* Just in case */ + + if (CommDlgSaveAs (hInst, hBox, &ofstrFile, szNewFile, szExt, + szFontFile) == TRUE) { + + szError = FontSave (szNewFile, &ofstrFile); + FontRename (szError); /* Rename or Print Error */ + } + + /* to prevent scrambling of Show window chars, + repaint show window after dialog is brought down */ + InvalidateRect (hFont, (LPRECT)NULL, TRUE); + UpdateWindow (hFont); + return; + + case FONT_HEADER: + /* to prevent scrambling of Show window chars, + * repaint show window after dialog is invoked */ + DialogBox(hInst, (LPSTR)vszDHeader, hBox, lpHeaderProc); + InvalidateRect(hFont, (LPRECT)NULL, TRUE); + UpdateWindow(hFont); + return; + + case FONT_RESIZE: + /* to prevent scrambling of Show window chars, + repaint show window after dialog is brought down */ + if (DialogBox(hInst, (LPSTR)vszDResize, hBox, lpReSizeProc)) { + /* BoxToChar(iChar);*/ /* save current before resizing */ + ResizeShow(); /* New Font Display Size */ + CharToBox(iChar); /* New Box display */ + } + InvalidateRect(hFont, (LPRECT)NULL, TRUE); + UpdateWindow(hFont); + return; + + case FONT_COPY: /* Copy to Clipboard */ + BoxToChar(iChar); /* Just in case */ + ToClipboard(iChar, wBox, kBox); + break; + + case FONT_PASTE: /* Paste in Character form Clipboard */ + BoxBackup(); /* In case we change our minds */ + ptA.x = ptA.y = 0; + wBox = ClipboardToBox(ptA, wBox, kBox, TRUE); + fRepaint = TRUE; + break; + + case WIDER_LEFT: + case WIDER_RIGHT: + case WIDER_BOTH: + case NARROWER_LEFT: + case NARROWER_RIGHT: + case NARROWER_BOTH: + case WIDTH: + w = newWidth = wBox; + if (font.Family & 1) /* Variable width or else */ { + switch (id) { + case WIDER_BOTH: + w++; + case WIDER_LEFT: + case WIDER_RIGHT: + w++; + break; + case NARROWER_BOTH: + w--; + case NARROWER_LEFT: + case NARROWER_RIGHT: + w--; + break; + case WIDTH: + if (DialogBox(hInst, + (LPSTR)vszDWidth, hBox, lpWidthProc)) + w = newWidth; + break; + } + + if (w < 0 || w >= wBoxLim) { + MessageBox(hBox, + (LPSTR)vszEdLimits0To64, + (LPSTR)szAppName, + MB_OK | MB_ICONASTERISK); + break; /* Out of range! quit */ + } + if (w > (LONG) font.MaxWidth) { + if (IDOK == MessageBox(hBox, + (LPSTR)vszMaxWidthIncrease, + (LPSTR)szAppName, + MB_OKCANCEL | MB_ICONQUESTION)) + font.MaxWidth = (WORD)w; + else + break; + } + BoxBackup(); /* In case we change our minds */ + wBox = (WORD)w; /* Reset width */ + fRepaint = TRUE; /* Signal redraw */ + switch (id) { + case WIDER_LEFT: +#ifdef DBCS //DBCS_FIX + DupCol(0, kBoxLim - 1); + for (y = 0; y < kBoxLim; y++) + matBox[0][y] = FALSE; /* Clear left column */ + break; +#endif + case WIDER_BOTH: /* Shift character one right */ + DupCol(0, kBoxLim - 1); + for (y = 0; y < kBoxLim; y++) + matBox[wBox -1][y] = FALSE; /* Clear right column */ + for (y = 0; y < kBoxLim; y++) + matBox[0][y] = FALSE; /* Clear left column */ + break; + case NARROWER_LEFT: + case NARROWER_BOTH: /* Shift character one left */ + if (wBox) { /* .. unless width is already 0 */ + for (j = 0; j <= kBox - 1; j++) + for (i = 0; i <= wBox - 1; i++) + matBox[i][j] = matBox[i + 1][j]; + break; + } + } + } + else { + MessageBox(hBox, + (LPSTR)vszCannotChangeWidth, + (LPSTR)szAppName, + MB_OK | MB_ICONASTERISK); + } + break; + + case ROW_ADD: + case ROW_DEL: + case COL_ADD: + case COL_DEL: + /* set cursor to "+" shaped cursor */ + SetCapture (hBox); /* so that cursor doesn't get restored + before we are done */ + hOldCursor = SetCursor (LoadCursor (NULL, IDC_CROSS)); + fCaptured = TRUE; + cursor = id; + break; + + case BOX_CLEAR: + case BOX_FILL: + case BOX_INV: + case BOX_HATCH: + case BOX_LEFTRIGHT: + case BOX_TOPBOTTOM: + case BOX_COPY: + case BOX_PASTE: + /* Get one o' da funky cursors */ + SetCapture(hBox); + hOldCursor = SetCursor(LoadCursor(hInst, MAKEINTRESOURCE(id))); + fStartRubberBand = TRUE; + CharRectDimensions((LPRECT)&FontRect); + cursor = id; + break; + + case BOX_REFRESH: /* Go get old version of character */ + BoxBackup(); /* In case we change our minds */ + CharToBox(iChar); + hMenu = GetMenu(hBox); + EnableMenuItem(hMenu, BOX_UNDO, MF_ENABLED); /* Can Unrefresh! */ + break; + case BOX_UNDO: + BoxRestore(); + hMenu = GetMenu(hBox); + EnableMenuItem(hMenu, BOX_REFRESH, MF_ENABLED); + fRepaint = TRUE; + break; + } + if (fRepaint) { + fEdited = fChanged = TRUE; + InvalidateRect(hBox, (LPRECT)NULL, TRUE); + } +} + + +VOID +CharRectDimensions( + LPRECT Rect + ) +/* returns the dimensions of the edit box */ +{ + Rect->top = ptBox.y; + Rect->bottom = ptBox.y + (kBox) * (scale); + Rect->left = ptBox.x; + Rect->right = ptBox.x + (wBox) * (scale); +} + + +/****************************************************************************** + * BOOL APIENTRY WidthProc(hDial, message, wParam, lParam) + * + * purpose: dialog function for Width menu function + * + * params: same as for all dialog fns. + * + * side effects: changes Box width variable + * + *****************************************************************************/ +BOOL APIENTRY +WidthProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + INT i; + BOOL fOk; + + UNREFERENCED_PARAMETER(lParam); + + switch (message) { + default: + return FALSE; + case WM_INITDIALOG: + SetDlgItemInt(hDial, BOX_WIDTH, newWidth, FALSE); + break; + + case WM_COMMAND: + switch (GET_WM_COMMAND_ID(wParam, lParam)) { + case IDOK: + fChanged = TRUE; + i = GetDlgItemInt(hDial, BOX_WIDTH, (LPBOOL)&fOk, FALSE); + if (fOk && i < wBoxLim) + newWidth = i; + else + ErrorBox(hDial, vszWidthOutOfBounds); + + case IDCANCEL: + EndDialog(hDial, GET_WM_COMMAND_ID(wParam, lParam) != IDCANCEL); + break; + + default: + break; + } + } + return TRUE; +} + + +/****************************************************************************** + * BOOL CheckSave() + * + * purpose: checks if font is dirty and prompts user to save font. If yes, + * edit box is saved and file save function is called. + * + * params: none + * + * returns: TRUE : font has been changed + * FALSE: font untouched + * + * side effects: file dirty flag is reset. + * + *****************************************************************************/ +BOOL +CheckSave( + VOID + ) +{ + CHAR * szError; /* String for error messages */ + CHAR szMessage[MAX_STR_LEN+MAX_FNAME_LEN]; + + /* Check if anything changed */ + if (fLoaded && fChanged && (!fReadOnly)) { + lstrcpy((LPSTR)szNewFile, (LPSTR)szFontFileFull); + DlgMergeStrings(szSCC, szNewFile, szMessage); + switch (MessageBox(hFont, + (LPSTR)szMessage, + (LPSTR)szAppName, + MB_YESNOCANCEL | MB_ICONQUESTION)) { + case IDYES: + BoxToChar(iChar); /* Just in case */ + szError = FontSave (szNewFile, &ofstrFile); + FontRename(szError); /* Rename or Print Error */ + case IDNO: + return TRUE; + case IDCANCEL: + return FALSE; + } + } + return TRUE; +} + + +/****************************************************************************** + * MouseInBox(hBox, message, ptMouse) + * + * purpose: do edit operation depending on currently active menu command + * + * params: HWND hBox : handle to main window + * WORD message : Message retrieved by main window's window fn. + * POINT ptMouse : current mouse coordinates + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box). Also assigns values to ptA and ptB + *****************************************************************************/ +VOID +MouseInBox( + HWND hBox, + WORD message, + POINT ptMouse + ) +{ + POINT pt; + BOOL fRepaint = FALSE; + + pt = SnapPointToGrid(ptMouse); + + if (pt.x >= 0L && pt.y >= 0L && + ((DWORD)pt.x) < wBox && ((DWORD)pt.y) < kBox) { + fEdited = fChanged = TRUE; + ptC.x = pt.x; + ptC.y = pt.y; /* Current square */ + if (message == WM_LBUTTONDOWN) + BoxBackup(); /* Set up for UNDO */ + switch (cursor) { + case BOX_COPY: + case BOX_PASTE: + case BOX_CLEAR: + case BOX_FILL: + case BOX_INV: + case BOX_HATCH: + case BOX_LEFTRIGHT: + case BOX_TOPBOTTOM: + ptA.x = pt.x; + ptA.y = pt.y; /* save anchor point */ + /* save color under marker */ + colorA = matBox[pt.x][pt.y]; + fAll = FALSE; + + fRepaint = TRUE; + break; + default: + AddDel(pt.x, pt.y, cursor); + fRepaint = TRUE; + cursor = FALSE; + break; + case FALSE: + switch (message) { + case WM_LBUTTONDOWN: /*invert */ + colorA = (matBox[pt.x][pt.y] ^= TRUE); + break; + + case WM_LBUTTONUP: + break; + + case WM_MOUSEMOVE: + matBox[pt.x][pt.y] = colorA; /* paint */ + break; + } + fRepaint = TRUE; + fAll = FALSE; /* Limited redraw */ + break; + } + if (fRepaint) { + BoxPaint(); + return; + } + } + cursor = FALSE; +} + + +/****************************************************************************** + * ReadRect(ptMouse) + * + * purpose: defines the rectangular region in edit box to be filled by + * fill menu command by fixing top left (ptA) and bottom right + * (ptB) coordinates of rect. + * + * params: + * + * assumes: that rectRubber is normalized (eg, left < right, botton > top) + * + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box). Also assigns values to ptA and ptB + *****************************************************************************/ +VOID +ReadRect( + ) +{ + + ptA.x = (rectRubber.left-(ptBox.x+1)) / scale; + ptA.y = (rectRubber.top-(ptBox.y+1)) / scale; + ptB.x = (rectRubber.right-(ptBox.x-2)) / scale - 1; + ptB.y = (rectRubber.bottom-(ptBox.y-2)) / scale - 1; + + if (((DWORD)ptB.x) > wBox - 1) + ptB.x = wBox - 1; + if (((DWORD)ptB.y) > kBox - 1) + ptB.y = kBox - 1; + + if (ptB.x >= 0 && ptB.y >= 0) { + ClearFill((DWORD)ptB.x, (DWORD)ptB.y, cursor); + BoxPaint(); + } + cursor = FALSE; +} + + +/****************************************************************************** + * ClearFill(col, row, mode) + * + * purpose: fill the specified rectangular region in edit box with fill type + * indicated by mode.Top left corner of rect is global(ptA) + * + * params: DWORD row : row (of bottom right corner of rect(ptB.x)) + * DWORD col : column (of bottom right corner of rect(ptB.y)) + * WORD mode: action to be performed + * + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +ClearFill( + DWORD col, + DWORD row, + WORD mode + ) +{ + DWORD i, x, y; + CHAR z; + + if (col < (DWORD)ptA.x) /* if points are reversed */ { + i = col; + col = ptA.x; + ptA.x = i; + } /* flip them */ + if (row < (DWORD) ptA.y) { + i = row; + row = ptA.y; + ptA.y = i; + } /* flip them */ + + if (mode == BOX_LEFTRIGHT) { + for (x = ptA.x; x <= (DWORD)((ptA.x + col) / 2); x++) + for (y = ptA.y; y <= row; y++) { + z = matBox[x][y]; + matBox[x][y] = matBox[ptA.x + col - x][y]; + matBox[ptA.x + col - x][y] = z; + } + return; + } + + if (mode == BOX_TOPBOTTOM) { + for (y = ptA.y; y <= ((DWORD)(ptA.y + row) / 2); y++) + for (x = ptA.x; x <= col; x++) { + z = matBox[x][y]; + matBox[x][y] = matBox[x][ptA.y + row - y]; + matBox[x][ptA.y + row - y] = z; + } + return; + } + + if (mode == BOX_COPY) + BoxToClipboard(ptA, col - ptA.x + 1, row - ptA.y + 1); + + if (mode == BOX_PASTE) + ClipboardToBox(ptA, col - ptA.x + 1, row - ptA.y + 1, FALSE); + + for (x = ptA.x; x <= col; x++) + for (y = ptA.y; y <= row; y++) { + switch (mode) { + case BOX_CLEAR: + case BOX_FILL: + matBox[x][y] = (CHAR)(mode == BOX_FILL); + break; + case BOX_INV: + matBox[x][y] ^= (CHAR)TRUE; + break; + case BOX_HATCH: + matBox[x][y] = (CHAR)((x+y)%2 ? TRUE : FALSE); + break; + } + } +} + + +/****************************************************************************** + * AddDel(col, row, mode) + * + * purpose: Add/Delete row/col as per mode + * + * params: DWORD row : row + * DWORD col : column + * WORD mode: action to be performed + * + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +AddDel( + DWORD col, + DWORD row, + WORD mode + ) +{ + switch (mode) { + case ROW_ADD: + DupRow(wBox, row); + break; + + case ROW_DEL: + ZapRow(wBox, row); + break; + + case COL_ADD: + DupCol(col, kBox); + break; + + case COL_DEL: + ZapCol(col, kBox); + break; + } + /* restore arrow cursor */ + SetCursor (hOldCursor); + ReleaseCapture(); + fCaptured = FALSE; + fJustZapped = TRUE; +} + + +/****************************************************************************** + * ZapCol(col, row) + * + * purpose: delete given column in edit box. Shift cols to right given col + * right. Rightmost column gets duplicated. + * + * params : DWORD col : column + * DWORD row : row + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +ZapCol( + DWORD col, + DWORD row + ) +{ + DWORD x, y; + for (y = 0; y <= row; y++) + for (x = col; x < wBox - 1; x++) + matBox[x][y] = matBox[x + 1][y]; + for (y = 0; y <= row; y++) + matBox[x][y] = matBox[x - 1][y]; +} + + +/****************************************************************************** + * ZapRow(col, row) + * + * purpose: delete given row in edit box. Shift rows below given row up. Lowest + * row gets duplicated + * + * params: DWORD col : column + * DWORD row : row + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +ZapRow( + DWORD col, + DWORD row + ) +{ + DWORD x, y; + for (x = 0; x <= col; x++) + for (y = row; y < kBox - 1; y++) + matBox[x][y] = matBox[x][y + 1]; + for (x = 0; x <= col; x++) + matBox[x][y] = matBox[x][y - 1]; +} + + +/****************************************************************************** + * DupCol(col, row) + * + * purpose: duplicate given column in edit box. Shift cols to right of given + * col right + * + * params: DWORD col : column + * DWORD row : row + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +DupCol( + DWORD col, + DWORD row + ) +{ + DWORD x, y; + for (x = wBox - 1; x > col; x--) + for (y = 0; y <= row; y++) + matBox[x][y] = matBox[x - 1][y]; +} + + +/****************************************************************************** + * DupRow(col, row) + * + * purpose: duplicate given row in edit box. Shift rows below given row down. + * + * params: DWORD col : column + * DWORD row : row + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + *****************************************************************************/ +VOID +DupRow( + DWORD col, + DWORD row + ) +{ + DWORD x, y; + for (x = 0; x <= col; x++) + for (y = kBox - 1; y > row; y--) + matBox[x][y] = matBox[x][y - 1]; +} + + +/****************************************************************************** + * ClearBox(col, row, bb) + * + * purpose: reset all pixels in edit box (make box white) + * + * params : none + * + * returns: none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box) + * + *****************************************************************************/ +VOID +ClearBox( + VOID + ) /* Clear edit box */ +{ + DWORD x, y; + for (x = 0; x < wBoxLim; x++) + for (y = 0; y < kBoxLim; y++) + matBox[x][y] = FALSE; +} + + +/****************************************************************************** + * BoxBackup() + * + * purpose: makes a backup of pix. info. of currently displayed edit box + * + * params: none + * + * returns: none + * + * side effects: alters matBackup (local 2-d array with backup pixel info. + * on edit box ) + *****************************************************************************/ +VOID +BoxBackup( + VOID + ) +{ + DWORD x, y; + HMENU hMenu; + + hMenu = GetMenu(hBox); + EnableMenuItem(hMenu, BOX_UNDO, MF_ENABLED); + EnableMenuItem(hMenu, BOX_REFRESH, MF_ENABLED); + for (x = 0; x < wBoxLim; x++) + for (y = 0; y < kBoxLim; y++) + matBackup[x][y] = matBox[x][y]; + wBoxBackup = wBox; +} + + +/****************************************************************************** + * BoxRestore() + * + * purpose : Current edit box and backup box exchange places + * + * params : none + * + * returns : none + * + * side effects: alters matBox (global 2-d array with ready pixel info. on + * currently displayed box + * + *****************************************************************************/ +VOID +BoxRestore( + VOID + ) /* Box and Backup exchange places */ +{ + DWORD x, y, temp; + CHAR z; + + for (x = 0; x < wBoxLim; x++) + for (y = 0; y < kBoxLim; y++) { + z = matBackup[x][y]; + matBackup[x][y] = matBox[x][y]; + matBox[x][y] = z; + } + temp = wBox; + wBox = wBoxBackup; + wBoxBackup = temp; +} + + +/****************************************************************************** + * POINT SnapPointToGrid (Pt) + * + * purpose : Intended only for the Fill menu command where rubberbanding rect. + * needs to be aligned on the grid lines. Snap the current mouse + * coordinates to nearest grid intersection. + * + * params : POINT Pt : current point mouse is over + * + * returns : POINT : number of nearest square + * + * side effects: : current mouse coordinate(global variable) altered to + * return value + * + *****************************************************************************/ +POINT +SnapPointToGrid( + POINT Pt + ) +{ + + Pt.x = (Pt.x - ptBox.x) / scale; + if (Pt.y > (scale * (font.Ascent - 1))) + Pt.y = Pt.y - 2; /* Allow for break in box */ + Pt.y = (Pt.y - ptBox.y) / scale; + return (Pt); +} + + +/****************************************************************************** + * VOID PASCAL EndRubberBandingRect() + * + * purpose: Stops rubberbanding rect for Fill menu command and cleans up + * + * params : HANDLE hDst : handle to dest. DC + * + * side effects: none + * + *****************************************************************************/ +VOID PASCAL +EndRubberBandingRect( + HDC hDst /* handle to dest. DC */ + ) +{ + fRubberBanding = FALSE; /* reset "in-progress" flag */ + + ReleaseDC(hBox, hDst); + ReleaseCapture(); + SetCursor(hOldCursor); +} + + +/****************************************************************************** + * HDC PASCAL InitialiseRubberBandingRect(hBox) + * + * purpose: Sets up rubberbanding rect for Fill menu command. + * + * params : HANDLE hDst : handle to box DC + * + * returns :handle to destination display context + * + * side effects: alters few global flags for rubberbanding + * + *****************************************************************************/ +HDC PASCAL +InitialiseRubberBandingRect( + HWND hBox /* handle to DC of box */ + ) +{ + HDC hDst; + + fRubberBanding = TRUE; /* set "in-progress" flag */ + fStartRubberBand = FALSE; /* reset "start-proceedings" flag */ + SetCapture(hBox); /* send all msgs to current window */ + + hDst = GetDC (hBox); + + /* select pen and fill mode for rectangle*/ + hWhitePen = SelectObject(hDst, GetStockObject (WHITE_PEN)); + hNullBrush = SelectObject(hDst, GetStockObject (NULL_BRUSH)); + SetROP2(hDst, R2_XORPEN); + + return(hDst); +} + + +/****************************************************************************** + * VOID PASCAL DrawRubberBand() + * + * purpose: Draw rubberbanding rect for Fill menu command. + * + * params : HANDLE hDst : handle to dest. DC + * + * side effects: alters few global flags for rubberbanding + * + *****************************************************************************/ +VOID PASCAL +DrawRubberBand( + HDC hDst, /* handle to dest. DC */ + LPRECT lpRect, + DWORD rop + ) +{ +#if DBG + char buf[256]; +#endif +#ifdef JAPAN + SIZE Size; + static LONG cxPrev; + INT nLeftRect; +#endif + + SetROP2(hDst, rop); + Rectangle(hDst, lpRect->left, lpRect->top, + lpRect->right, lpRect->bottom); + +#if DBG + sprintf(buf, "left=%d, top=%d, right=%d, bottom=%d", + lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + +#ifdef JAPAN + GetTextExtentPoint32(hDst, buf, lstrlen(buf), &Size); + nLeftRect = ptBox.x+scale*wBox+16 + Size.cx; + if(nLeftRect < cxPrev) { + RECT rc; + rc.left = nLeftRect; + rc.top = 14+2*kBox+font.ExtLeading+3*cSysHeight; + rc.right = cxPrev; + rc.bottom = 14+2*kBox+font.ExtLeading+3*cSysHeight + Size.cy; + FillRect(hDst, &rc, hbrBackGround); + } + cxPrev = nLeftRect; +#endif + TextOut(hDst, ptBox.x+scale*wBox+16, + 14+2*kBox+font.ExtLeading+3*cSysHeight, + buf, strlen(buf)); +#endif +} + + +/****************************************************************************** + * long APIENTRY FontEditWndProc(hBox, message, wParam, lParam) + * + * purpose: Master controller for Fontedit's all-encompassing main window + * + * params : same as for all window functions + * + * side effects: countless + * + *****************************************************************************/ +LONG APIENTRY +FontEditWndProc( + HWND hBox, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + PAINTSTRUCT ps; + HMENU hMenu; + WORD mf; + POINT pt; + RECT BoxRect; + + switch (message) { + case WM_CLOSE: + if (!CheckSave()) /* See if any files need saving */ + break; + /* Window's being destroyed. */ + if (fLoaded) /* 4/8/87 Linsh added */ + DeleteBitmap(); /* Get rid of memory DC */ + DestroyWindow(hFont); + DestroyWindow(hBox); + break; + + case WM_DESTROY: + PostQuitMessage(0); /* Cause application to be terminated */ + break; + + case WM_QUERYENDSESSION: + if (CheckSave()) /* See if any files need saving */ + return TRUE; + break; + + case WM_ENDSESSION: + if (fLoaded) + DeleteBitmap(); /* Get rid of memory DC */ + break; + + case WM_SIZE: + /* Window's size is changing. lParam contains the width + ** and height, in the low and high words, respectively. + ** wParam contains SIZENORMAL for "normal" size changes, + ** SIZEICONIC when the window is being made iconic, and + ** SIZEFULLSCREEN when the window is being made full screen. */ + switch (wParam) { + case SIZEFULLSCREEN: + case SIZENORMAL: + ResizeShow(); + if (kStuff != GetkStuff()) /* Did it change ? */ + ResizeShow(); /* Yes resize again */ + break; + } + break; + + case WM_MOVE: /* Tell popup to move with us. */ + if (!IsIconic(hBox)) + ResizeShow(); + break; + + case WM_PAINT: + /* Time for the window to draw itself. */ + BeginPaint(hBox, (LPPAINTSTRUCT)&ps); + FontEditPaint(hBox, ps.hdc); + EndPaint(hBox, (LPPAINTSTRUCT)&ps); + break; + + + case WM_COMMAND: + /* A menu item has been selected, or a control is notifying + * its parent. wParam is the menu item value (for menus), + * or control ID (for controls). For controls, the low word + * of lParam has the window handle of the control, and the hi + * word has the notification code. For menus, lParam contains + * 0L. */ + FontEditCommand(hBox, GET_WM_COMMAND_ID(wParam, lParam)); + break; + + /* Data interchange request. */ + case WM_CUT: + case WM_COPY: + case WM_PASTE: + case WM_CLEAR: + case WM_UNDO: + case WM_RENDERFORMAT: + case WM_RENDERALLFORMATS: + case WM_DESTROYCLIPBOARD: + case WM_DRAWCLIPBOARD: + break; + case WM_INITMENU: + hMenu = GetMenu(hBox); /* Gray menu if no clipboard bitmap */ + mf = (WORD)(IsClipboardFormatAvailable(CF_BITMAP) ? MF_ENABLED : + MF_GRAYED); + EnableMenuItem(hMenu, BOX_PASTE, mf); + EnableMenuItem(hMenu, FONT_PASTE, mf); + break; + + /* For each of following mouse window messages, wParam contains + ** bits indicating whether or not various virtual keys are down, + ** and lParam is a POINT containing the mouse coordinates. The + ** keydown bits of wParam are: MK_LBUTTON (set if Left Button is + ** down); MK_RBUTTON (set if Right Button is down); MK_SHIFT (set + ** if Shift Key is down); MK_ALTERNATE (set if Alt Key is down); + ** and MK_CONTROL (set if Control Key is down). */ + + case WM_LBUTTONDOWN: + MPOINT2POINT(MAKEMPOINT(lParam), pt); + + if (fStartRubberBand) { + /* a green signal to rubberband a rectangle for the + * Fill menu command rectangle now has null dimensions. + * Snap the current mouse point to nearest grid + * intersection thus defining upper left corner of + * rectangle */ + + if (PtInRect((LPRECT)&FontRect, pt)) { + pt = SnapPointToGrid(pt); + rectRubber.top = pt.y *scale+ptBox.y+1; + rectRubber.bottom = (pt.y+1)*scale+ptBox.y-2; + rectRubber.left = pt.x *scale+ptBox.x+1; + rectRubber.right = (pt.x+1)*scale+ptBox.x-2; + + hDst = InitialiseRubberBandingRect(hBox); + DrawRubberBand(hDst, &rectRubber, R2_XORPEN); + } + else { + fStartRubberBand = fRubberBanding = FALSE; + ReleaseCapture(); + } + } + /* do operation depending upon current active command, + * but not if we just added/deleted a row/column. */ + if (!fJustZapped) { + if (fStartRubberBand) { + pt.x *= scale; + pt.y *= scale; + MouseInBox(hBox, message, pt); + } + else { + MPOINT2POINT(MAKEMPOINT(lParam), pt); + MouseInBox(hBox, message, pt); + } + } + + break; + + case WM_LBUTTONUP: /* Get other corner of rectangle */ + fJustZapped = FALSE; + if (fRubberBanding) { + /* if rubberbanding for the Fill menu command, + * terminate proceedings and clean up */ + DrawRubberBand(hDst, &rectRubber, R2_NOT); + EndRubberBandingRect(hDst); + if (cursor) { + ReadRect(); + } + } + if (fCaptured ) { + /* if cursor is + shaped, restore it to default */ + ReleaseCapture(); + SetCursor (hOldCursor); + } + break; + + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + break; + + case WM_MOUSEMOVE: /* If mouse is down */ + + MPOINT2POINT(MAKEMPOINT(lParam), pt); + + if ((fRubberBanding) && (wParam & MK_LBUTTON)) { + /* if any of Fill menu commands is active + ** (AND the mouse key depressed) draw a rubberband + ** a rectangle with the mouse movements */ + + /* get current square number */ + pt = SnapPointToGrid(pt); + + /* calculate grid for new square */ + BoxRect.top = pt.y *scale+ptBox.y+1; + BoxRect.bottom = (pt.y+1)*scale+ptBox.y-2; + BoxRect.left = pt.x *scale+ptBox.x+1; + BoxRect.right = (pt.x+1)*scale+ptBox.x-2; + + /* erase old mark */ + DrawRubberBand(hDst, &rectRubber, R2_NOT); + + /* limit rubber band to box */ + if (BoxRect.right > scale * (LONG)wBox + ptBox.x) + BoxRect.right = scale * wBox + ptBox.x; + if (BoxRect.bottom > scale * (LONG)kBox + ptBox.y) + BoxRect.bottom = scale * kBox + ptBox.y; + if (BoxRect.top < 0) + BoxRect.top = 1; + if (BoxRect.left < 0) + BoxRect.left = 1; + + if (ptA.x == pt.x) { + rectRubber.right = BoxRect.right; + rectRubber.left = BoxRect.left; + } + if (ptA.y == pt.y) { + rectRubber.bottom = BoxRect.bottom; + rectRubber.top = BoxRect.top; + } + + /* almost an IntersectRect */ + if (ptA.x >= pt.x) + rectRubber.left = BoxRect.left; + else + rectRubber.right = BoxRect.right; + + if (ptA.y >= pt.y) + rectRubber.top = BoxRect.top; + else + rectRubber.bottom = BoxRect.bottom; + + /* Draw new mark */ + DrawRubberBand(hDst, &rectRubber, R2_XORPEN); + } + else { + /* if not "Fill"ing(AND mouse key depressed, + * paint with the mouse movements */ + if ((wParam & MK_LBUTTON) && cursor == FALSE && + fJustZapped == FALSE) + MouseInBox(hBox, message, pt); + } + break; + + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + break; + + default: + + /* Everything else comes here. This call MUST exist + ** in your window proc. */ + + return(DefWindowProc(hBox, message, wParam, lParam)); + break; + } + + /* A window proc should always return something */ + return(0L); +} + + +/***************************** Public Function ****************************\ +* +* BOOL APIENTRY AboutDlg(hDlg, message, wParam, lParam) +* HWND hDlg; +* WORD message; +* WPARAM wParam; +* LONG lParam; +* +* +* Effects: none. +* +\***************************************************************************/ +BOOL APIENTRY +AboutDlg( + HWND hDlg, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (message) { + case WM_INITDIALOG: + break; + + case WM_COMMAND: + EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam)); + /* idok or idcancel */ + break; + + default: + return FALSE; + break; + } + return(TRUE); +} diff --git a/private/sdktools/fontedit/fontcvt.c b/private/sdktools/fontedit/fontcvt.c new file mode 100644 index 000000000..bb66f4819 --- /dev/null +++ b/private/sdktools/fontedit/fontcvt.c @@ -0,0 +1,577 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + fontcvt.c + +Abstract: + + Font Editor specific routines for interface to the type conversion + functions in Typecvt.c. + +Author: + + David J. Marsyla (t-davema) 6-Aug-1991 + +Revision History: + + +--*/ + + +#include "windows.h" +#include <port1632.h> +#include "typecvt.h" +#include "fontedit.h" + + +extern LONG lSizeOfOldFontHeader; /* Old packed font header size. */ +extern LONG lSizeOfOldFontHeader30; /* Old 3.0 packed font header size. */ +extern LONG lSizeOfOldGlyph20; /* Old packed glyph 2.0 structure. */ +extern LONG lSizeOfOldGlyph30; /* Old packed glyph 3.0 structure. */ + + +// +// The following is a definition of the current 2.0 font header structure. +// This is the same as the old structure except that it will now be stored +// DWORD aligned in memory. +// +// First, we give it the size of the element type (as it was under Win 3.0). +// Second, we give it the actual size of the element. These will only differ +// if the element is some sort of array. +// +// Note that it is important that this array accurately reflect any changes +// in the actual structure. When CalculateStructOffsets is called it will +// return an error if the structure does not match in size, but it cannot +// detect swapped element errors. +// + +#define pfh2T ((FontHeaderType *)NULL) + +SDI rgsdiFontHeader [] = +{ + { sizeof (WORD), sizeof (pfh2T->Version) }, + { sizeof (DWORD), sizeof (pfh2T->Size) }, + { sizeof (CHAR), sizeof (pfh2T->Copyright) }, + { sizeof (WORD), sizeof (pfh2T->Type) }, + { sizeof (WORD), sizeof (pfh2T->Points) }, + { sizeof (WORD), sizeof (pfh2T->VertRes) }, + { sizeof (WORD), sizeof (pfh2T->HorizRes) }, + { sizeof (WORD), sizeof (pfh2T->Ascent) }, + { sizeof (WORD), sizeof (pfh2T->IntLeading) }, + { sizeof (WORD), sizeof (pfh2T->ExtLeading) }, + { sizeof (BYTE), sizeof (pfh2T->Italic) }, + { sizeof (BYTE), sizeof (pfh2T->Underline) }, + { sizeof (BYTE), sizeof (pfh2T->StrikeOut) }, + { sizeof (WORD), sizeof (pfh2T->Weight) }, + { sizeof (BYTE), sizeof (pfh2T->CharSet) }, + { sizeof (WORD), sizeof (pfh2T->PixWidth) }, + { sizeof (WORD), sizeof (pfh2T->PixHeight) }, + { sizeof (BYTE), sizeof (pfh2T->Family) }, + { sizeof (WORD), sizeof (pfh2T->AvgWidth) }, + { sizeof (WORD), sizeof (pfh2T->MaxWidth) }, + { sizeof (BYTE), sizeof (pfh2T->FirstChar) }, + { sizeof (BYTE), sizeof (pfh2T->LastChar) }, + { sizeof (BYTE), sizeof (pfh2T->DefaultChar) }, + { sizeof (BYTE), sizeof (pfh2T->BreakChar) }, + { sizeof (WORD), sizeof (pfh2T->WidthBytes) }, + { sizeof (DWORD), sizeof (pfh2T->Device) }, + { sizeof (DWORD), sizeof (pfh2T->Face) }, + { sizeof (DWORD), sizeof (pfh2T->BitsPointer) }, + { sizeof (DWORD), sizeof (pfh2T->BitsOffset) }, + { 0, 0 } +}; + +// +// The following is the current font 3.0 header. This structure has not +// changed at all. Note that it will contain filler between elements to +// maintain DWORD alignment. +// + +#define pfh3T ((FontHeader30 *)NULL) + +SDI rgsdiFontHeader30 [] = +{ + { sizeof (WORD), sizeof (pfh3T->fsVersion) }, + { sizeof (DWORD), sizeof (pfh3T->fsSize) }, + { sizeof (CHAR), sizeof (pfh3T->fsCopyright) }, + { sizeof (WORD), sizeof (pfh3T->fsType) }, + { sizeof (WORD), sizeof (pfh3T->fsPoints) }, + { sizeof (WORD), sizeof (pfh3T->fsVertRes) }, + { sizeof (WORD), sizeof (pfh3T->fsHorizRes) }, + { sizeof (WORD), sizeof (pfh3T->fsAscent) }, + { sizeof (WORD), sizeof (pfh3T->fsInternalLeading) }, + { sizeof (WORD), sizeof (pfh3T->fsExternalLeading) }, + { sizeof (BYTE), sizeof (pfh3T->fsItalic) }, + { sizeof (BYTE), sizeof (pfh3T->fsUnderline) }, + { sizeof (BYTE), sizeof (pfh3T->fsStrikeOut) }, + { sizeof (WORD), sizeof (pfh3T->fsWeight) }, + { sizeof (BYTE), sizeof (pfh3T->fsCharSet) }, + { sizeof (WORD), sizeof (pfh3T->fsPixWidth) }, + { sizeof (WORD), sizeof (pfh3T->fsPixHeight) }, + { sizeof (BYTE), sizeof (pfh3T->fsPitchAndFamily) }, + { sizeof (WORD), sizeof (pfh3T->fsAvgWidth) }, + { sizeof (WORD), sizeof (pfh3T->fsMaxWidth) }, + { sizeof (BYTE), sizeof (pfh3T->fsFirstChar) }, + { sizeof (BYTE), sizeof (pfh3T->fsLastChar) }, + { sizeof (BYTE), sizeof (pfh3T->fsDefaultChar) }, + { sizeof (BYTE), sizeof (pfh3T->fsBreakChar) }, + { sizeof (WORD), sizeof (pfh3T->fsWidthBytes) }, + { sizeof (DWORD), sizeof (pfh3T->fsDevice) }, + { sizeof (DWORD), sizeof (pfh3T->fsFace) }, + { sizeof (DWORD), sizeof (pfh3T->fsBitsPointer) }, + { sizeof (DWORD), sizeof (pfh3T->fsBitsOffset) }, + { sizeof (CHAR), sizeof (pfh3T->fsDBfiller) }, + { sizeof (DWORD), sizeof (pfh3T->fsFlags) }, + { sizeof (WORD), sizeof (pfh3T->fsAspace) }, + { sizeof (WORD), sizeof (pfh3T->fsBspace) }, + { sizeof (WORD), sizeof (pfh3T->fsCspace) }, + { sizeof (DWORD), sizeof (pfh3T->fsColorPointer) }, + { sizeof (DWORD), sizeof (pfh3T->fsReserved) }, + { sizeof (CHAR), sizeof (pfh3T->fsCharOffset) }, + { 0, 0 } +}; + +// +// The following definition is for the GlyphInfo20 structure. These +// structures are read off of disk and then converted into memory. +// + +#define pgi2T ((GLYPHINFO_20 *)NULL) + +SDI rgsdiGlyph20 [] = +{ + { sizeof (SHORT), sizeof (pgi2T->GIwidth) }, + { sizeof (SHORT), sizeof (pgi2T->GIoffset) }, + { 0, 0 } +}; + +// +// The following definition is for the GlyphInfo30 structure. These +// structures are read off of disk and then converted into memory. +// + +#define pgi3T ((GLYPHINFO_30 *)NULL) + +SDI rgsdiGlyph30 [] = +{ + { sizeof (SHORT), sizeof (pgi3T->GIwidth) }, + { sizeof (LONG), sizeof (pgi3T->GIoffset) }, + { 0, 0 } +}; + + + +BOOL +fConvStructInit () + +/*++ + +Routine Description: + + This function performs all the necessary initialization on the font + editor's structure definition info strucrures (SDI) and type conversion + structures (TCI). This routine should be called before either + FontStructFromBuffer or BufferFromFontStruct are called. + It is also important that this function be called before the global + variable ulOldFontHeaderSize is accessed. + +Arguments: + + None. The function accesses the global definition structures and sets + the variable ulOldFontHeaderSize to the size of the packed font header + structure. + +Return Value: + + BOOL - TRUE = the function successfully initialized all internal + strucutres. + FALSE = there was an error in one of the structure definitions. + This is usually caused by element changes which are not reflected + in the structure definition. The program should perform an + assertion failure if this is the case. + Also, the global variable ulOldFontHeaderSize is set to the size of the + packed font header structure. + +--*/ + +{ + //LONG lFontHeaderSize; // Temp variable. + + // + // Calculate all of the element offsets for the old font header structure. + // The function will return the size of the structure in packed format. + // + lSizeOfOldFontHeader = lCalculateStructOffsets ( + rgsdiFontHeader, // Give it the struct definition. + CVT_ALIGN_PACKED, // Alignment type is packed on disk. + sizeof (FontHeaderType) + ); + + // + // If CalculateStructOffsets returns -1 then there was a problem with + // structure definition. The only types of error it can find is if the + // structure size it is passed does not match the one it calculates. + // + if (lSizeOfOldFontHeader == -1) { + return (FALSE); + } + + // + // Calculate The size of the old font 3.0 structure. + // The function will return the size of the structure in packed format. + // + + lSizeOfOldFontHeader30 = lCalculateStructOffsets ( + rgsdiFontHeader30, // Give it the new font header struct. + CVT_ALIGN_PACKED, // Alignment type is packed on disk. + sizeof (FontHeader30) + ); + + // + // Check if the routine detected and error in the structure definition. + // + if (lSizeOfOldFontHeader30 == -1) { + return (FALSE); + } + + // + // Now do the same operations on the glyph information structures. + // + + lSizeOfOldGlyph20 = lCalculateStructOffsets ( + rgsdiGlyph20, + CVT_ALIGN_PACKED, + sizeof (GLYPHINFO_20) + ); + + if (lSizeOfOldGlyph20 == -1) { + return (FALSE); + } + + lSizeOfOldGlyph30 = lCalculateStructOffsets ( + rgsdiGlyph30, + CVT_ALIGN_PACKED, + sizeof (GLYPHINFO_30) + ); + + if (lSizeOfOldGlyph30 == -1) { + return (FALSE); + } + + return (TRUE); // No error found. +} + + +VOID +vFontStructFromBuffer ( + PBYTE pjSourceBuff, + FontHeaderType *pfhDestFHStruct + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pjSourceBuff - This is a pointer to the source buffer with the old + packed font header information. This buffer is from a + memory mapped disk file. + + pfhDestFHStruct - This is a pointer to the destination FontHeaderType + structure. This structure is of the new DWORD aligned + type. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiFontHeader, // Give it the structure description. + pjSourceBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT, // Use file endian type (little). + (PBYTE)pfhDestFHStruct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM // Use the current system endian. + ); +} + + +VOID +vBufferFromFontStruct ( + FontHeaderType *pfhSrcFHStruct, + PBYTE pjDestBuff + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It converts a source structure of type FontHeaderType to a destination + buffer which can then be written out to disk. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pfhSrcFHStruct - This is a pointer to the source FontHeaderType structure. + This structure is of the new DWORD aligned type. + + pjDestBuff - This is a pointer to the destination buffer which will + hold the old packed font header structure. + This buffer is from a memory mapped disk file. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiFontHeader, // Give it the structure description. + (PBYTE)pfhSrcFHStruct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM, // Use the current system endian. + pjDestBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT // Use file endian type (little). + ); +} + + +VOID +vBufferFromFont30Struct ( + FontHeader30 *pfh3SrcFH3Struct, + PBYTE pjDestBuff + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It converts a source structure of type FontHeader30 to a destination + buffer which can then be written out to disk. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pfh3SrcFH3Struct- This is a pointer to the source FontHeader30 structure. + This structure is of the new DWORD aligned type. + + pjDestBuff - This is a pointer to the destination buffer which will + hold the old packed font header structure. + This buffer is from a memory mapped disk file. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiFontHeader30, // Give it the structure description. + (PBYTE)pfh3SrcFH3Struct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM, // Use the current system endian. + pjDestBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT // Use file endian type (little). + ); +} + + +VOID +vGlyphInfo20FromBuffer ( + PBYTE pjSourceBuff, + GLYPHINFO_20 *pgi2DestGI2Struct + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pjSourceBuff - This is a pointer to the source buffer with the old + packed font header information. This buffer is from a + memory mapped disk file. + + pgi2DestGI2Struct - This is a pointer to the destination GLYPHINFO_20 + structure. This structure is of the new DWORD aligned + type. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiGlyph20, // Give it the structure description. + pjSourceBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT, // Use file endian type (little). + (PBYTE)pgi2DestGI2Struct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM // Use the current system endian. + ); +} + + +VOID +vGlyphInfo30FromBuffer ( + PBYTE pjSourceBuff, + GLYPHINFO_30 *pgi3DestGI3Struct + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pjSourceBuff - This is a pointer to the source buffer with the old + packed font header information. This buffer is from a + memory mapped disk file. + + pgi3DestGI3Struct - This is a pointer to the destination GLYPHINFO_30 + structure. This structure is of the new DWORD aligned + type. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiGlyph30, // Give it the structure description. + pjSourceBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT, // Use file endian type (little). + (PBYTE)pgi3DestGI3Struct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM // Use the current system endian. + ); +} + + +VOID +vBufferFromGlyphInfo20 ( + GLYPHINFO_20 *pgi2SrcGI2Struct, + PBYTE pjDestBuff + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It converts a source structure of type GLYPHINFO_20 to a destination + buffer which can then be written out to disk. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pgi2SrcGI2Struct- This is a pointer to the source GLYPHINFO_20 structure. + This structure is of the new DWORD aligned type. + + pjDestBuff - This is a pointer to the destination buffer which will + hold the old packed font header structure. + This buffer is from a memory mapped disk file. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiGlyph20, // Give it the structure description. + (PBYTE)pgi2SrcGI2Struct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM, // Use the current system endian. + pjDestBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT // Use file endian type (little). + ); +} + + +VOID +vBufferFromGlyphInfo30 ( + GLYPHINFO_30 *pgi3SrcGI3Struct, + PBYTE pjDestBuff + ) + +/*++ + +Routine Description: + + This function provides an interface to the font editor for the strutcture + type conversion routines. + It converts a source structure of type GLYPHINFO_30 to a destination + buffer which can then be written out to disk. + It essentially just calls the typecvt routines but hides the details from + the font editor. + +Arguments: + + pgi3SrcGI3Struct- This is a pointer to the source GLYPHINFO_30 structure. + This structure is of the new DWORD aligned type. + + pjDestBuff - This is a pointer to the destination buffer which will + hold the old packed font header structure. + This buffer is from a memory mapped disk file. + +Return Value: + + None. + +--*/ + +{ + vPerformConversion ( + rgsdiGlyph30, // Give it the structure description. + (PBYTE)pgi3SrcGI3Struct, // Give it our destination buffer. + CVT_ALIGN_SYSTEM, // Use the current system aligment. + CVT_ENDIAN_SYSTEM, // Use the current system endian. + pjDestBuff, // Give it our source file buffer. + CVT_ALIGN_PACKED, // File is packed alignment. + CVT_FILE_ENDIAN_DEFAULT // Use file endian type (little). + ); +} diff --git a/private/sdktools/fontedit/fontdlg.c b/private/sdktools/fontedit/fontdlg.c new file mode 100644 index 000000000..ca6d1cd89 --- /dev/null +++ b/private/sdktools/fontedit/fontdlg.c @@ -0,0 +1,380 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + fontdlg.c + +Abstract: + + Font Editor interface to the common dialog Open File and Save File + functions. Also, this routine displays and controls the font format + save dialog. + +Author: + + David J. Marsyla (t-davema) 22-Aug-1991 + +Revision History: + + +--*/ + + +#include "windows.h" +#include <port1632.h> +#include "fontedit.h" +#include "commdlg.h" + + +/* message box strings loaded in sample.c from the stringtable */ +extern CHAR szIFN[], szFNF[], szREF[], szSCC[], szEOF[], szECF[]; + +extern CHAR szAppName []; +extern CHAR szExt []; +extern CHAR szExtDesc []; + +extern CHAR szNEWFONT []; +extern CHAR szFRO []; + +extern INT iFontFormat; /* Set to the id of current font format */ +extern BOOL fReadOnly; + +CHAR szDlgMsg [MAX_STR_LEN+MAX_FNAME_LEN]; + +extern CHAR szFilter[]; + +// +// Local Function Prototypes. +// + +BOOL +DlgCheckFormat ( + HANDLE hInstance, // app module instance handle + HWND hWndParent // window handle of parent window + ); + +BOOL APIENTRY +DlgFnCheckFormat ( + HWND hDlg, + WORD message, + WPARAM wParam, + LONG lParam + ); + +// +// Functions. +// + +BOOL +CommDlgOpen ( + HWND hWndParent, /* window handle of parent window */ + OFSTRUCT *pofsReOpenInfo,/* ptr to current file OFSTRUCT (->cBytes=0 if no + * cur. file)*/ + CHAR *pszNewNameIn, /* ptr to array which will get new file's name + * (no path) */ + CHAR *pszExtIn, /* ptr to current default extension */ + CHAR *pszFileNameOnly, /* ptr to application name */ + BOOL fOpenType + ) +{ + OPENFILENAME ofTempOF; + HFILE hFile; + CHAR szBuf[_MAX_PATH]; + + ofTempOF.lStructSize = sizeof(OPENFILENAME); + ofTempOF.hwndOwner = hWndParent; + ofTempOF.lpstrFilter = szFilter; + ofTempOF.lpstrCustomFilter = (LPSTR)NULL; + ofTempOF.nMaxCustFilter = 0L; + ofTempOF.nFilterIndex = 0L; + ofTempOF.lpstrFile = pszNewNameIn; + ofTempOF.nMaxFile = MAX_FNAME_LEN; + ofTempOF.lpstrFileTitle = pszFileNameOnly; + ofTempOF.nMaxFileTitle = MAX_FNAME_LEN; + ofTempOF.lpstrInitialDir = (LPSTR)NULL; + ofTempOF.lpstrTitle = (LPSTR)NULL; + ofTempOF.Flags = 0; + ofTempOF.nFileOffset = 0; + ofTempOF.nFileExtension = 0; + ofTempOF.lpstrDefExt = pszExtIn; + + if (fOpenType == FONT_NEW) + { + if (MessageBox (hWndParent, (LPSTR)szNEWFONT, (LPSTR)szAppName, + MB_OKCANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL) == IDCANCEL) + { + return (FALSE); + } + } + + // save lpstrFile. Because if GetSaveFileName returns 0(i.e. select + // [Cancel] in dialog, pointer to lpstrFile will be lost. + lstrcpy(szBuf,pszNewNameIn); + if (GetOpenFileName (&ofTempOF) == FALSE) + { + lstrcpy(pszNewNameIn,szBuf); + return (FALSE); + } + + CharUpper (pszNewNameIn); + + fReadOnly = FALSE; + + hFile = MOpenFile (pszNewNameIn, pofsReOpenInfo, OF_READWRITE); + + if (hFile == (HFILE) -1) { + + hFile = MOpenFile (pszNewNameIn, pofsReOpenInfo, OF_READ); + + if (hFile == (HFILE) -1) { + + DlgMergeStrings (szFNF, pszNewNameIn, szDlgMsg); + + MessageBox (hWndParent, szDlgMsg, szAppName, + MB_OK | MB_ICONASTERISK | MB_APPLMODAL); + + return (FALSE); + + } else if (fOpenType != FONT_NEW) { + + BOOL fResult; + + DlgMergeStrings (szFRO, pszNewNameIn, szDlgMsg); + + /* File Is Read Only */ + fResult = MessageBox (hWndParent, szDlgMsg, szAppName, + MB_OKCANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL); + + /* Give them the chance to cancel right now. */ + if (fResult == IDCANCEL) { + + M_lclose (hFile); + return (FALSE); + } + + fReadOnly = TRUE; + } + } + + M_lclose (hFile); + + return (TRUE); +} + +BOOL +CommDlgSaveAs( + HANDLE hInstance, + HWND hWndParent, /* window handle of parent window */ + OFSTRUCT *pofsReOpenInfo,/* ptr to current file OFSTRUCT (->cBytes=0 if no + * cur. file)*/ + CHAR *pszNewNameIn, /* ptr to array which will get new file's name + * (no path) */ + CHAR *pszExtIn, /* ptr to current default extension */ + CHAR *pszFileNameOnly /* ptr to file name */ + ) +{ + OPENFILENAME ofTempOF; + HFILE hFile; + CHAR szBuf[_MAX_PATH]; + + ofTempOF.lStructSize = sizeof(OPENFILENAME); + ofTempOF.hwndOwner = hWndParent; + ofTempOF.lpstrFilter = szFilter; + ofTempOF.lpstrCustomFilter = (LPSTR)NULL; + ofTempOF.nMaxCustFilter = 0L; + ofTempOF.nFilterIndex = 0L; + ofTempOF.lpstrFile = pszNewNameIn; + ofTempOF.nMaxFile = MAX_FNAME_LEN; + ofTempOF.lpstrFileTitle = pszFileNameOnly; + ofTempOF.nMaxFileTitle = MAX_FNAME_LEN; + ofTempOF.lpstrInitialDir = (LPSTR)NULL; + ofTempOF.lpstrTitle = (LPSTR)NULL; + ofTempOF.Flags = OFN_SHOWHELP; + ofTempOF.nFileOffset = 0; + ofTempOF.nFileExtension = 0; + ofTempOF.lpstrDefExt = pszExtIn; + + if (DlgCheckFormat (hInstance, hWndParent) == FALSE) + { + return (FALSE); + } + + // save lpstrFile. Because if GetSaveFileName returns 0(i.e. select + // [Cancel] in dialog, pointer to lpstrFile will be lost. + lstrcpy(szBuf,pszNewNameIn); + if (GetSaveFileName (&ofTempOF) == FALSE) + { + lstrcpy(pszNewNameIn,szBuf); + return (FALSE); + } + + CharUpper (pszNewNameIn); + + hFile = MOpenFile (pszNewNameIn, pofsReOpenInfo, OF_EXIST); + + if (hFile >= (HFILE) 0) /* already exists */ + { + M_lclose (hFile); + + DlgMergeStrings (szREF, pszNewNameIn, szDlgMsg); + + if (MessageBox (hWndParent, (LPSTR)szDlgMsg, (LPSTR)pszNewNameIn, + MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION | MB_APPLMODAL) + == IDNO) + { + return (FALSE); + } + + hFile = MOpenFile (pszNewNameIn, pofsReOpenInfo, OF_WRITE); + + if (hFile == (HFILE) -1) + { + DlgMergeStrings(szEOF, pszNewNameIn, szDlgMsg); + + MessageBox(hWndParent, (LPSTR)szDlgMsg, (LPSTR)pszNewNameIn, + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + + return (FALSE); + } + + M_lclose (hFile); + + return (TRUE); + } + + hFile = MOpenFile (pszNewNameIn, pofsReOpenInfo, OF_CREATE); + + if (hFile == (HFILE) -1) + { + DlgMergeStrings(szECF, pszNewNameIn, szDlgMsg); + + MessageBox(hWndParent, (LPSTR)szDlgMsg, (LPSTR)pszNewNameIn, + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + + return (FALSE); + } + + M_lclose (hFile); + + return (TRUE); + +} /* end dlgsaveas */ + + +/*============================================================================= + DLGMERGESTRINGS scans string1 for merge spec (%%). If found, insert string2 at + that point, and then append remainder of string1. Result in string3. +==============================================================================*/ +BOOL +DlgMergeStrings( + CHAR *szSrc, + CHAR *szMerge, + CHAR *szDst + ) +{ + CHAR *pchSrc; + CHAR *pchDst; + + pchSrc = szSrc; + pchDst = szDst; + + /* Find merge spec if there is one. */ + while (!((*pchSrc == '%') && (*(pchSrc+1) == '%'))) { + *pchDst++ = *pchSrc; + + /* If we reach end of string before merge spec, just return. */ + if (!*pchSrc++) + return FALSE; + + } + /* If merge spec found, insert sz2 there. (check for null merge string */ + if (szMerge) { + while (*szMerge) + *pchDst++ = *szMerge++; + + } + + /* Jump over merge spec */ + pchSrc++; pchSrc++; + + + /* Now append rest of Src String */ + while (*pchDst++ = *pchSrc++); + return TRUE; + +} /* end dlgmergestrings */ + + +BOOL +DlgCheckFormat ( + HANDLE hInstance, // app module instance handle + HWND hWndParent // window handle of parent window + ) +{ + //FARPROC lpProc; + BOOL fResult; + + fResult = DialogBox (hInstance, (LPSTR)MAKEINTRESOURCE (IDD_FORMAT), + //hWndParent, (WNDPROC)(lpProc = DlgFnCheckFormat)); + hWndParent, (WNDPROC)DlgFnCheckFormat); + + //FreeProcInstance(lpProc); + + return (fResult); + +} /* end dlgcheckformat */ + + +BOOL APIENTRY +DlgFnCheckFormat ( + HWND hDlg, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + + switch (message) + { + + case WM_INITDIALOG: + CheckRadioButton (hDlg, ID_FORMAT2, ID_FORMAT3, iFontFormat); + break; + + case WM_COMMAND: + + switch (GET_WM_COMMAND_ID(wParam, lParam)) + { + case IDOK: + + EndDialog (hDlg, TRUE); + break; + + case IDCANCEL: + EndDialog (hDlg, FALSE); + break; + + case ID_FORMAT2: + case ID_FORMAT3: + CheckRadioButton(hDlg, ID_FORMAT2,ID_FORMAT3, + iFontFormat = GET_WM_COMMAND_ID(wParam,lParam)); + break; + + default: + + return FALSE; + + } /* end switch wparam */ + break; + + default: + + return FALSE; + + } /* end switch message */ + + return TRUE; + +} /* end dlgsaveasdlg */ diff --git a/private/sdktools/fontedit/fontedit.c b/private/sdktools/fontedit/fontedit.c new file mode 100644 index 000000000..e60a19ac3 --- /dev/null +++ b/private/sdktools/fontedit/fontedit.c @@ -0,0 +1,1055 @@ +#define NOVIRTUALKEYCODES + +#include "windows.h" +#include <port1632.h> +#include "fontedit.h" +#include "fcntl.h" +#include <stdlib.h> // Causes redefinition warnings. +#include <string.h> + +/****************************************************************************/ +/* Shared Variables (Home base) */ +/****************************************************************************/ + +FARPROC lpHeaderProc; /* Pointer to Dialog Box Procedure */ +FARPROC lpReSizeProc; /* Pointer to Dialog Box Procedure */ +FARPROC lpWidthProc; /* Pointer to Dialog Box Procedure */ + +FontHeaderType font; /* Structure of Font File Header */ +LONG lSizeOfOldFontHeader = 0; /* Old packed header size. */ +LONG lSizeOfOldFontHeader30 = 0; /* Old 3.0 packed header size. */ +LONG lSizeOfOldGlyph20 = 0; /* Old packed 2.0 glyph info size. */ +LONG lSizeOfOldGlyph30 = 0; /* Old packed 3.0 glyph info size. */ +extern CHAR szFontFile[]; /* Name of Font File */ +extern CHAR szFontFileFull[]; /* Name of Font File */ +extern CHAR szNewFile[]; /* Temporary Name */ +extern BOOL NewFile; /* flag indicating if file was opened + by selecting NEW menu item */ +HCURSOR hCross; /* handle to a "+" shaped cursor */ +HANDLE hInst; /* Handle to Window Instance */ +HANDLE hgPrev; +INT swH = 0; /* Position in Show Window 0-100 */ +BYTE iChar = 65; /* Character being edited */ +BYTE jChar = 65; /* Last Char. of edit block */ +CHAR szFaceName[szNamesMax] = {""}; /* Face Name of Font */ +DWORD offsets[257]; /* Offsets Table */ +CHAR *vrgsz[CSTRINGS]; /* string table */ +CHAR gszHelpFile[MAX_PATH]; + +BOOL fChanged = FALSE; /* Note if we did anything */ +BOOL fLoaded = FALSE; /* Set if a font is loaded */ +BOOL fEdited = FALSE; /* Character was edited */ +INT iFontFormat; /* Set to id of current font format */ +INT iFontFormatPrev; /* Set to id of prev. font format */ +BOOL fReadOnly; + +HWND hBox = NULL; /* Handle to Edit Window */ +HWND hFont = NULL; /* Handle to Show window */ +HDC hMemDC = NULL; /* Handle to Memory Display Context */ +HBITMAP hBitmap = NULL; /* Handle to our work bit map */ + +CHAR matBox [wBoxLim] [kBoxLim]; /* array to hold Box */ +DWORD wBox = 10; /* Width of Character(s) */ +DWORD kBox = 16; /* Height of Characters */ +DWORD kStuff; /* Height of font window caption etc. */ + +OFSTRUCT ofstrFile; /* holds info of file - filled in by dlgopen/save */ +//WORD fp = NULL; /* global fp of current file - " " " " " " */ + +/*** string arrays for using stringtable ***/ +CHAR szAppName[MAX_STR_LEN]; +CHAR szIFN[MAX_STR_LEN]; /* illegal filename */ +CHAR szFNF[MAX_STR_LEN]; /* file not found */ +CHAR szREF[MAX_STR_LEN]; /* replace existing file */ +CHAR szSCC[MAX_STR_LEN]; /* save current changes */ +CHAR szEOF[MAX_STR_LEN]; /* error opening file */ +CHAR szECF[MAX_STR_LEN]; /* error creating file */ +CHAR szFRO[MAX_STR_LEN]; /* error creating file */ +CHAR szExt[MAX_STR_LEN]; /* .FNT */ +CHAR szExtDesc[MAX_STR_LEN]; /* Font Files(.FNT) */ +CHAR szNEWFONT[MAX_STR_LEN]; /* Font Files(.FNT) */ +CHAR szFilter[MAX_STR_LEN]; /* Font Files(.FNT) */ + + +/* size of system font */ +INT cSysWidth; +INT cSysHeight; + +/****************************************************************************/ +/* Local Variables */ +/****************************************************************************/ + +BYTE FindMouse(); /* Find where mouse is */ + +HBRUSH hbrWhite; +HBRUSH hbrBlack; +HBRUSH hbrGray; +HBRUSH hbrDkGray; +HBRUSH hbrBackGround; + +BYTE downChar; /* Where mouse was pressed */ +BYTE lastChar; /* Where mouse was last */ +WORD wBoxOld; /* So we can catch any changes */ +RECT rectWin; /* Client Rectangle */ +LONG origin; /* Position in Show Window pixels */ +BOOL fFirstShow = TRUE; /* first time Show Window displayed? */ + +/****************************************************************************/ +/* Local Functions */ +/****************************************************************************/ + +VOID InvertFont(HDC, BYTE, BYTE); +BOOL FontEditInit(HANDLE); +VOID InitSizes(VOID); + +/***************************************************************************** + * FontShowHorzScroll(hFont, code, posNew) + * + * purpose: intepret scroll message for tiny window and call scroll funtion + * accordingly + * + * params: HWND hFont : handle to tiny window + * int code : scroll message + * int posNew : thumb position + * returns: none + * + * side effects: scroll position variable altered + * + ****************************************************************************/ +VOID +FontShowHorzScroll( + HWND hFont, + INT code, + INT posNew + ) +{ + WORD wChar; + RECT rect; + + /* Get dimensions */ + GetClientRect(hFont, (LPRECT)&rect); + + /* Make a fair guess as to how many characters are in the window */ + /* Convert sorta to hex too. */ +#ifdef JAPAN + if (font.AvgWidth == 0 ) { + font.AvgWidth = 1 ; + } +#endif + wChar=(WORD)(11*(rect.right-rect.left)/(font.AvgWidth*16)); + + switch (code) + { + case SB_LINEUP: /* line left */ + swH -= 1; + break; + case SB_LINEDOWN: /* line right */ + swH += 1; + break; + case SB_PAGEUP: /* page left */ + swH -= wChar; + break; + case SB_PAGEDOWN: /* page right */ + swH += wChar; + break; + case SB_THUMBPOSITION: + swH = posNew; + break; + case SB_THUMBTRACK: + return; + } + ScrollFont(); +} + +/***************************************************************************** + * FontShowPaint(hDC) + * + * purpose: repaint the little window at the bottom + * + * params: HDC hDC : handle to display context. + * + * returns: none + * + * side effects: some scroll globals altered. + * + ****************************************************************************/ + +VOID +FontShowPaint( + HDC hDC + ) +{ + DWORD range, nBits; + INT nx; + + nx=GetSystemMetrics(SM_CXBORDER); + /* 320 --> 300 */ + nBits = min(300, rectWin.right - rectWin.left-nx-nx) - 24; + /* Window width (pixels) */ + /* 320 --> 300 */ + range = max(0, (font.WidthBytes << 3) - min(300, nBits)); + origin = (swH * range) / 100; /* Global variable */ + BitBlt(hDC, 12, 2, nBits, font.PixHeight, + hMemDC, origin, 0, NOTSRCCOPY); + /* Now highlight the current value of iChar */ + InvertFont(hDC, iChar, jChar); +} + + +/***************************************************************************** + * MouseInFont(ptMouse) + * + * purpose: Select new char in tiny Show window by inverting current char + * and un-inverting last one + * + * params: POINT ptMouse : mouse coordinates + * + * returns: none + * + * side effects: pixels inverted(uninverted) in bitmap. + * + ****************************************************************************/ +VOID +MouseInFont( + POINT ptMouse /* .. to get new iChar */ + ) +{ + HDC hDC; + + BoxToChar(iChar); /* Replace edited character in Box if changed */ + hDC = GetDC(hFont); + /* UnInvert present inverted region */ + InvertFont(hDC, iChar, jChar); + /* Find where mouse is */ + lastChar = downChar = iChar = jChar = FindMouse(ptMouse); + /* Invert Character touched */ + InvertFont(hDC, iChar, jChar); + ReleaseDC(hFont, hDC); +} + + +/***************************************************************************** + * + * purpose: God knows. Ask Him. + * + * params: + * + * returns: + * + * side effects: + * + ****************************************************************************/ +VOID +MouseMoveFont( + POINT ptMouse + ) + /* Mouse raised in font */ + /* .. to get new jChar */ +{ + UNREFERENCED_PARAMETER(ptMouse); + return; /********* NOT YET IN USE !! ********/ + +#if 0 + BYTE newChar; + HDC hDC; + + newChar = FindMouse(ptMouse); /* Find where mouse is */ + if (newChar == lastChar) /* Did we move ? */ + return; /* No: return */ + lastChar = newChar; + hDC = GetDC(hFont); + if (newChar > jChar) + { + InvertFont(hDC, jChar + 1, newChar); /* extend jChar */ + jChar = newChar; + } + else if (newChar < iChar) /* iChar & jChar switch */ + { + InvertFont(hDC, newChar, iChar - 1); + iChar = newChar; + } + else + { + if (newChar >= downChar) /* width reduced on right */ + { + InvertFont(hDC, newChar + 1, jChar); + jChar = newChar; + } + if (newChar <= downChar) /* width reduced on left */ + { + InvertFont(hDC, iChar, newChar - 1); + iChar = newChar; + } + } + ReleaseDC(hFont, hDC); +#endif +} + + +/***************************************************************************** + * InvertFont(hDC, iChar, jChar) + * + * purpose: inverts color on selected chars (iChar thro' jChar) in the Show + * Window + * + * params: HDC hDC : handle to display context + * char iChar : start char + * char jChar : end char + * + * returns: none + * + * side effects: changes pixel values in bitmap + * + ****************************************************************************/ +VOID +InvertFont( + HDC hDC, + BYTE iChar, + BYTE jChar + ) +{ + PatBlt(hDC, /* Use Blt to Invert it */ + 12 + offsets[iChar] - origin, /* X: Position */ + 2, /* Y: Allow for top band */ + offsets[jChar + 1] - offsets[iChar], /* dx: Compute width */ + font.PixHeight, /* dy: Look up the Height */ + DSTINVERT); /* Z: Tell it to invert it */ +} + + +/***************************************************************************** + * MouseOutFont(ptMouse) + * + * purpose: brings selected char to edit box and sets up tiny window for + * repainting + * + * params: POINT ptMouse : mouse location + * + * returns: none + * + * side effects: changes matBox(2-d array containing ready pixel info. on + * char being edited) + * + ****************************************************************************/ +VOID +MouseOutFont( + POINT ptMouse + ) + /* Mouse raised in font */ + /* .. to get new jChar */ +{ + MouseMoveFont(ptMouse); /* Check on iChar and jChar */ + CharToBox(iChar); + InvalidateRect(hFont, (LPRECT)NULL, TRUE); /* Cause repaint */ +} + + +/***************************************************************************** + * BYTE FindMouse(ptMouse) + * + * purpose: Locate number of character(in tiny window at bottom) under mouse + * + * params: POINT ptMouse : mouse location + * + * returns: number of character + * + * side effects: alters scroll position variable + * + ****************************************************************************/ + +BYTE +FindMouse( + POINT ptMouse + ) +{ + int iChar; + LONG x; + + + x = ptMouse.x + origin - 12; /* Horizontal position of mouse */ + if (x < 0) + iChar = font.FirstChar; + else + { + iChar = x / font.AvgWidth + font.FirstChar; + /* Right if Fixed Pitch -- Best Guess if variable width */ + if (!font.PixWidth) /* Scan for new iChar */ + { + if (iChar > (int)font.LastChar) + iChar = (int)font.LastChar; /* Don't overshoot */ + + while (iChar < (int)font.LastChar && offsets[iChar] < (DWORD)x) + iChar++; + while (iChar > (int)font.FirstChar && offsets[iChar] > (DWORD)x) + iChar--; + } + } + + /* Bug fix: prevent nil character from showing if mouse is pressed way + over on right side of font scroll with narrow fixed fonts. */ + if (iChar > (int)font.LastChar) + iChar = (int)font.LastChar; /* Don't overshoot */ + + if (iChar < (int)font.FirstChar) + iChar = (int)font.FirstChar; /* Don't undershoot */ + + if (ptMouse.x <= 12L) + { + swH -= 1; + ScrollFont(); + } + if (ptMouse.x > 308L) + { + swH += 1; + ScrollFont(); + } + return (BYTE)iChar; +} + + +/***************************************************************************** + * ScrollFont() + * + * purpose: scrolls tiny window at bottom + * + * params: none + * + * returns: none + * + * side effects: alters scroll position variable + * + ****************************************************************************/ +VOID +ScrollFont( + VOID + ) +{ + HDC hDC; + + swH = max(0, swH); + swH = min(100, swH); /* maintain 0 - 100 range */ + SetScrollPos(hFont, SB_HORZ, swH, TRUE); /* Move thumb */ + hDC = GetDC(hFont); + FontShowPaint(hDC); + ReleaseDC(hFont, hDC); +} + + +/***************************************************************************** + * BoxToChar(iChar) + * + * purpose: sets pixels in bitmap according to matBox(2-d array containing + * ready pixel info. on char being edited) + * + * params: BYTE iChar : index of char in bitmap offset array(offsets) + * + * returns: none + * + * side effects: changes font bitmap + * + ****************************************************************************/ +VOID +BoxToChar( + BYTE iChar + ) +{ + DWORD x, y, offset; + + if (!fEdited) + return; + + if (wBox != wBoxOld) /* I.e if width has changed */ + CharWidth(iChar, wBox); /* .. go fix it */ + + offset = offsets[iChar]; + for (x = 0; x < wBox; x++) + { + for (y = 0; y < kBox; y++) + SetPixel(hMemDC, offset + x, y, + matBox[x] [y] == TRUE ? WHITE : BLACK); + } + fEdited = FALSE; +} + + +/***************************************************************************** + * CharToBox(iChar) + * + * purpose: assigns matBox(2-d array containing ready pixel info. on char being + * edited) according to pixels in portion of bitmap corresp. to char. + * + * params: BYTE iChar : index of char in bitmap offset array(offsets) + * + * returns: none + * + * side effects: changes matBox + * + ****************************************************************************/ +VOID +CharToBox( + BYTE iChar + ) +{ + DWORD x, y, offset; + HMENU hMenu; + + ClearBox(); + offset = offsets[iChar]; + wBox = (DWORD)(wBoxOld = (WORD) (offsets[iChar + 1] - offset)); /* Edit Box width */ + kBox = font.PixHeight; /* Edit Box Height */ + for (x = 0; x < wBox; x++) + for (y = 0; y < kBox; y++) + matBox[x][y] = (BYTE) (GetPixel(hMemDC, offset + x, y) ? 1 : 0); + InvalidateRect(hBox, (LPRECT)NULL, TRUE); + fEdited = FALSE; /* Not Changed Yet */ + hMenu = GetMenu(hBox); + EnableMenuItem(hMenu, BOX_UNDO, MF_GRAYED); + EnableMenuItem(hMenu, BOX_REFRESH, MF_GRAYED); +} + + +/*****************************************************************************/ +/* WinMain and Friends */ +/*****************************************************************************/ + + +/* Procedure called every time a new instance of the application +** is created */ + +MMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow) +/* { */ + MSG msg; + WORD message; + INT nx; + HANDLE hAccel; + + hInst = hInstance; + hgPrev=hPrevInstance; + /*if (!hPrevInstance) + { */ + + + if (!FontEditInit( hInstance )) + return FALSE; + + + /*} + /*else Hacked this out--why not just make our own again. Alleviates + problems with some strange RIPs + get data from previous instance */ + /*{ + /* Copy global instance variables from previous instance */ + /*GetInstanceData( hPrevInstance, (PSTR)&hbrWhite, sizeof( hbrWhite)); + GetInstanceData( hPrevInstance, (PSTR)&hbrBlack, sizeof( hbrBlack)); + GetInstanceData( hPrevInstance, (PSTR)&hbrGray, sizeof( hbrGray)); + GetInstanceData( hPrevInstance, (PSTR)&hbrDkGray, sizeof( hbrDkGray)); + GetInstanceData( hPrevInstance, (PSTR)&hbrBackGround, + sizeof( hbrBackGround)); + }*/ + + LoadString(hInstance, IDS_APPNAME, szAppName, MAX_STR_LEN); + LoadString(hInstance, IDS_IFN, szIFN, MAX_STR_LEN); /* illegal filename */ + LoadString(hInstance, IDS_FNF, szFNF, MAX_STR_LEN); /* file not found */ + LoadString(hInstance, IDS_REF, szREF, MAX_STR_LEN); + /* replace existing file */ + LoadString(hInstance, IDS_SCC, szSCC, MAX_STR_LEN); + /* save current changes */ + LoadString(hInstance, IDS_EOF, szEOF, MAX_STR_LEN); /* error opening file */ + LoadString(hInstance, IDS_ECF, szECF, MAX_STR_LEN); + // File is read only. + LoadString(hInstance, IDS_FRO, szFRO, MAX_STR_LEN); + /* error creating file */ + LoadString(hInstance, IDS_EXT, szExt, MAX_STR_LEN); /* default file ext. */ + + // File extension description for common dialog. + LoadString(hInstance, IDS_EXTDESC, szExtDesc, MAX_STR_LEN); + // Message for new font warning box. + LoadString(hInstance, IDS_NEW_FONT, szNEWFONT, MAX_STR_LEN); + memset(szFilter, 0, MAX_STR_LEN); + LoadString(hInstance, IDS_EXTDESC, szFilter, MAX_STR_LEN); + LoadString(hInstance, IDS_STARDOTFNT, szFilter+strlen(szFilter)+1, + MAX_STR_LEN-(strlen(szFilter)+1)); + + + ClearBox(); + + /* Create a window instance of class "FontEdit" */ + + hBox = CreateWindow((LPSTR) vszFontEdit, + (LPSTR)szAppName, + WS_TILEDWINDOW, + 56,34, + GetSystemMetrics(SM_CXFULLSCREEN)/2, + GetSystemMetrics(SM_CYFULLSCREEN)/2, + (HWND)NULL, /* no parent */ + (HMENU)NULL, /* use class menu */ + (HANDLE)hInstance, /* handle to window instance */ + (LPSTR)NULL /* no params to pass on */ + ); + + ShowWindow(hBox, cmdShow); + UpdateWindow(hBox); + InitSizes(); /* 11/21/86 - linsh - get system char width & height */ + + + GetWindowRect(hBox, (LPRECT)&rectWin); + nx=GetSystemMetrics(SM_CXBORDER); + hFont = CreateWindow((LPSTR) vszFontShow, + (LPSTR) "", + WS_BORDER|WS_HSCROLL|WS_CAPTION, + rectWin.left, + rectWin.bottom-56, + min(300, rectWin.right - rectWin.left-nx-nx), + 50 - GetSystemMetrics(SM_CYBORDER), + (HWND)hBox, + (HMENU)NULL, + (HANDLE)hInstance, + (LPSTR)NULL + ); + + + /* Get address of Dialog Box procedure */ + lpHeaderProc = MakeProcInstance((FARPROC)HeaderProc, hInstance); + lpReSizeProc = MakeProcInstance((FARPROC)ReSizeProc, hInstance); + lpWidthProc = MakeProcInstance((FARPROC)WidthProc, hInstance); + + /* Start it loading if it's not iconic */ + if (!IsIconic(hBox)) + { + if (lpszCmdLine[0]) /* If we have a font name use it */ + { + BOOL fDot; + INT i; + + /* Copy the specified file and make it upper case */ + lstrcpy((LPSTR)szFontFile, CharUpper((LPSTR)lpszCmdLine)); + + fDot = FALSE; + nx=lstrlen((LPSTR)szFontFile); + + for (i = 0; i < nx; i++) + { + if (szFontFile[i] == '.') /* Add .FNT if none */ + fDot = TRUE; + + if (szFontFile[i] == ' ') + szFontFile[i]=0; + } + + if (!fDot) + lstrcat((LPSTR)szFontFile, (LPSTR)vszDotFNT); + + lstrcpy((LPSTR)szNewFile, (LPSTR)szFontFile); + + /* Do this thing that someone forgot. THe dialog open does it + and affects the Save As initialization. */ + MOpenFile((LPSTR)szNewFile, &ofstrFile, OF_READ); + + message = FONT_START; + } + else /* Start by doing a regular file load */ + message = FONT_LOAD; + + SetFocus(hBox); + PostMessage(hBox, WM_COMMAND, message, (LONG)0); + } + + if (!fLoaded) + ShowWindow(hFont, SW_HIDE); + + hAccel=LoadAccelerators(hInstance, "FE"); + + /* Quit message will terminate application */ + while (GetMessage((LPMSG)&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator (hBox, hAccel, &msg)) + { + TranslateMessage((LPMSG)&msg); + DispatchMessage((LPMSG)&msg); + } + } + + return msg.wParam; + (void)_argc; (void)_argv; + } + +/************************************************************************ +* FileInPath +* +* This function takes a path and returns a pointer to the file name +* portion of it. For instance, it will return a pointer to +* "abc.res" if it is given the following path: "c:\windows\abc.res". +* +* Arguments: +* PSTR pstrPath - Path to look through. +* +* History: +* 29-Jul-1994 JonPa copied from imagedit +************************************************************************/ + +PSTR FileInPath( + PSTR pstrPath) +{ + PSTR pstr; + + pstr = pstrPath + strlen(pstrPath); + while (pstr > pstrPath) { + pstr = AnsiPrev(pstrPath, pstr); + if (*pstr == '\\' || *pstr == ':' || *pstr == '/') { + pstr = AnsiNext(pstr); + break; + } + } + + return pstr; +} + +/***************************************************************************** + * int FontEditInit( hInstance ) + * + * purpose: Initialises a whole lot of stuff + * + * params: HANDLE hInstance : handle to instance of application + * + * returns: TRUE : if everything goes off well + * FALSE : error in initialisation + * + * side effects: a whole lot + * + ****************************************************************************/ + +/* Procedure called when the application is loaded */ +BOOL +FontEditInit( + HANDLE hInstance + ) +{ + INT cch; /* all variables used to load srings from .RC file */ + INT cchRemaining; + CHAR *pch; + HANDLE hStrings; + INT i; + CHAR ColorStr[CCHCOLORSTRING]; /* background color inf. fronm win.ini */ + BYTE bR, bG, bB; /* the three primary color values ret. from win.ini */ + // CHAR cDummy; /* dummy char to hold the " " char */ + PWNDCLASS pFontEditClass; /* Edit Box window class */ + PWNDCLASS pFontShowClass; /* Show Font window class */ + + // + // Initialize the conversion routines to read in the old font structure + // off of disk. + // + + if (fConvStructInit () == FALSE) { + + return FALSE; + } + + /* load strings from resource file */ + if (!(pch = (CHAR *)(hStrings = + LocalAlloc (LPTR, cchRemaining = CCHSTRINGSMAX)))) + return FALSE; /* unable to alloc. Try increasing initial + heapsize in .DEf file */ + for (i=0; i< CSTRINGS; i++){ + cch = 1+LoadString (hInstance, (WORD) i, (LPTSTR)pch, cchRemaining); + if (cch < 2){ + return FALSE; + } + vrgsz[i] = pch; + pch += cch; + if ((cchRemaining -= cch ) <= 0) + return FALSE; + } + + /* Allocate class structure in local heap */ + pFontEditClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) ); + if (pFontEditClass == NULL) + return FALSE; + + /* set up some default brushes */ + hbrWhite = GetStockObject( WHITE_BRUSH ); + hbrBlack = GetStockObject( BLACK_BRUSH ); + hbrGray = GetStockObject( GRAY_BRUSH ); + hbrDkGray = GetStockObject( DKGRAY_BRUSH ); + + /* get App. Workspace color from win.ini - LR */ + if (GetProfileString(vszcolors, vszAppWorkspace, "",ColorStr, + CCHCOLORSTRING)){ + bR = (BYTE)atoi((const char *)strtok (ColorStr, " ")); + bG = (BYTE)atoi((const char *)strtok (NULL, " ")); + bB = (BYTE)atoi((const char *)strtok (NULL, "\n")); + hbrBackGround = CreateSolidBrush(RGB(bR, bG, bB)); + } + else /* set to lt. blue background */ + hbrBackGround = CreateSolidBrush((LONG)0x00FF8000); + + /* get necessary resources */ + pFontEditClass->hCursor = LoadCursor( NULL, IDC_ARROW); + pFontEditClass->hIcon = LoadIcon( hInstance,(LPSTR)vszFontEdit); + pFontEditClass->lpszMenuName = (LPSTR)vszFontEdit; + pFontEditClass->lpszClassName = (LPSTR)vszFontEdit; + pFontEditClass->hbrBackground = hbrBackGround; + pFontEditClass->hInstance = hInstance; + + pFontEditClass->style = CS_VREDRAW | CS_HREDRAW; + + /* Register our Window Proc */ + pFontEditClass->lpfnWndProc = (WNDPROC)FontEditWndProc; + + /* register this new class with WINDOWS */ + if (!hgPrev) + if (!RegisterClass( (LPWNDCLASS)pFontEditClass ) ) + return FALSE; /* Initialization failed */ + + /* Now repeat the performance for the Show window */ + + pFontShowClass = pFontEditClass; + /* get necessary resources */ + pFontShowClass->hCursor = LoadCursor(NULL,IDC_ARROW); + pFontShowClass->hIcon = (HICON)NULL; + pFontShowClass->lpszMenuName = NULL; + pFontShowClass->lpszClassName = (LPSTR)vszFontShow; + pFontShowClass->hbrBackground = hbrGray; + pFontShowClass->hInstance = hInstance; + pFontShowClass->style = CS_VREDRAW | CS_HREDRAW; + + /* Register our Window Proc */ + pFontShowClass->lpfnWndProc = (WNDPROC)FontShowWndProc; + + /* register this new class with WINDOWS */ + if (!hgPrev) + if (!RegisterClass( (LPWNDCLASS)pFontShowClass ) ) + return FALSE; /* Initialization failed */ + + LocalFree( (HANDLE)pFontShowClass ); + + /* + * Build the help file name path. Assume the help file is in the + * same directory as the executable. + */ + GetModuleFileName(hInstance, gszHelpFile, MAX_PATH); + *FileInPath(gszHelpFile) = '\0'; + lstrcat(gszHelpFile, vrgsz[IDS_HELPFILE]); + + return TRUE; /* Initialization succeeded */ +} + +/***************************************************************************** + * InitSizes() + * + * purpose: gets system char width and height + * + * params: none + * + * returns: none + * + * side effects: sets width and height globals + * + ****************************************************************************/ +VOID +InitSizes( + VOID + ) +{ + HDC hDC; + TEXTMETRIC tm; + + hDC = GetDC(hFont); + GetTextMetrics(hDC, (LPTEXTMETRIC) &tm); + cSysHeight = tm.tmHeight + tm.tmExternalLeading;; + cSysWidth = tm.tmAveCharWidth; + ReleaseDC(hFont, hDC); +} + + +/***************************************************************************** + * long APIENTRY FontShowWndProc(hFont, message, wParam, lParam) + * + * purpose: Window function for tiny window at the bottom (showing font chars) + * Independently processes paint, scroll, keyboard and mouse + * messages for the window + * + * params: as for window functions + * + * side effects: lots + * + ****************************************************************************/ + +/* Procedures which make up the window class. */ +LONG APIENTRY +FontShowWndProc( + HWND hFont, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + PAINTSTRUCT ps; + // RECT rectWin; + POINT pt; + + MPOINT2POINT(MAKEMPOINT(lParam), pt); + + switch (message) + { + + case WM_SIZE : + switch (wParam){ + /* if main window is iconised, hide the child window */ + case SIZEICONIC : + ShowWindow(hFont, SW_HIDE); + break; + default: + return(DefWindowProc(hFont, message, wParam, lParam)); + break; + } + break; + + + case WM_PAINT: + /* Time for the window to draw itself. */ + BeginPaint(hFont, (LPPAINTSTRUCT)&ps); + FontShowPaint(ps.hdc); + EndPaint(hFont, (LPPAINTSTRUCT)&ps); + break; + + /* For each of following mouse window messages, wParam contains + ** bits indicating whether or not various virtual keys are down, + ** and lParam is a POINT containing the mouse coordinates. The + ** keydown bits of wParam are: MK_LBUTTON (set if Left Button is + ** down); MK_RBUTTON (set if Right Button is down); MK_SHIFT (set + ** if Shift Key is down); MK_ALTERNATE (set if Alt Key is down); + ** and MK_CONTROL (set if Control Key is down). */ + + case WM_LBUTTONDOWN: + MouseInFont(pt); /* .. set iChar */ + break; + case WM_LBUTTONUP: + MouseOutFont(pt); /* .. set jChar */ + break; + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: /* If mouse is down */ + if (wParam & MK_LBUTTON) + MouseMoveFont(pt); /* .. set jChar */ + break; + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + break; + + case WM_HSCROLL: + /* wParam contains the scroll code. + ** For the thumb movement codes, the low + ** word of lParam contain the new scroll position. + ** Possible values for wParam are: SB_LINEUP, SB_LINEDOWN, + ** SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, SB_THUMBTRACK */ + /* Horizontal scroll bar input. Parameters same as for + ** WM_HSCROLL. UP and DOWN should be interpreted as LEFT + ** and RIGHT, respectively. */ + FontShowHorzScroll(hFont, GET_WM_HSCROLL_CODE(wParam,lParam), + GET_WM_HSCROLL_POS(wParam,lParam)); + break; + case WM_CLOSE: + break; /* don't allow this window to be closed before + bigger one */ + + default: + + /* Everything else comes here. This call MUST exist + ** in your window proc. */ + + return(DefWindowProc(hFont, message, wParam, lParam)); + break; + + } + + /* A window proc should always return something */ + return(0L); +} + + +VOID +FontRename( + CHAR * szError + ) +{ + CHAR *szTitle[MAX_STR_LEN+MAX_FNAME_LEN]; + + if (szError[0]) + ErrorBox(hBox, szError); + else + { + lstrcpy((LPSTR)szFontFileFull, (LPSTR)szNewFile); + lstrcpy((LPSTR)szTitle, (LPSTR)szAppName); + lstrcat((LPSTR)szTitle, (LPSTR)vszBlankDashBlank); + lstrcat((LPSTR)szTitle, (LPSTR)szFontFile); + SetWindowText(hBox, (LPSTR)szTitle); + } +} + + +/***************************************************************************** + * ResizeShow() + * + * purpose: resize tiny window at bottom (showing font chars) in proportion + * to large window + * + * params: none + * + * returns: none + * + * side effects: + * + ****************************************************************************/ + +VOID +ResizeShow( + VOID + ) +{ + INT height; + INT nx; + + /* size message for hbox goes thru before hfont created. 06-Jul-1987. */ + if (!hFont) + return; + + GetWindowRect(hBox, (LPRECT)&rectWin); + kStuff = GetkStuff(); /* For check on second pass */ + +#if 0 + height = font.PixHeight + kStuff + 20; /* 4 Height we want box */ +#else + height = font.PixHeight + GetSystemMetrics(SM_CYHSCROLL) + + GetSystemMetrics(SM_CYCAPTION) + + 4*GetSystemMetrics(SM_CYBORDER)/*20*/; /* 4*/ +#endif + + nx=GetSystemMetrics(SM_CXBORDER); + MoveWindow(hFont, + rectWin.left +nx+4, + rectWin.bottom - (height + GetSystemMetrics(SM_CYBORDER)+2), + min(300, rectWin.right - rectWin.left-nx-nx), + height, + TRUE); + if (!IsWindowVisible(hFont) && fLoaded) + ShowWindow(hFont, SW_SHOW); +} + + +DWORD +GetkStuff( + VOID + ) /* Get size of menu, scrollbar etc. */ +{ + RECT rect, rectWin; + + /* size message for hbox goes thru before hfont created. 06-Jul-1987. */ + if (!hFont) + return 0; + + GetClientRect(hFont, (LPRECT)&rect); /* How much do WE get? */ + GetWindowRect(hFont, (LPRECT)&rectWin); + return (DWORD) (rectWin.bottom - rectWin.top) - (rect.bottom - rect.top); +} + diff --git a/private/sdktools/fontedit/fontedit.def b/private/sdktools/fontedit/fontedit.def new file mode 100644 index 000000000..f6eb01689 --- /dev/null +++ b/private/sdktools/fontedit/fontedit.def @@ -0,0 +1,22 @@ +NAME FontEdit + +DESCRIPTION 'Microsoft Windows Font Editor' + +STUB 'WINSTUB.EXE' + +EXETYPE WINDOWS + +CODE MOVEABLE +DATA MOVEABLE MULTIPLE + +HEAPSIZE 2048 ; Must be non-zero to use Local memory manager 2048 +STACKSIZE 4096 ; Must be non-zero for SS == DS + +EXPORTS ; Must export all procedures called by Windows + FontEditWndProc @1 ; (ordinal numbers use less resident memory) + FontShowWndProc @2 + HeaderProc @3 + ReSizeProc @4 + WidthProc @5 + DlgFnCheckFormat @6 + AboutDlg @7 diff --git a/private/sdktools/fontedit/fontedit.h b/private/sdktools/fontedit/fontedit.h new file mode 100644 index 000000000..f0065875a --- /dev/null +++ b/private/sdktools/fontedit/fontedit.h @@ -0,0 +1,540 @@ +#include <stdlib.h> + +#define WIDER_LEFT 1 +#define WIDER_RIGHT 2 +#define WIDER_BOTH 3 +#define NARROWER_LEFT 4 +#define NARROWER_RIGHT 5 +#define NARROWER_BOTH 6 +#define WIDTH 7 +#define BOX_WIDTH 8 + +#define BOX_REFRESH 10 /* Restore char to original form */ +#define BOX_CLEAR 11 +#define BOX_FILL 12 +#define BOX_INV 13 +#define BOX_HATCH 14 +#define BOX_UNDO 15 /* Undo last change */ +#define BOX_LEFTRIGHT 16 /* Flip left to right */ +#define BOX_TOPBOTTOM 17 /* Flip top over bottom */ +#define BOX_COPY 18 +#define BOX_PASTE 19 + +#define ROW_ADD 21 +#define ROW_DEL 22 + +#define COL_ADD 31 +#define COL_DEL 32 + + +#define ID_EDIT 34 +#define ID_PATH 35 +#define ID_LISTBOX 36 +#define ID_FACE_NAME 37 +#define ID_FONT_NAME 38 +#define ID_COPYRIGHT 39 + +#define FONT_START 40 /* Generated if win fontedit arg. */ + +#define FONT_LOAD 41 /* Codes for Font Window */ +#define FONT_SAVE 42 +#define FONT_HEADER 43 +#define FONT_COPY 44 +#define FONT_PASTE 45 /* Paste in without rescaling */ +#define FONT_ABOUT 46 /* Display the about box */ +#define FONT_RESIZE 47 /* Go to Resize Dialog Box */ +#define FONT_NEW 95 /* Menu id: create new font */ + +#define FONT_HELP_CONTENTS 50 /* HELP menu constants */ +#define FONT_HELP_SEARCH 51 /* HELP menu constants */ + + +#define ID_FIRST_CHAR 48 /* First character in the font */ +#define ID_LAST_CHAR 49 /* Last character in the font */ + +#define ID_POINTS 50 /* Nominal Point Size */ +#define ID_VERT_RES 51 /* Nominal Vertical Resolution */ +#define ID_HORIZ_RES 52 /* Nominal Horizontal Resolution */ +#define ID_ASCENT 53 /* Height of Ascent */ +#define ID_EXT_LEADING 54 /* Height of External Leading */ +#define ID_INT_LEADING 55 /* Height of Internal Leading */ + +#define FONT_EXIT 56 /* exit the font editor */ + +#define ID_ITALIC 60 /* Flag for Italic Fonts */ +#define ID_UNDERLINE 61 /* Flag for Underlined Fonts */ +#define ID_STRIKEOUT 62 /* Flag for Struckout Fonts */ +#define ID_ANSI 63 /* 0 = ANSI, 255 = other */ +#define ID_OEM 64 +#define ID_CHAR_SET 65 +#define ID_DEFAULT_CHAR 66 /* Default for undefined Chars. */ +#define ID_BREAK_CHAR 67 +#define ID_SYMBOL 68 + +#define ID_UNKNOWN 70 +#define ID_ROMAN 71 +#define ID_SWISS 72 /* Pitch Families */ +#define ID_MODERN 73 +#define ID_SCRIPT 74 +#define ID_DECORATIVE 75 + +#define ID_PIX_HEIGHT 80 /* Height of Characters */ +#define ID_WIDTH 81 /* Fixed or Maximum Width */ +#define ID_WIDTH_TEXT 82 /* Caption for above */ +#define ID_AVERAGE 83 /* Average Character Width */ +#define ID_FIXED 84 /* Fixed Width Font */ +#define ID_VARIABLE 85 /* Variable width font */ + +#define ID_THIN 86 +#define ID_EXTRALIGHT 87 +#define ID_LIGHT 88 +#define ID_NORMAL 89 +#define ID_MEDIUM 90 +#define ID_SEMIBOLD 91 +#define ID_BOLD 92 +#define ID_EXTRABOLD 93 +#define ID_HEAVY 94 +#define ID_BOXOPEN 96 /* dialog box frame id for File Open */ +#define FONT_SAVEAS 97 + +#define ID_FORMAT2 102 /* Windows 2.0 Font Format */ +#define ID_FORMAT3 103 /* Windows 3.0 Font Format */ + +/* string IDS for strings in resource file - LR */ +#define IDS_NOMPTSIZENOTOK 0 +#define IDS_NOMVERTRESNOTOK 1 +#define IDS_NOMHORRESNOTOK 2 +#define IDS_ASCENTTOOBIG 3 +#define IDS_ASCENTNOTOK 4 +#define IDS_EXTLEADNOTOK 5 +#define IDS_INTLEADTOOBIG 6 +#define IDS_INTLEADNOTOK 7 +#define IDS_CHARSETOUTOFBOUNDS 8 +#define IDS_DEFCHAROUTSIDEFONT 9 +#define IDS_DEFCHARNOTOK 10 +#define IDS_BREAKCHAROUTSIDEFONT 11 +#define IDS_BREAKCHARNOTOK 12 +#define IDS_UNKNOWNFACE 13 +#define IDS_NOVARTOFIXCHANGE 14 +#define IDS_TOOBIGFOR20 15 +#define IDS_HEIGHTOUTOFBOUNDS 16 +#define IDS_WIDTHOUTOFBOUNDS 17 +#define IDS_CHAR1MORETHANDCHAR 18 +#define IDS_CHAR1NOTOK 19 +#define IDS_LASTCHARTOOSMALL 20 +#define IDS_LASTCHARNOTOK 21 +#define IDS_CANNOTOPENCLIP 22 +#define IDS_COPYINGTOCLIP 23 +#define IDS_NOTENOUGHMEM 24 +#define IDS_ALLOCATINGSPACE 25 +#define IDS_FONTEDIT 26 +#define IDS_FONTSHOW 27 +#define IDS_DOTFNT 28 +#define IDS_BLANKDASHBLANK 29 +#define IDS_ERROROPENINGFILE 30 +#define IDS_ERRORREADINGHDR 31 +#define IDS_UNKNOWNFORMAT 32 +#define IDS_ERRORREADINGBODY 33 +#define IDS_FILETOOLARGE 34 +#define IDS_ERRORWRITINGHDR 35 +#define IDS_ERRORWRITINGOFFSETS 36 +#define IDS_ERRORWRITINGBODY 37 +#define IDS_STARDOTFNT 38 +#define IDS_UNKNOWN 39 +#define IDS_MAXWIDTH 40 +#define IDS_CHARPIXELWIDTH 41 +#define IDS_ABOUT 42 +#define IDS_DHEADER 43 +#define IDS_DRESIZE 44 +#define IDS_DWIDTH 45 +#define IDS_EDLIMITS0TO64 46 +#define IDS_MAXWIDTHINCREASE 47 +#define IDS_CANNOTCHANGEWIDTH 48 +#define IDS_WARNING 49 +#define IDS_INCORRECTPIXWIDTH 50 +#define IDS_MAXWIDTHOUTOFBOUNDS 51 +#define IDS_AVGWIDTHOUTOFBOUNDS 52 +#define IDS_WIDTHBYTESNOTOK 53 +#define IDS_BITSOFFSETNOTOK 54 +#define IDS_TABLEWIDTHSBAD 55 +#define IDS_TABLEOFFSETSBAD 56 +#define IDS_COLOR 57 +#define IDS_APPWORKSPACE 58 +#define IDS_FILEREADONLY 59 + +#define IDS_APPNAME 60 +#define IDS_IFN 61 +#define IDS_FNF 62 +#define IDS_REF 63 +#define IDS_SCC 64 +#define IDS_EOF 65 +#define IDS_ECF 66 +#define IDS_FRO 67 +#define IDS_EXT 68 +#define IDS_EXTDESC 69 +#define IDS_NEW_FONT 70 +#define IDS_ERRORCLIP 71 +#define IDS_CHAR 72 +#define IDS_WIDTH 73 +#define IDS_HEIGHT 74 + +#define IDS_HELPFILE 75 + + +#define CSTRINGS 76 /* total number of strings in + resource file */ +#define CCHSTRINGSMAX 4096 /* total length of all strings + loaded must be <= this */ +#define CCHCOLORSTRING 15 /* size of App Workspace color inf. + string loaded from win.ini */ +#ifdef JAPAN +#define ID_SHIFTJIS 76 +#endif + +/*****************************************************************************/ +/* Typedef's etc. */ +/*****************************************************************************/ + +// typedef unsigned char CHAR; /* ... since we use these to index */ + +/* font file header (Adaptation Guide section 6.4) */ +typedef struct { + WORD Version; /* Always 17985 for the Nonce */ + DWORD Size; /* Size of whole file */ + CHAR Copyright[60]; + WORD Type; /* Raster Font if Type & 1 == 0 */ + WORD Points; /* Nominal Point size */ + WORD VertRes; /* Nominal Vertical resolution */ + WORD HorizRes; /* Nominal Horizontal resolution */ + WORD Ascent; /* Height of Ascent */ + WORD IntLeading; /* Internal (Microsoft) Leading */ + WORD ExtLeading; /* External (Microsoft) Leading */ + BYTE Italic; /* Italic font if set */ + BYTE Underline; /* Etc. */ + BYTE StrikeOut; /* Etc. */ + WORD Weight; /* Weight: 200 = regular */ + BYTE CharSet; /* ANSI=0. other=255 */ + WORD PixWidth; /* Fixed width. 0 ==> Variable */ + WORD PixHeight; /* Fixed Height */ + BYTE Family; /* Pitch and Family */ + WORD AvgWidth; /* Width of character 'X' */ + WORD MaxWidth; /* Maximum width */ + BYTE FirstChar; /* First character defined in font */ + BYTE LastChar; /* Last character defined in font */ + BYTE DefaultChar; /* Sub. for out of range chars. */ + BYTE BreakChar; /* Word Break Character */ + WORD WidthBytes; /* No.Bytes/row of Bitmap */ + DWORD Device; /* Pointer to Device Name string */ + DWORD Face; /* Pointer to Face Name String */ + DWORD BitsPointer; /* Pointer to Bit Map */ + DWORD BitsOffset; /* Offset to Bit Map */ +} FontHeaderType; /* Above pointers all rel. to start of file */ + + +typedef struct { + WORD fsVersion; + DWORD fsSize; + CHAR fsCopyright[60]; + WORD fsType; /* Type field for the font */ + WORD fsPoints; /* Point size of font */ + WORD fsVertRes; /* Vertical digitization */ + WORD fsHorizRes; /* Horizontal digitization */ + WORD fsAscent; /* Baseline offset from char cell top */ + WORD fsInternalLeading; /* Internal leading included in font */ + WORD fsExternalLeading; /* Prefered extra space between lines */ + BYTE fsItalic; /* Flag specifying if italic */ + BYTE fsUnderline; /* Flag specifying if underlined */ + BYTE fsStrikeOut; /* Flag specifying if struck out */ + WORD fsWeight; /* Weight of font */ + BYTE fsCharSet; /* Character set of font */ + WORD fsPixWidth; /* Width field for the font */ + WORD fsPixHeight; /* Height field for the font */ + BYTE fsPitchAndFamily; /* Flag specifying pitch and family */ + WORD fsAvgWidth; /* Average character width */ + WORD fsMaxWidth; /* Maximum character width */ + BYTE fsFirstChar; /* First character in the font */ + BYTE fsLastChar; /* Last character in the font */ + BYTE fsDefaultChar; /* Default character for out of range */ + BYTE fsBreakChar; /* Character to define wordbreaks */ + WORD fsWidthBytes; /* Number of bytes in each row */ + DWORD fsDevice; /* Offset to device name */ + DWORD fsFace; /* Offset to face name */ + DWORD fsBitsPointer; /* Bits pointer */ + DWORD fsBitsOffset; /* Offset to the begining of the bitmap */ + BYTE fsDBfiller; /* Word alignment for the offset table */ + + DWORD fsFlags; /* Bit flags */ + WORD fsAspace; /* Global A space, if any */ + WORD fsBspace; /* Global B space, if any */ + WORD fsCspace; /* Global C space, if any */ + DWORD fsColorPointer; /* offset to color table, if any */ + DWORD fsReserved[4]; /* */ + BYTE fsCharOffset; /* Area for storing the char. offsets */ + +} FontHeader30; + +#define CCHEXTRA 31 /* no. of extra bytes in the 3.0 header */ + +// +// These are the old glyph info structures. Since they are not DWORD aligned +// they must be converted to new structure types. +// + +typedef struct{ + SHORT GIwidth; + SHORT GIoffset; +} GLYPHINFO_20; + +typedef struct{ + SHORT GIwidth; + LONG GIoffset; +} GLYPHINFO_30; + +#define ClipBoard TRUE + +LONG APIENTRY FontEditWndProc(HWND, WORD, WPARAM, LONG); +LONG APIENTRY FontShowWndProc(HWND, WORD, WPARAM, LONG); +BOOL APIENTRY +HeaderProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ); +BOOL APIENTRY +ReSizeProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ); +BOOL APIENTRY +WidthProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ); + +CHAR * FontLoad(CHAR *, OFSTRUCT *); +CHAR * FontSave(CHAR *, OFSTRUCT *); +BOOL ResizeBody(); /* Change Height of Font. MAde return type BOOL istead of VOID - LR */ +BOOL ResizeWidths(); /* Change Widths (Fixed Width Fonts).MAde return type BOOL istead of VOID - LR */ +BOOL SpreadWidths(DWORD); /* Change Widths (Var. Width Fonts). MAde return type BOOL istead of VOID - LR */ +VOID DeleteBitmap(); +VOID ExciseChars(); /* Delete part of a font */ +BOOL +CharWidth( + BYTE iChar, /* Character to change */ + DWORD wBox /* New width */ + ); +BOOL NewLastChar(DWORD); /* MAde return type BOOL istead of VOID - LR */ +BOOL NewFirstChar(DWORD); /* MAde return type BOOL istead of VOID - LR */ +#define kBoxLim 65 /* was 49 */ + +#define wBoxLim 65 +#define szNamesMax 32 +#define BLACK (LONG)0 +#define WHITE (LONG)0x00FFFFFF /* For SetPixel rgbColor */ +#define FILENAMEMAX MAX_PATH /* Maximum allowed length of file names */ + + +/********* + the following added 11-Sep-1986 to use dlgsave.c and dlgopen.c +**********/ +#define IDD_OPEN 1 /* dialog box ids */ +#define IDD_SAVE 2 +#define IDD_FORMAT 3 + +#define MAX_STR_LEN 128 +#define MAX_FNAME_LEN 128 +#define CBEXTMAX 6 /* Number of bytes in "\*.ext" */ + + +#define NOSAVE 0 /* return flags for DlgFnSave() */ +#define NEWSAVE 1 +#define OLDSAVE 2 + +#define NOOPEN 0 /* return flags for DlgFnOpen() */ +#define NEWOPEN 1 +#define OLDOPEN 2 + +#define WORD_LIMIT 65534 /* max. number of bytes that can be + read(written) by M_lread(HFILE_lwrite, , WPARAM*/ +#define SEGMENT_SIZE 65536 /* segment length in bytes */ + +/* abbreviations for accessing resource strings - LR */ + +#define vszNomPtSizeNotOk vrgsz[IDS_NOMPTSIZENOTOK ] +#define vszNomVertResNotOk vrgsz[IDS_NOMVERTRESNOTOK ] +#define vszNomHorResNotOk vrgsz[IDS_NOMHORRESNOTOK ] +#define vszAscentTooBig vrgsz[IDS_ASCENTTOOBIG ] +#define vszAscentNotOk vrgsz[IDS_ASCENTNOTOK ] +#define vszExtLeadNotOk vrgsz[IDS_EXTLEADNOTOK ] +#define vszIntLeadTooBig vrgsz[IDS_INTLEADTOOBIG ] +#define vszIntLeadNotOk vrgsz[IDS_INTLEADNOTOK ] +#define vszCharSetOutOfBounds vrgsz[IDS_CHARSETOUTOFBOUNDS ] +#define vszDefCharOutsideFont vrgsz[IDS_DEFCHAROUTSIDEFONT ] +#define vszDefCharNotOk vrgsz[IDS_DEFCHARNOTOK ] +#define vszBreakCharOutsideFont vrgsz[IDS_BREAKCHAROUTSIDEFONT] +#define vszBreakCharNotOk vrgsz[IDS_BREAKCHARNOTOK ] +#define vszUnknownFace vrgsz[IDS_UNKNOWNFACE ] +#define vszNoVarToFixChange vrgsz[IDS_NOVARTOFIXCHANGE ] +#define vszTooBigFor20 vrgsz[IDS_TOOBIGFOR20 ] +#define vszHeightOutOfBounds vrgsz[IDS_HEIGHTOUTOFBOUNDS ] +#define vszWidthOutOfBounds vrgsz[IDS_WIDTHOUTOFBOUNDS ] +#define vszChar1MoreThanDChar vrgsz[IDS_CHAR1MORETHANDCHAR ] +#define vszChar1NotOk vrgsz[IDS_CHAR1NOTOK ] +#define vszLastCharTooSmall vrgsz[IDS_LASTCHARTOOSMALL ] +#define vszLastCharNotOk vrgsz[IDS_LASTCHARNOTOK ] +#define vszCannotOpenClip vrgsz[IDS_CANNOTOPENCLIP ] +#define vszCopyingToClip vrgsz[IDS_COPYINGTOCLIP ] +#define vszNotEnoughMem vrgsz[IDS_NOTENOUGHMEM ] +#define vszAllocatingSpace vrgsz[IDS_ALLOCATINGSPACE ] +#define vszFontEdit vrgsz[IDS_FONTEDIT ] +#define vszFontShow vrgsz[IDS_FONTSHOW ] +#define vszDotFNT vrgsz[IDS_DOTFNT ] +#define vszBlankDashBlank vrgsz[IDS_BLANKDASHBLANK ] +#define vszErrorOpeningFile vrgsz[IDS_ERROROPENINGFILE ] +#define vszErrorReadingHdr vrgsz[IDS_ERRORREADINGHDR ] +#define vszUnknownFormat vrgsz[IDS_UNKNOWNFORMAT ] +#define vszErrorReadingBody vrgsz[IDS_ERRORREADINGBODY ] +#define vszFileTooLarge vrgsz[IDS_FILETOOLARGE ] +#define vszErrorWritingHdr vrgsz[IDS_ERRORWRITINGHDR ] +#define vszErrorWritingOffsets vrgsz[IDS_ERRORWRITINGOFFSETS ] +#define vszErrorWritingBody vrgsz[IDS_ERRORWRITINGBODY ] +#define vszStarDotFNT vrgsz[IDS_STARDOTFNT ] +#define vszUnknown vrgsz[IDS_UNKNOWN ] +#define vszMaxWidth vrgsz[IDS_MAXWIDTH ] +#define vszCharPixelWidth vrgsz[IDS_CHARPIXELWIDTH ] +#define vszABOUT vrgsz[IDS_ABOUT ] +#define vszDHeader vrgsz[IDS_DHEADER ] +#define vszDResize vrgsz[IDS_DRESIZE ] +#define vszDWidth vrgsz[IDS_DWIDTH ] +#define vszEdLimits0To64 vrgsz[IDS_EDLIMITS0TO64 ] +#define vszMaxWidthIncrease vrgsz[IDS_MAXWIDTHINCREASE ] +#define vszCannotChangeWidth vrgsz[IDS_CANNOTCHANGEWIDTH ] +#define vszWarning vrgsz[IDS_WARNING ] +#define vszIncorrectPixWidth vrgsz[IDS_INCORRECTPIXWIDTH ] +#define vszMaxWidthOutOfBounds vrgsz[IDS_MAXWIDTHOUTOFBOUNDS ] +#define vszAvgWidthOutOfBounds vrgsz[IDS_AVGWIDTHOUTOFBOUNDS ] +#define vszWidthBytesNotOk vrgsz[IDS_WIDTHBYTESNOTOK ] +#define vszBitsOffsetNotOk vrgsz[IDS_BITSOFFSETNOTOK ] +#define vszTableWidthsBad vrgsz[IDS_TABLEWIDTHSBAD ] +#define vszTableOffsetsBad vrgsz[IDS_TABLEOFFSETSBAD ] +#define vszcolors vrgsz[IDS_COLOR ] +#define vszAppWorkspace vrgsz[IDS_APPWORKSPACE ] +#define vszFileReadOnly vrgsz[IDS_FILEREADONLY ] +#define vszErrorClip vrgsz[IDS_ERRORCLIP ] +#define vszCHAR vrgsz[IDS_CHAR ] +#define vszWIDTH vrgsz[IDS_WIDTH ] +#define vszHEIGHT vrgsz[IDS_HEIGHT ] + + +/*------ fontedit.c -------*/ +extern VOID ResizeShow(VOID); +extern VOID ScrollFont(VOID); +extern VOID CharToBox(BYTE); +extern VOID FontRename(CHAR *); +extern VOID BoxToChar(BYTE); +extern DWORD GetkStuff(VOID); + +/*------ fontload.c -------*/ +extern VOID ToClipboard(BYTE, DWORD, DWORD); +extern VOID BoxToClipboard(POINT, DWORD, DWORD); +extern DWORD ClipboardToBox(POINT, DWORD, DWORD, BOOL); + +/*------ fontdlg.c -------*/ +BOOL +CommDlgOpen ( + HWND hWndParent, /* window handle of parent window */ + OFSTRUCT *pOfstrIn, /* ptr to current file OFSTRUCT (->cBytes=0 if no + * cur. file)*/ + CHAR *pszNewNameIn, /* ptr to array which will get new file's name */ + CHAR *pszExtIn, /* ptr to current default extension */ + CHAR *pszAppNameIn, /* ptr to application name */ + BOOL fOpenType + ); + +BOOL +CommDlgSaveAs( + HANDLE hInstance, + HWND hWndParent, /* window handle of parent window */ + OFSTRUCT *pOfstrIn, /* ptr to current file OFSTRUCT (->cBytes=0 if no + * cur. file)*/ + CHAR *pszNewNameIn, /* ptr to array which will get new file's name + * (no path) */ + CHAR *pszExtIn, /* ptr to current default extension */ + CHAR *pszAppNameIn /* ptr to application name */ + ); + +BOOL +DlgMergeStrings( + CHAR *szSrc, + CHAR *szMerge, + CHAR *szDst + ); + +/*------ fonthead.c -------*/ +extern VOID ErrorBox(HWND, CHAR *); + +/*------ fontchar.c -------*/ +extern VOID ClearBox(VOID); + +/*------ fontcvt.c --------*/ + +BOOL +fConvStructInit (); + +VOID +vFontStructFromBuffer ( + PBYTE pjSourceBuff, + FontHeaderType *pfhDestFHStruct + ); + +VOID +vBufferFromFontStruct ( + FontHeaderType *pfhSourceFHStruct, + PBYTE pjDestBuff + ); + +VOID +vBufferFromFont30Struct ( + FontHeader30 *pfh3SourceFH3Struct, + PBYTE pjDestBuff + ); + +VOID +vGlyphInfo20FromBuffer ( + PBYTE pjSourceBuff, + GLYPHINFO_20 *pgi2DestGI2Struct + ); + +VOID +vGlyphInfo30FromBuffer ( + PBYTE pjSourceBuff, + GLYPHINFO_30 *pgi3DestGI3Struct + ); + +VOID +vBufferFromGlyphInfo20 ( + GLYPHINFO_20 *pgi2SrcGI2Struct, + PBYTE pjDestBuff + ); + +VOID +vBufferFromGlyphInfo30 ( + GLYPHINFO_30 *pgi3SrcGI3Struct, + PBYTE pjDestBuff + ); + +#ifdef JAPAN +// dword alligned size of DIB scan in bytes + +#define CJ_DIB_SCAN(cx) ((((cx) + 31) & ~31) >> 3) + +#else /* not JAPAN */ + +#define CJ_DIB_SCAN(cx) ((cx + 15) >> 4 << 1) + +#endif diff --git a/private/sdktools/fontedit/fontedit.ico b/private/sdktools/fontedit/fontedit.ico Binary files differnew file mode 100644 index 000000000..b8fee1daa --- /dev/null +++ b/private/sdktools/fontedit/fontedit.ico diff --git a/private/sdktools/fontedit/fontedit.lnk b/private/sdktools/fontedit/fontedit.lnk new file mode 100644 index 000000000..6ddd693c3 --- /dev/null +++ b/private/sdktools/fontedit/fontedit.lnk @@ -0,0 +1,5 @@ +fontedit fontload fonthead fontchar dlgopen dlgsave +fontedit.exe/ALIGN:16 +fontedit.map/MAP +libw slibcew/noe/nod +fontedit.def diff --git a/private/sdktools/fontedit/fontedit.rc b/private/sdktools/fontedit/fontedit.rc new file mode 100644 index 000000000..344b1461f --- /dev/null +++ b/private/sdktools/fontedit/fontedit.rc @@ -0,0 +1,364 @@ +#include "fontedit.h" +#include "windows.h" + +#define DLGMODAL WS_POPUP | WS_DLGFRAME | WS_VISIBLE +#define TABGRP WS_TABSTOP | WS_GROUP +#define VK_A 97 +#define VK_D 100 +#define VK_L 108 +#define VK_R 114 +#define VK_B 98 + +BOX_CLEAR CURSOR fillclr.cur +BOX_FILL CURSOR fillsol.cur +BOX_INV CURSOR fillinv.cur +BOX_HATCH CURSOR fillhat.cur +BOX_LEFTRIGHT CURSOR filllft.cur +BOX_TOPBOTTOM CURSOR filltop.cur +BOX_COPY CURSOR fillcpy.cur +BOX_PASTE CURSOR fillpst.cur + + +fontedit icon FONTEDIT.ICO + +fontedit menu +begin + POPUP "&File" + begin + MENUITEM "&New...", FONT_NEW + MENUITEM "&Open...", FONT_LOAD + MENUITEM "&Save", FONT_SAVE, GRAYED + MENUITEM "Save &as...", FONT_SAVEAS, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", FONT_EXIT + end + POPUP "&Edit", GRAYED + begin + MENUITEM "&Undo\tAlt+Bksp", BOX_UNDO, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Copy\tCtrl+Ins", FONT_COPY + MENUITEM "&Paste\tShift+Ins", FONT_PASTE, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Refresh", BOX_REFRESH, GRAYED + end + POPUP "F&ont", GRAYED + begin + MENUITEM "&Size...", FONT_RESIZE + MENUITEM "&Header...", FONT_HEADER + end + POPUP "F&ill", GRAYED + begin + MENUITEM "&Clear\tCtrl+C", BOX_CLEAR + MENUITEM "&Solid\tCtrl+S", BOX_FILL + MENUITEM "&Hatched\tCtrl+H", BOX_HATCH + MENUITEM "&Inverted\tCtrl+I", BOX_INV + MENUITEM "&Left=Right\tCtrl+F1", BOX_LEFTRIGHT + MENUITEM "&Top=Bottom\tCtrl+F2", BOX_TOPBOTTOM + MENUITEM "C&opy\tCtrl+O", BOX_COPY + MENUITEM "&Paste\tCtrl+P", BOX_PASTE, GRAYED + end + POPUP "&Width", GRAYED + begin + MENUITEM "Wider (left)\tCtrl+L", WIDER_LEFT + MENUITEM "Wider (right)\tCtrl+R", WIDER_RIGHT + MENUITEM "Wider (both)\tCtrl+B", WIDER_BOTH + MENUITEM "Narrower (left)\tL", NARROWER_LEFT + MENUITEM "Narrower (right)\tR", NARROWER_RIGHT + MENUITEM "Narrower (both)\tB", NARROWER_BOTH + MENUITEM SEPARATOR + MENUITEM "Width ...", WIDTH + end + POPUP "&Row", GRAYED + begin + MENUITEM "&Add", ROW_ADD + MENUITEM "&Delete", ROW_DEL + end + POPUP "&Column", GRAYED + begin + MENUITEM "&Add", COL_ADD + MENUITEM "&Delete", COL_DEL + end + POPUP "&Help" + begin + MENUITEM "&Contents", FONT_HELP_CONTENTS + MENUITEM "&Search", FONT_HELP_SEARCH + MENUITEM SEPARATOR + MENUITEM "A&bout Fontedit...", FONT_ABOUT + end +end + +FE ACCELERATORS +BEGIN + "^C", BOX_CLEAR + "^S", BOX_FILL + "^H", BOX_HATCH + "^I", BOX_INV + "^O", BOX_COPY + "^P", BOX_PASTE + + "^L", WIDER_LEFT + "^R", WIDER_RIGHT + "^B", WIDER_BOTH + + VK_L, NARROWER_LEFT, ASCII + VK_R, NARROWER_RIGHT, ASCII + VK_B, NARROWER_BOTH, ASCII + + VK_F1,BOX_LEFTRIGHT , VIRTKEY, CONTROL + VK_F2,BOX_TOPBOTTOM , VIRTKEY, CONTROL + + VK_INSERT, FONT_COPY, VIRTKEY, CONTROL + VK_INSERT, FONT_PASTE, VIRTKEY, SHIFT + VK_BACK, BOX_UNDO, VIRTKEY, ALT +END + + + +ABOUT DIALOG LOADONCALL MOVEABLE DISCARDABLE 22, 17, 160, 80 +STYLE WS_DLGFRAME | WS_POPUP +BEGIN + CONTROL "Microsoft Windows" -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 0, 5, 160, 8 + CONTROL "Font Editor" -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 0, 14, 160, 8 + CONTROL "Version 3.0" -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 30, 34, 94, 8 + CONTROL "Copyright © 1985-1991, Microsoft Corp." -1, "static", SS_CENTER | WS_GROUP | WS_CHILD, 0, 47, 160, 9 + CONTROL "fontedit" -1, "static", SS_ICON | WS_CHILD, 14, 13, 0, 0 + CONTROL "OK" IDOK, "button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 64, 59, 32, 14 +END + +IDD_OPEN DIALOG LOADONCALL MOVEABLE DISCARDABLE 10, 10, 198, 136 +STYLE WS_DLGFRAME | WS_POPUP +BEGIN + CONTROL "" ID_BOXOPEN,"static",SS_LEFT|WS_CHILD, 2,148,198,0 + CONTROL "FONTEDIT requires you to create a new font file" -1, "static",SS_LEFT|WS_GROUP|WS_CHILD, 2,2, 196,8 + CONTROL "by borrowing from an already existing file." -1, "static", SS_LEFT|WS_GROUP|WS_CHILD,2, 12, 196,8 + CONTROL "Open File &Name:" -1, "static", SS_LEFT | WS_GROUP | WS_CHILD, 2,24, 76, 10 + CONTROL "" ID_EDIT, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP | WS_CHILD, 2, 37, 100, 12 + CONTROL "&Files in" -1, "static", SS_LEFT | WS_GROUP | WS_CHILD, 2, 59, 38, 10 + CONTROL "" ID_LISTBOX, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | WS_BORDER | WS_VSCROLL | WS_GROUP | WS_TABSTOP | WS_CHILD, 3, 73, 90, 57 + CONTROL "&Open" IDOK, "button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD,118, 82, 50, 16 + CONTROL "Cancel" IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD,118, 107, 50, 16 + CONTROL "" ID_PATH, "static", SS_LEFT | SS_NOPREFIX | WS_GROUP | WS_CHILD, 44, 59, 98, 12 +END + +IDD_SAVE DIALOG LOADONCALL MOVEABLE DISCARDABLE 10, 10, 140, 160 +STYLE WS_DLGFRAME | WS_POPUP +BEGIN + CONTROL "Save File &Name: " -1, "static", SS_LEFT | WS_GROUP | WS_CHILD, 2, 6,100, 12 + CONTROL "" ID_EDIT, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP | WS_CHILD, 2, 20,110, 12 + CONTROL "" ID_PATH, "static", SS_LEFT | SS_NOPREFIX | WS_GROUP | WS_CHILD, 2,35, 98, 12 + CONTROL "&Directories" -1, "static", SS_LEFT | WS_GROUP | WS_CHILD, 2, 50, 45, 10 + CONTROL "" ID_LISTBOX, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | WS_BORDER | WS_VSCROLL | WS_GROUP | WS_TABSTOP | WS_CHILD, 3, 65, 70, 60 + CONTROL "OK" IDOK, "button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 90, 70, 40, 16 + CONTROL "Cancel" IDCANCEL, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 90,100, 40, 16 + GROUPBOX "Font Format" 0, 7,127, 100,25 + RADIOBUTTON "2.0", ID_FORMAT2, 20, 137, 20, 12 ,WS_GROUP|WS_TABSTOP + RADIOBUTTON "3.0", ID_FORMAT3, 80, 137, 20, 12 + +END + + +IDD_FORMAT DIALOG LOADONCALL MOVEABLE DISCARDABLE 46, 37, 141, 79 +CAPTION "Save File Format" +STYLE WS_BORDER | WS_CAPTION | WS_DLGFRAME | DS_MODALFRAME | WS_POPUP +BEGIN + CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 20, 53, 40, 16 + CONTROL "Cancel", 2, "button", BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP | WS_CHILD, 80, 53, 40, 16 + GROUPBOX "Font Format" 0, 23,10, 96,30 + RADIOBUTTON "2.0", ID_FORMAT2, 37, 21, 20, 12 ,WS_GROUP|WS_TABSTOP + RADIOBUTTON "3.0", ID_FORMAT3, 85, 21, 20, 12 + +END + + + +DWidth DIALOG 20, 20, 140, 50 +STYLE WS_POPUP | WS_DLGFRAME | WS_VISIBLE +BEGIN + LTEXT "Character Width", -1, 10, 7, 50, 20 + EDITTEXT BOX_WIDTH, 50, 5, 30, 12 + + DEFPUSHBUTTON "OK", IDOK, 100, 5, 35, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 100, 23, 35, 14, WS_GROUP +END + + +DHeader DIALOG 10, 10, 282, 162 +STYLE WS_POPUP | WS_DLGFRAME | WS_VISIBLE +BEGIN + LTEXT "Face Name", -1, 10, 22, 43, 10 + EDITTEXT ID_FACE_NAME, 60, 20, 133, 12 + LTEXT "File Name", -1, 10, 7, 50, 10 + LTEXT "", ID_FONT_NAME, 52, 7, 65, 12 + LTEXT "Copyright: ", -1, 10, 37, 90, 10 + EDITTEXT ID_COPYRIGHT, 10, 47, 245, 12 + + LTEXT "Nominal Point Size", -1, 10, 68, 60, 20 + EDITTEXT ID_POINTS, 65, 66, 17, 12, TABGRP + LTEXT "Height of Ascent", -1, 90, 68, 60, 20 + EDITTEXT ID_ASCENT, 150, 66, 17, 12, TABGRP + + LTEXT "Nominal Vert. Resolution", -1, 10, 85, 60, 20 + EDITTEXT ID_VERT_RES, 65, 85, 17, 12 , TABGRP + LTEXT "Nominal Horiz. Resolution", -1, 90, 85, 60, 20 + EDITTEXT ID_HORIZ_RES, 150, 85, 17, 12 , TABGRP + + LTEXT "External Leading", -1, 10, 104, 60, 20 + EDITTEXT ID_EXT_LEADING, 65, 104, 17, 12 , TABGRP + LTEXT "Internal Leading", -1, 90, 104, 60, 20 + EDITTEXT ID_INT_LEADING, 150, 104, 17, 12, TABGRP + + LTEXT "Default Character", -1, 10, 123, 50, 20 + EDITTEXT ID_DEFAULT_CHAR, 65, 123, 17, 12, TABGRP + LTEXT "Break Character", -1, 90, 123, 50, 20 + EDITTEXT ID_BREAK_CHAR, 150, 123, 17, 12, TABGRP + + GROUPBOX "Character Set", 0, 174, 60, 104, 31 +#ifdef JAPAN + RADIOBUTTON, "ShiftJIS", ID_SHIFTJIS, 215, 78, 40, 12 , TABGRP + RADIOBUTTON, "ANSI", ID_ANSI, 177, 68, 35, 12 +#else + RADIOBUTTON, "ANSI", ID_ANSI, 177, 68, 35, 12 , TABGRP +#endif + RADIOBUTTON, "OEM", ID_OEM, 215, 68, 35, 12 + RADIOBUTTON, "SYMBOL", ID_SYMBOL, 177, 78, 40, 12 + EDITTEXT ID_CHAR_SET, 255, 66, 17, 12 ,TABGRP + + GROUPBOX "Font Family", -1, 174, 92, 104, 50 + RADIOBUTTON "Roman", ID_ROMAN, 177, 102, 42, 12 , TABGRP + RADIOBUTTON "Modern", ID_MODERN, 220, 102, 55, 12 + RADIOBUTTON "Swiss", ID_SWISS, 177, 114, 42, 12 + RADIOBUTTON "Decorative", ID_DECORATIVE, 220, 114, 55, 12 + RADIOBUTTON "Script", ID_SCRIPT, 177, 126, 42, 12 + RADIOBUTTON "Dontcare", ID_UNKNOWN, 220, 126, 55, 12 + + CHECKBOX "Italic", ID_ITALIC, 10, 142, 60, 12 , TABGRP + CHECKBOX "Underline", ID_UNDERLINE, 75, 142, 60, 12 , TABGRP + CHECKBOX "Strikeout", ID_STRIKEOUT, 140, 142, 60, 12, TABGRP + + DEFPUSHBUTTON "OK", IDOK, 230, 5, 35, 14, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, 230, 23, 35, 14, WS_GROUP +END + + +DReSize DIALOG 10, 10, 200, 150 +STYLE DLGMODAL +BEGIN + LTEXT "", ID_WIDTH_TEXT, 10, 10, 50, 20 /* Filled in later */ + EDITTEXT ID_WIDTH, 65, 12, 13, 12 , TABGRP + LTEXT "Character Pixel Height", -1, 10, 30, 50, 20 + EDITTEXT ID_PIX_HEIGHT, 65, 32 13, 12, TABGRP + LTEXT "Average Width", -1, 110, 10, 50, 20 + LTEXT "", ID_AVERAGE, 160, 10, 17, 12 + LTEXT "First Character", -1, 10, 50, 50, 20 + EDITTEXT ID_FIRST_CHAR, 65, 52, 17, 12, TABGRP + LTEXT "Last Character", -1, 10, 70, 50, 20 + EDITTEXT ID_LAST_CHAR, 65, 72, 17, 12, TABGRP + + GROUPBOX "Pitch", -1, 10, 88, 65, 35, + RADIOBUTTON, "Fixed", ID_FIXED, 20, 98, 45, 12, TABGRP + RADIOBUTTON, "Variable", ID_VARIABLE, 20, 110, 45, 12, + + GROUPBOX "Weight", -1, 110, 28, 70, 115 + RADIOBUTTON "Thin", ID_THIN, 120, 40, 55, 11,TABGRP + RADIOBUTTON "Extra Light", ID_EXTRALIGHT, 120, 51, 55, 11 + RADIOBUTTON "Light", ID_LIGHT, 120, 62, 55, 11 + RADIOBUTTON "Normal", ID_NORMAL, 120, 73, 55, 11 + RADIOBUTTON "Medium", ID_MEDIUM, 120, 84, 55, 11 + RADIOBUTTON "Semi-Bold", ID_SEMIBOLD, 120, 95, 55, 11 + RADIOBUTTON "Bold", ID_BOLD, 120, 106, 55, 11 + RADIOBUTTON "Extra Bold", ID_EXTRABOLD, 120, 117, 55, 11 + RADIOBUTTON "Heavy", ID_HEAVY, 120, 128, 55, 11 + + DEFPUSHBUTTON "OK", IDOK, 10, 130, 35, 14, TABGRP + PUSHBUTTON "Cancel", IDCANCEL, 56, 130, 35, 14, TABGRP +END + +STRINGTABLE +BEGIN + IDS_FILEREADONLY,"Warning : File is read only. Changes cannot will not be written to disk." + IDS_NOMPTSIZENOTOK , "Nominal Point size must be number from 0-999" + IDS_NOMVERTRESNOTOK, "Nominal Vertical Resolution must be number from 0-999" + IDS_NOMHORRESNOTOK, "Nominal Horizontal Resolution must be number from 0-999" + IDS_ASCENTTOOBIG, "Ascent cannot be greater than font height" + IDS_ASCENTNOTOK, "Ascent must be number from 0-999" + IDS_EXTLEADNOTOK,"External leading must be number from 0-999" + IDS_INTLEADTOOBIG, "Internal leading must not be greater than Ascent" + IDS_INTLEADNOTOK, "Internal leading must be number from 0-999" + IDS_CHARSETOUTOFBOUNDS, "Character set must be number from 0-255" + IDS_DEFCHAROUTSIDEFONT, "Default character must be within the font" + IDS_DEFCHARNOTOK,"Default char must be number from 0-255" + IDS_BREAKCHAROUTSIDEFONT, "Break char must be within the font" + IDS_BREAKCHARNOTOK, "Break char must be number from 0-255" + IDS_UNKNOWNFACE,"Font face must be specified -- 'Unknown' inserted" + IDS_NOVARTOFIXCHANGE, "Cannot change width from variable to fixed" + IDS_TOOBIGFOR20 "This resize will make font too big to save in 2.0 format. Save in 3.0 format?" + IDS_HEIGHTOUTOFBOUNDS, "Font height must be number from 1-64 pixels" + IDS_WIDTHOUTOFBOUNDS, "Fixed/maximum width must be number from 1-64" + IDS_CHAR1MORETHANDCHAR, "First character cannot be more than Default character" + IDS_CHAR1NOTOK,"First character must be number from 0-255" + IDS_LASTCHARTOOSMALL,"Last character cannot be less than Default character" + IDS_LASTCHARNOTOK, "Last character must be number from 0-255" + IDS_CANNOTOPENCLIP, "Cannot open Clipboard" + IDS_ERRORCLIP, "Error copying from Clipboard" + IDS_COPYINGTOCLIP, "abc" /* Unused string, MUST BE TRHEE CHARS LONG! */ + IDS_NOTENOUGHMEM, "Not enough memory available" + IDS_ALLOCATINGSPACE, "Allocating space" + IDS_FONTEDIT, "FontEdit" + IDS_FONTSHOW, "FontShow" + IDS_DOTFNT, ".FNT" + IDS_BLANKDASHBLANK, " - " + IDS_ERROROPENINGFILE, "Error trying to open file" + IDS_ERRORREADINGHDR, "Error reading header of font file" + IDS_UNKNOWNFORMAT, "File not in known format" + IDS_ERRORREADINGBODY, "Error reading body of font file" + IDS_FILETOOLARGE, "Font file too large to save" + IDS_ERRORWRITINGHDR, "Error writing header of font file" + IDS_ERRORWRITINGOFFSETS, "Error writing offsets table of font file" + IDS_ERRORWRITINGBODY, "Error writing body of font file" + IDS_STARDOTFNT, "*.FNT" + IDS_UNKNOWN, "Unknown" + IDS_MAXWIDTH, "Maximum width" + IDS_CHARPIXELWIDTH, "Character Pixel width" + IDS_ABOUT, "ABOUT" + IDS_DHEADER, "DHeader" + IDS_DRESIZE, "DResize" + IDS_DWIDTH, "DWidth" + IDS_EDLIMITS0TO64, "Editor only handles widths 0-64" + IDS_MAXWIDTHINCREASE, "Maximum width will be increased" + IDS_CANNOTCHANGEWIDTH, "Cannot change width of a fixed width font" + IDS_WARNING, "WARNING !" + IDS_INCORRECTPIXWIDTH, "PixWidth field in header should be 0 for variable-width fonts" + IDS_MAXWIDTHOUTOFBOUNDS, " Maximum width field in header must be number from 0-64" + IDS_AVGWIDTHOUTOFBOUNDS, " Average width field in header must be number from 0-64" + IDS_WIDTHBYTESNOTOK," WidthBytes field in header not OK" + IDS_BITSOFFSETNOTOK," BitsOffset field in header cannot exceed 64kbytes in a 2.0 font" + IDS_TABLEWIDTHSBAD, " Bad value(s) in width field(s) of offset table" + IDS_TABLEOFFSETSBAD," Bad value(s) in offset field(s) of offset table" + IDS_COLOR, "colors" + IDS_APPWORKSPACE, "AppWorkspace" + IDS_APPNAME, "Font Editor" + IDS_IFN, "%% is not a valid filename." + IDS_FNF, "%% not found." + IDS_REF, "Replace existing %%?" + IDS_SCC, "%% has changed. Save current changes?" + IDS_EOF, "Error opening %%" + IDS_ECF, "Error creating %%" + IDS_FRO, "Warning : File %% is read only. Changes will not be written to disk." + IDS_EXT, "FNT" + IDS_EXTDESC, "Font File (*.FNT)" + IDS_NEW_FONT, "FONTEDIT requires you to create a new font file by borrowing from an already existing file." + IDS_CHAR, "Char=%d" + IDS_WIDTH, "Width=%d" + IDS_HEIGHT, "Height=%d" + IDS_HELPFILE, "fontedit.hlp" +END + +#include <ntverp.h> + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "Microsoft Font Editor for Raster Fonts" +#define VER_INTERNALNAME_STR "fontedit\0" +#define VER_ORIGINALFILENAME_STR "FONTEDIT.EXE" + +#include "common.ver" diff --git a/private/sdktools/fontedit/fonthead.c b/private/sdktools/fontedit/fonthead.c new file mode 100644 index 000000000..20f3c58e2 --- /dev/null +++ b/private/sdktools/fontedit/fonthead.c @@ -0,0 +1,790 @@ +#include "windows.h" +#include <port1632.h> +#include "fontedit.h" +#include "fcntl.h" +#include "stdio.h" + +#define ATTRDIRLIST 0x4010 /* Include directories and drives in listbox */ + +/****************************************************************************/ +/* Shared Variables */ +/****************************************************************************/ +extern LONG lSizeOfOldFontHeader; /* Old font header type. */ +extern FontHeaderType font; /* Structure of Font File Header */ +extern FontHeaderType fontBuffer; /* temp structure of font file header */ +CHAR szFontFileFull[FILENAMEMAX] = {"*.FNT"}; /* Name of Font File */ +CHAR szFontFile[FILENAMEMAX] = {"*.FNT"}; /* Name of Font File */ +CHAR szNewFile[FILENAMEMAX] = {"*.FNT"}; /* Name of New File */ +extern CHAR szFaceName[]; /* Face Name of Font */ +extern BOOL NewFile; /* flag indicating if file was opened + by selecting NEW on menu */ +extern CHAR *vrgsz[CSTRINGS]; /* string table */ +extern BOOL fChanged; /* Note if we did anything */ +extern INT swH; +extern BYTE iChar, jChar; + +extern HWND hFont; /* Handle to Show window */ +extern HWND hBox; /* Handle to Edit Window */ +extern HDC hMemDC; /* Handle to Memory Display Context */ + +extern CHAR szAppName[]; +extern INT iFontFormat; /* format of font currently being edited */ +extern DWORD cTable; /* offset table size */ +/****************************************************************************/ +/* Local Variables */ +/****************************************************************************/ +WORD newCharSet; /* Temporary value of font.CharSet */ +WORD newFamily; /* Temporary value of font.Family << 4 */ +BOOL newFV; /* Temporay value of Fixed/Variable flag */ +WORD newItalic, newUnderline, newStrikeOut; +WORD newWeight; /* Temporary value of font.Weight */ +BOOL fMsgBoxUp; /* Bug Fix Hack explained in ReSizeProc */ +/****************************************************************************/ +/* Local Functions */ +/****************************************************************************/ + +VOID SetCharSet(HWND hDial); +VOID SetFamily(HWND hDial); +VOID SetFixed(HWND hDial, BOOL fFV); +VOID SetWeight(HWND hDial); + +/**************************************************************************** + * BOOL APIENTRY HeaderProc(hDial, message, wParam, lParam) + * + * purpose : Dialog function which verifies and accepts inputs which may + * alter font's header information (font attributes) + * + * params : Same as for all dialog functions + * + * side effects: may alter font attributes + * + ***************************************************************************/ +BOOL APIENTRY +HeaderProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + FontHeaderType FAR * lpFont; + BOOL fOk; /* for GetDlgItemInt errors! */ + UINT i; + + UNREFERENCED_PARAMETER(lParam); + + lpFont = (FontHeaderType FAR *)&font; + switch (message) + { + default: + return FALSE; + case WM_INITDIALOG: + newCharSet = font.CharSet; + SetCharSet(hDial); /* Set OEM/ANSI buttons */ + + newFamily = (WORD) (font.Family >> 4); /* Working value */ + SetFamily(hDial); /* Set Font Family */ + + CheckDlgButton(hDial, ID_ITALIC, newItalic = font.Italic); + CheckDlgButton(hDial, ID_UNDERLINE, newUnderline = font.Underline); + CheckDlgButton(hDial, ID_STRIKEOUT, newStrikeOut = font.StrikeOut); + + SetDlgItemInt(hDial, ID_POINTS, lpFont->Points, FALSE); + SetDlgItemInt(hDial, ID_VERT_RES, lpFont->VertRes, FALSE); + SetDlgItemInt(hDial, ID_HORIZ_RES, lpFont->HorizRes, FALSE); + SetDlgItemInt(hDial, ID_ASCENT, lpFont->Ascent, FALSE); + SetDlgItemInt(hDial, ID_EXT_LEADING, lpFont->ExtLeading, FALSE); + SetDlgItemInt(hDial, ID_INT_LEADING, lpFont->IntLeading, FALSE); + SetDlgItemInt(hDial, ID_DEFAULT_CHAR,lpFont->DefaultChar , FALSE); + SetDlgItemInt(hDial, ID_BREAK_CHAR, lpFont->BreakChar, FALSE); + + SetDlgItemText(hDial, ID_COPYRIGHT, lpFont->Copyright); + SetDlgItemText(hDial, ID_FACE_NAME, (LPSTR)szFaceName); + SetDlgItemText(hDial, ID_FONT_NAME, (LPSTR)szFontFile); + break; + case WM_COMMAND: + switch (GET_WM_COMMAND_ID(wParam, lParam)) + { + case ID_ANSI: + newCharSet = ANSI_CHARSET; + SetCharSet(hDial); /* Set OEM/ANSI buttons */ + break; + case ID_SYMBOL: + newCharSet = SYMBOL_CHARSET; + SetCharSet(hDial); /* Set OEM/ANSI buttons */ + break; + case ID_OEM: + newCharSet = OEM_CHARSET; + SetCharSet(hDial); /* Set OEM/ANSI buttons */ + break; +#ifdef JAPAN + case ID_SHIFTJIS: + newCharSet = SHIFTJIS_CHARSET; + SetCharSet(hDial); /* Set OEM/ANSI buttons */ + break; +#endif + case ID_UNKNOWN: + newFamily = 0; + SetFamily(hDial); + break; + case ID_ROMAN: + newFamily = 1; + SetFamily(hDial); + break; + case ID_SWISS: + newFamily = 2; + SetFamily(hDial); + break; + case ID_MODERN: + newFamily = 3; + SetFamily(hDial); + break; + case ID_SCRIPT: + newFamily = 4; + SetFamily(hDial); + break; + case ID_DECORATIVE: + newFamily = 5; + SetFamily(hDial); + break; + case ID_ITALIC: + newItalic = (WORD) !newItalic; + CheckDlgButton(hDial, ID_ITALIC, newItalic); + break; + case ID_UNDERLINE: + newUnderline = (WORD) !newUnderline; + CheckDlgButton(hDial, ID_UNDERLINE, newUnderline); + break; + case ID_STRIKEOUT: + newStrikeOut = (WORD) !newStrikeOut; + CheckDlgButton(hDial, ID_STRIKEOUT, newStrikeOut); + break; + case ID_CHAR_SET : + i = GetDlgItemInt(hDial, ID_CHAR_SET, (LPBOOL)&fOk, FALSE); + if (fOk && (i < 256)) + { + font.CharSet = (BYTE) (newCharSet = (WORD) i); + CheckDlgButton(hDial, ID_ANSI, (WORD) (i == ANSI_CHARSET)); + CheckDlgButton(hDial, ID_SYMBOL, (WORD) (i == SYMBOL_CHARSET)); + CheckDlgButton(hDial, ID_OEM, (WORD) (i == OEM_CHARSET)); +#ifdef JAPAN + CheckDlgButton(hDial, ID_SHIFTJIS,i == SHIFTJIS_CHARSET); +#endif + } + break; + + case IDOK: + font.CharSet = (BYTE) newCharSet; + font.Family = (BYTE) ((newFamily << 4) | (font.Family & 1)); + font.Italic = (BYTE) newItalic; + font.Underline = (BYTE) newUnderline; + font.StrikeOut = (BYTE) newStrikeOut; + fChanged = TRUE; + + /* nominal point size */ + i = GetDlgItemInt(hDial, ID_POINTS, (LPBOOL)&fOk, FALSE); + if (fOk) + lpFont->Points = (WORD) i; + else{ + ErrorBox(hDial, vszNomPtSizeNotOk); + SetFocus(GetDlgItem(hDial, ID_POINTS)); + break; + } + /* nominal vertical resolution */ + i = GetDlgItemInt(hDial, ID_VERT_RES, (LPBOOL)&fOk, FALSE); + if (fOk) + lpFont->VertRes = (WORD) i; + else{ + ErrorBox(hDial, vszNomVertResNotOk); + SetFocus(GetDlgItem(hDial, ID_VERT_RES)); + break; + } + /* nominal horizontal resolution */ + i = GetDlgItemInt(hDial, ID_HORIZ_RES, (LPBOOL)&fOk, FALSE); + if (fOk) + lpFont->HorizRes = (WORD) i; + else{ + ErrorBox(hDial, vszNomHorResNotOk); + SetFocus(GetDlgItem(hDial, ID_HORIZ_RES)); + break; + } + /* font ascent */ + i = GetDlgItemInt(hDial, ID_ASCENT, (LPBOOL)&fOk, FALSE); + if (fOk) + { + if (i <= font.PixHeight) + lpFont->Ascent = (WORD) i; + else{ + ErrorBox(hDial, vszAscentTooBig); + SetFocus(GetDlgItem(hDial, ID_ASCENT)); + break; + } + } + else{ + ErrorBox(hDial, vszAscentNotOk); + SetFocus(GetDlgItem(hDial, ID_ASCENT)); + break; + } + /* font external leading */ + i = GetDlgItemInt(hDial, ID_EXT_LEADING, (LPBOOL)&fOk, FALSE); + if (fOk) + lpFont->ExtLeading = (WORD) i; + else{ + ErrorBox(hDial, vszExtLeadNotOk); + SetFocus(GetDlgItem(hDial, ID_EXT_LEADING)); + break; + } + /* font internal leading */ + i = GetDlgItemInt(hDial, ID_INT_LEADING, (LPBOOL)&fOk, FALSE); + if (fOk) + { + if (i <= font.Ascent) + lpFont->IntLeading = (WORD) i; + else{ + ErrorBox(hDial, vszIntLeadTooBig); + SetFocus(GetDlgItem(hDial, ID_INT_LEADING)); + break; + } + } + else{ + ErrorBox(hDial, vszIntLeadNotOk); + SetFocus(GetDlgItem(hDial, ID_INT_LEADING)); + break; + } + /* font character set */ + i = GetDlgItemInt(hDial, ID_CHAR_SET, (LPBOOL)&fOk, FALSE); + if (fOk && i < 256) + { + font.CharSet = (BYTE) i; + SetCharSet(hDial); + } + else{ + ErrorBox(hDial, vszCharSetOutOfBounds); + SetFocus(GetDlgItem(hDial, ID_CHAR_SET)); + break; + } + /* font default char number */ + i = GetDlgItemInt(hDial, ID_DEFAULT_CHAR, (LPBOOL)&fOk, FALSE); + + if (fOk) + { + if (i <= (UINT)font.LastChar - (UINT)font.FirstChar) + lpFont->DefaultChar = (BYTE) i; + else{ + ErrorBox(hDial, vszDefCharOutsideFont); + SetFocus(GetDlgItem(hDial, ID_DEFAULT_CHAR)); + break; + } + } + else{ + ErrorBox(hDial, vszDefCharNotOk); + SetFocus(GetDlgItem(hDial, ID_DEFAULT_CHAR)); + break; + } + /* break char number */ + i = GetDlgItemInt(hDial, ID_BREAK_CHAR, (LPBOOL)&fOk, FALSE); + if (fOk) + { + if (i <= (UINT)(font.LastChar - font.FirstChar)) + lpFont->BreakChar = (BYTE) i; + else{ + ErrorBox(hDial, vszBreakCharOutsideFont); + SetFocus(GetDlgItem(hDial, ID_BREAK_CHAR)); + break; + } + } + else{ + ErrorBox(hDial, vszBreakCharNotOk); + SetFocus(GetDlgItem(hDial, ID_BREAK_CHAR)); + break; + } + /* facename string */ + GetDlgItemText(hDial, ID_COPYRIGHT, lpFont->Copyright, 60); + GetDlgItemText(hDial, ID_FACE_NAME, (LPSTR)szFaceName, szNamesMax); + if (!lstrlen((LPSTR)szFaceName)) + { + lstrcpy((LPSTR)szFaceName, (LPSTR)vszUnknown); + ErrorBox(hDial, vszUnknownFace); + } + /* fall thru to enddialog */ + + + case IDCANCEL: + EndDialog(hDial, wParam != IDCANCEL); + break; + + default: + break; + } + } + return TRUE; +} + +/**************************************************************************** + * char * VerifyHeaderContents() + * + * purpose: Checks if the Header information of the file just read makes + * sense. If not, returns an error message string to FontLoad + * + * params : none + * + * returns :char *szError : ptr to error string if error occurs + * NULL otherwise + * + * side effects: none + * + ***************************************************************************/ +CHAR * PASCAL +VerifyHeaderContents( + VOID + ) +{ + if (fontBuffer.Points > 999) + return vszNomPtSizeNotOk; + if (fontBuffer.VertRes > 999) + return vszNomVertResNotOk; + if (fontBuffer.HorizRes > 999) + return vszNomHorResNotOk; + if (fontBuffer.Ascent > fontBuffer.PixHeight) + return vszAscentTooBig; + if (fontBuffer.Ascent > 999) + return vszAscentNotOk; + if (fontBuffer.ExtLeading > 999) + return vszExtLeadNotOk; + if (fontBuffer.IntLeading > fontBuffer.Ascent) + return vszIntLeadTooBig; + if (fontBuffer.IntLeading > 999) + return vszIntLeadNotOk; + if (fontBuffer.LastChar > 255) + return vszCharSetOutOfBounds; + if (fontBuffer.DefaultChar > fontBuffer.FirstChar + (fontBuffer.LastChar - fontBuffer.FirstChar)) +#if 0 + fontBuffer.DefaultChar = 0; +#else + return vszDefCharOutsideFont; +#endif + if (fontBuffer.DefaultChar > 255) + return vszDefCharNotOk; + if (fontBuffer.BreakChar > (fontBuffer.LastChar - fontBuffer.FirstChar)) + return vszBreakCharOutsideFont; + if (fontBuffer.BreakChar > 255) + return vszBreakCharNotOk; + if (fontBuffer.PixHeight > 64) + return vszHeightOutOfBounds; + if (fontBuffer.MaxWidth > 64) + return vszMaxWidthOutOfBounds; + if (fontBuffer.AvgWidth > 64) + return vszAvgWidthOutOfBounds; + if (iFontFormat == ID_FORMAT2) + if (fontBuffer.BitsOffset > (DWORD)SEGMENT_SIZE) + return vszBitsOffsetNotOk; + return NULL; +} + +/**************************************************************************** + * BOOL PASCAL Format20FileTooBig(iHeight, iWidth) + * + * purpose: Checks if the 2.0 font file size is within the 64k + * limit imposed by the 2.0 format offset table.( if file over + * size limit is saved in 2.0 format, loss of information will + * result) + * + * params: WORD iHeight : current height of font in pixels + * WORD iWidth : current width of font in pixels + * + * returns: TRUE : file too large + * FALSE : ok to save + * + * side effects: none + * + ***************************************************************************/ +BOOL PASCAL +Format20FileTooBig( + WORD iHeight, + WORD iWidth + ) +{ + if ((DWORD)lSizeOfOldFontHeader + (DWORD)cTable + + (font.LastChar - font.FirstChar +1) + * (((DWORD)iHeight * (DWORD)iWidth ) >> 3) >= WORD_LIMIT) + return TRUE; + return FALSE; +} + +/**************************************************************************** + * BOOL APIENTRY ReSizeProc(hDial, message, wParam, lParam) + * + * purpose : dialog fn. which verifies and accepts font resize (stretch, + * shrink...) input and calls the appropriate routine to perform + * the function. Also alters font weight attributes (bold, light, + * extra light...) + * + * params : same as for all dialog functions + * + * side effects: alters header information regarding font dimensions and font + * weight + * + ***************************************************************************/ +BOOL APIENTRY +ReSizeProc( + HWND hDial, + WORD message, + WPARAM wParam, + LONG lParam + ) +{ + FontHeaderType FAR * lpFont; + BOOL fOk; /* for GetDlgItemInt errors! */ + UINT i; + HMENU hMenu; + static BOOL fFV; /* temporary fixed/var width flag */ + + UNREFERENCED_PARAMETER(lParam); + + lpFont = (FontHeaderType FAR *)&font; + switch (message) + { + case WM_INITDIALOG: + fMsgBoxUp = FALSE; + newWeight = (WORD) font.Weight; + newFV = (BOOL) (font.Family & 1); + fFV = newFV; + SetFixed(hDial, fFV); /* Set Fixed or Variable width */ + SetDlgItemInt(hDial, ID_PIX_HEIGHT, lpFont->PixHeight, FALSE); + SetDlgItemInt(hDial, ID_FIRST_CHAR, lpFont->FirstChar, FALSE); +#ifdef JAPAN + if (!fFV) + SetDlgItemInt(hDial, ID_WIDTH, lpFont->AvgWidth, FALSE); + else + SetDlgItemInt(hDial, ID_WIDTH, lpFont->MaxWidth, FALSE); +#else + SetDlgItemInt(hDial, ID_WIDTH, lpFont->MaxWidth, FALSE); +#endif + SetDlgItemInt(hDial, ID_AVERAGE, lpFont->AvgWidth, FALSE); + SetDlgItemInt(hDial, ID_LAST_CHAR, lpFont->LastChar, FALSE); + SetWeight(hDial); + SetFixed(hDial, fFV); + break; + + case WM_COMMAND: + switch (GET_WM_COMMAND_ID(wParam, lParam)) + { + case ID_THIN: + newWeight = FW_THIN; + SetWeight(hDial); + break; + case ID_EXTRALIGHT: + newWeight = FW_EXTRALIGHT; + SetWeight(hDial); + break; + case ID_LIGHT: + newWeight = FW_LIGHT; + SetWeight(hDial); + break; + case ID_NORMAL: + newWeight = FW_NORMAL; + SetWeight(hDial); + break; + case ID_MEDIUM: + newWeight = FW_MEDIUM; + SetWeight(hDial); + break; + case ID_BOLD: + newWeight = FW_BOLD; + SetWeight(hDial); + break; + case ID_SEMIBOLD: + newWeight = FW_SEMIBOLD; + SetWeight(hDial); + break; + case ID_EXTRABOLD: + newWeight = FW_EXTRABOLD; + SetWeight(hDial); + break; + case ID_HEAVY: + newWeight = FW_HEAVY; + SetWeight(hDial); + break; + + case ID_FIXED: + fFV = 0; + SetFixed(hDial, fFV); + break; + case ID_VARIABLE: + fFV = 1; + SetFixed(hDial, fFV); + break; + + case IDOK: + fChanged = TRUE; + font.Weight = newWeight; + /* give warning if user attempts to change from variable to + fixed width */ + if ((fFV == 0) && (newFV != 0)) + { + fMsgBoxUp = TRUE; + ErrorBox(hDial, vszNoVarToFixChange); + fMsgBoxUp = FALSE; + SetFocus(GetDlgItem(hDial, ID_VARIABLE)); + break; + } + else + newFV = fFV; + + if (newFV && !(font.Family & 1)) + { + font.PixWidth = 0; /* All we need to do to make this */ + font.Family |= 1; /* .. font variable width */ + } + /* change height command */ + i = GetDlgItemInt(hDial, ID_PIX_HEIGHT, (LPBOOL)&fOk, FALSE); + if (fOk && i && i < kBoxLim && i>0 ) + { + if (i != font.PixHeight){ /* Same size ? */ + /* No: Resize body height */ + if (!ResizeBody(font.WidthBytes, i)){ + SetFocus(hDial); + break; + } + } + } + else{ + ErrorBox(hDial, vszHeightOutOfBounds); + SetFocus(GetDlgItem(hDial, ID_PIX_HEIGHT)); + break; + } + + /* change width command */ + i = GetDlgItemInt(hDial, ID_WIDTH, (LPBOOL)&fOk, FALSE); + if (fOk && i < wBoxLim && i > 0){ +#ifdef JAPAN + int kki; + kki = (newFV) ? font.MaxWidth : font.AvgWidth; + if (i != (UINT)kki){ + if (newFV){ + if (!SpreadWidths(i)){ + SetFocus(hDial); + break; /* new variable widths */ + } + } + else{ + if (!ResizeWidths(i)){ + SetFocus(hDial); + break; /* new fixed widths */ + } + } + } +#else + if (i != font.MaxWidth){ + if (newFV){ + if (!SpreadWidths(i)){ + SetFocus(hDial); + break; /* New Variable Widths */ + } + } + else{ + if (!ResizeWidths(i)){ + SetFocus(hDial); + break; /* New Fixed Widths */ + } + } + } +#endif + } + else{ + ErrorBox(hDial, vszWidthOutOfBounds); + SetFocus(GetDlgItem(hDial, ID_WIDTH)); + break; + } + + /* new first char command */ + i = GetDlgItemInt(hDial, ID_FIRST_CHAR, (LPBOOL)&fOk, FALSE); + if (fOk) + { + if ((i <= font.LastChar) && (i <= font.DefaultChar)) + { + if (i != font.FirstChar) + { + if (!NewFirstChar(i)) + break; + iChar = jChar = (CHAR) i; + swH = 0; + ScrollFont(); /* Show front end */ + } + } + else{ + ErrorBox(hDial, vszChar1MoreThanDChar); + SetFocus(GetDlgItem(hDial, ID_FIRST_CHAR)); + break; + } + } + else{ + ErrorBox(hDial, vszChar1NotOk); + SetFocus(GetDlgItem(hDial, ID_FIRST_CHAR)); + break; + } + + + /* new last char command */ + i = GetDlgItemInt(hDial, ID_LAST_CHAR, (LPBOOL)&fOk, FALSE); + if (fOk && i < 256) + { + if ((i >= font.FirstChar) && + (i >= font.DefaultChar)) + { + if (i != font.LastChar) + { + if (!NewLastChar(i)) + break; + iChar = jChar = (CHAR) i; + swH = 100; + ScrollFont(); /* Show back end */ + } + } + else{ + ErrorBox(hDial, vszLastCharTooSmall); + SetFocus(GetDlgItem(hDial, ID_LAST_CHAR)); + break; + } + } + else{ + ErrorBox(hDial, vszLastCharNotOk); + SetFocus(GetDlgItem(hDial, ID_LAST_CHAR)); + break; + } + + /* this is moved from SetFixed, since it should only be done + * if idok pressed. */ + if (newFV) + { /* Enable "width" if variable-width font */ + hMenu = GetMenu(hBox); + EnableMenuItem(hMenu, 4, MF_BYPOSITION | MF_ENABLED); + DrawMenuBar(hBox); + } + + /* fall thru to enddialog...*/ + + case IDCANCEL: + EndDialog(hDial, wParam != IDCANCEL); + break; + + default: + return FALSE; + break; + } /* end switch wParam */ + + default: + return FALSE; + } /* end switch message */ + + return TRUE; +} + +VOID +ErrorBox( + HWND hWndparent, + CHAR * szMessage + ) + /* Show Message Box */ +{ + MessageBox(hWndparent, (LPSTR)szMessage, (LPSTR)szAppName, + MB_OK | MB_ICONASTERISK | MB_APPLMODAL); +} + +/**************************************************************************** + * SetCharSet(hDial) + * + * purpose : Set ANSI/OEM dialog button and set the number in edit window + * + * param : HWND hDial : handle to dialog box window + * + * returns : none + * + ***************************************************************************/ +VOID +SetCharSet( + HWND hDial + ) +{ + CheckDlgButton(hDial, ID_ANSI, (WORD) (newCharSet == ANSI_CHARSET)); + CheckDlgButton(hDial, ID_SYMBOL, (WORD) (newCharSet == SYMBOL_CHARSET)); + CheckDlgButton(hDial, ID_OEM, (WORD) (newCharSet == OEM_CHARSET)); +#ifdef JAPAN + CheckDlgButton(hDial, ID_SHIFTJIS, newCharSet == SHIFTJIS_CHARSET); +#endif + SetDlgItemInt(hDial, ID_CHAR_SET, newCharSet, FALSE); +} + +/**************************************************************************** + * SetFixed(hDial) + * + * purpose : Set fixed/variable dialog button + * + * params : HWND hDial : handle to dialog box window + * BOOL fFV : variable or fixed + * + * returns : none + * + ***************************************************************************/ +VOID +SetFixed( + HWND hDial, + BOOL fFV + ) +{ + CheckDlgButton(hDial, ID_FIXED, (WORD)(fFV == 0)); + CheckDlgButton(hDial, ID_VARIABLE, (WORD)(fFV == 1)); + if (newFV) + SetDlgItemText(hDial, ID_WIDTH_TEXT, (LPSTR)vszMaxWidth); + else + SetDlgItemText(hDial, ID_WIDTH_TEXT, (LPSTR)vszCharPixelWidth); +} + +/**************************************************************************** + * SetWeight(hDial) + * + * purpose : Set font weight dialog button + * + * params : HWND hDial : handle to dialog box window + * + * returns : none + * + ****************************************************************************/ +VOID +SetWeight( + HWND hDial + ) +{ + CheckDlgButton(hDial, ID_THIN, (WORD)(newWeight == FW_THIN)); + CheckDlgButton(hDial, ID_EXTRALIGHT, (WORD)(newWeight == FW_EXTRALIGHT)); + CheckDlgButton(hDial, ID_LIGHT, (WORD)(newWeight == FW_LIGHT)); + CheckDlgButton(hDial, ID_NORMAL, (WORD)(newWeight == FW_NORMAL)); + CheckDlgButton(hDial, ID_MEDIUM, (WORD)(newWeight == FW_MEDIUM)); + CheckDlgButton(hDial, ID_SEMIBOLD, (WORD)(newWeight == FW_SEMIBOLD)); + CheckDlgButton(hDial, ID_BOLD, (WORD)(newWeight == FW_BOLD)); + CheckDlgButton(hDial, ID_EXTRABOLD, (WORD)(newWeight == FW_EXTRABOLD)); + CheckDlgButton(hDial, ID_HEAVY, (WORD)(newWeight == FW_HEAVY)); +} + +/**************************************************************************** + * SetFamily(hDial) + * + * purpose : Set font family dialog button + * + * params : HWND hDial : handle to dialog box window + * + * returns : none + * + ***************************************************************************/ +VOID +SetFamily( + HWND hDial + ) +{ + CheckDlgButton(hDial, ID_UNKNOWN, (WORD) (newFamily == 0)); + CheckDlgButton(hDial, ID_ROMAN, (WORD)(newFamily == 1)); + CheckDlgButton(hDial, ID_SWISS, (WORD)(newFamily == 2)); + CheckDlgButton(hDial, ID_MODERN, (WORD)(newFamily == 3)); + CheckDlgButton(hDial, ID_SCRIPT, (WORD)(newFamily == 4)); + CheckDlgButton(hDial, ID_DECORATIVE, (WORD) (newFamily == 5)); +} diff --git a/private/sdktools/fontedit/fontload.c b/private/sdktools/fontedit/fontload.c new file mode 100644 index 000000000..9b3cea983 --- /dev/null +++ b/private/sdktools/fontedit/fontload.c @@ -0,0 +1,1971 @@ +#include "windows.h" +#include <port1632.h> +#include "fontedit.h" +#include "fcntl.h" +#include "memory.h" +#include "stdio.h" +#include "commdlg.h" + + +/****************************************************************************/ +/* Shared Variables */ +/****************************************************************************/ +extern CHAR *PASCAL VerifyHeaderContents();/* checks integrity of header */ + +extern FontHeaderType font; /* Structure of Font File Header */ +extern LONG lSizeOfOldGlyph20; /* Old packed 2.0 glyph info size. */ +extern LONG lSizeOfOldGlyph30; /* Old packed 3.0 glyph info size. */ +extern LONG lSizeOfOldFontHeader; /* Old packed font header size. */ +extern LONG lSizeOfOldFontHeader30; /* Old 3.0 packed font header size. */ +extern CHAR szFaceName[]; /* Face Name of Font */ +extern DWORD offsets[]; /* Offsets Table */ + +extern BOOL fReadOnly; +extern BOOL fChanged; /* Note if we did anything */ +extern BOOL fLoaded; /* Set if a font is loaded */ +extern INT iFontFormatPrev; /* Set to the id of prev.font format */ +extern INT iFontFormat; /* Set to the id of current font format */ + +extern HWND hFont; /* Handle to Show window */ +extern HWND hBox; /* Handle to Edit Window */ +extern HDC hMemDC; /* Handle to Memory Display Context */ +extern HBITMAP hBitmap; /* Handle to our work bit map */ +extern CHAR matBox [wBoxLim] [kBoxLim]; /* array to hold Box */ + +extern CHAR *vrgsz[]; /* string table */ +extern OFSTRUCT ofstrFile; +extern BOOL NewFile; /* flag indicating if file was opened + by selecting NEW on menu */ +FontHeaderType fontBuffer; /* temporary buffer of Font File Header */ +WORD cHeader, cTable; +HFILE nNewFile; /* NT file handle */ + + +/****************************************************************************/ +/* Local Variables */ +/****************************************************************************/ + +DWORD Proport(DWORD, DWORD, DWORD, DWORD); /* Reproportions a value */ + +CHAR HUGE_T *lpFontBody = NULL; /* Pointer to Font Body */ +CHAR HUGE_T *lpWork = NULL; /* Pointer to Work Area */ +HDC hNewMemDC; +HDC hBoxMemDC; +HBITMAP hNewBitmap; +HBITMAP hBoxBitmap; +HCURSOR hOldCursor = NULL; /* Holds Arrow while we show Hourglass */ +HCURSOR hHourGlass = NULL; +DWORD oldMode; /* For StretchBltMode */ +BYTE HUGE_T *lp1, HUGE_T *lp2; /* Pointers to bitmaps in format N */ + +FontHeader30 font30; + +#define ALPHA_CNT 26 +#define TOTAL_WEIGHTS 1000 +#define FSF_FIXED 0x0001 +#define FSF_PROPORTIONAL 0x0002 + +SHORT widthweights[ALPHA_CNT + 1] = + { + 64, /* a + 14, /* b */ + 27, /* c */ + 35, /* d */ + 100, /* e */ + 20, /* f */ + 14, /* g */ + 42, /* h */ + 63, /* i */ + 3 , /* j */ + 6 , /* k */ + 35, /* l */ + 20, /* m */ + 56, /* n */ + 56, /* o */ + 17, /* p */ + 4 , /* q */ + 49, /* r */ + 56, /* s */ + 71, /* t */ + 31, /* u */ + 10, /* v */ + 18, /* w */ + 3 , /* x */ + 18, /* y */ + 2 , /* z */ + 166, /* space, must be last, to use with the following + code */ + }; + +/****************************************************************************/ +/* Local Functions */ +/****************************************************************************/ + +VOID NewAverage(VOID); +BOOL GetNewMap(DWORD, DWORD); +VOID UseNewMap(VOID); +VOID ShrinkFont(DWORD, DWORD); + +/**************************************************************************** + * WORD ConvertToBitmapFormat(width, phase, height) + * + * purpose : Takes a part of the font file and converts it to a string of + * bytes for a single scan of bitmap for a character. + * + * params : WORD width : width of the character in pixels(bits) + * WORD phase : current deviation from byte alignment (pixels) + * WORD height: height of character(pixels) + * + * returns : WORD phase : new deviation from byte alignment (pixels) + * + * side effects : modifies pointers lp1 and lp2 (pointing to work space and + * font body respectively) + * + ****************************************************************************/ +DWORD PASCAL +ConvertToBitmapFormat( + DWORD width, /* width of the character in pixels(bits) */ + DWORD phase, /* current deviation from byte alignment (pixels) */ + DWORD height /* height of character(pixels) */ + ) +{ + INT w; + WORD j; + + /* in the font file format characters are stored consecutively in + column-major ordering (columns of char 1 followed by columns of char + 2 ... etc.). lp2 points to start of columns of current character. + lp1 points to start of row of bitmap for character. */ + + for (w = width; w > 0; w -= 8){ + if (phase == 0){ + /* easy case */ + *lp1++ = *lp2; + + if (w < 8) + phase = w; + } + else{ + + --lp1; + j = (WORD)*lp1; + j <<= 8; + j |= (((WORD)*lp2) << (8 - phase)); + *lp1++ = (BYTE)(j >> 8); + *lp1++ = (BYTE)j; + if (w < 8){ + phase += w; + if (phase <= 8) + lp1--; /* back up pointer */ + phase &= 7; + } + } + lp2 += height; /* move to next column */ + } + return phase; +} + +/**************************************************************************** + * char * VerifyTableContents() + * + * purpose : scan the offsets table of file just read and check if + * width and offsets lie within limits + * + * params : none + * + * returns : char * szError : ptr to Error message if table not OK + * NULL otherwise + * + * side effects : none + * + ****************************************************************************/ +CHAR * PASCAL +VerifyTableContents( + VOID + ) +{ + PBYTE pjGlyphData; + GLYPHINFO_20 gi2T20; /* temp ptr to a 2.0 style table*/ + GLYPHINFO_30 gi3T30; /* temp ptr to a 2.0 style table*/ + INT i; + + /* separate loops written for the 2.0 and 3.0 font processing because + a single loop would involve too many checks (of font type) within + the loop and slow down processing */ + if (iFontFormat == ID_FORMAT2){ + pjGlyphData = (lpFontBody +1); + + /* view table as 2.0 table */ + + /* check that each and every width and offset lie within limits */ + + for (i=0; i < (fontBuffer.LastChar - fontBuffer.FirstChar + 1); i++) { + + vGlyphInfo20FromBuffer (pjGlyphData, &gi2T20); + + if (gi2T20.GIwidth > 64) + return vszTableWidthsBad; + + if ((gi2T20.GIoffset > (UINT)WORD_LIMIT) || + (gi2T20.GIoffset < 0) ) + return vszTableOffsetsBad; + + pjGlyphData += lSizeOfOldGlyph20; + } + } + else{ + + pjGlyphData = lpFontBody; + + /* view table as 3.0 table */ + /* check that each and every width and offset lie within limits */ + + for (i=0; i< (fontBuffer.LastChar - fontBuffer.FirstChar +1); i++) { + + vGlyphInfo30FromBuffer (pjGlyphData, &gi3T30); + + if (gi3T30.GIwidth > 64) + return vszTableWidthsBad; + + if (gi3T30.GIoffset < (DWORD)0) + return vszTableOffsetsBad; + + pjGlyphData += lSizeOfOldGlyph30; + } + } + return NULL; +} + +/**************************************************************************** + * char * FontLoad() + * + * purpose: reads in the specified font file and creates a work bitmap for + * the editor. Also creates a local bitmap-offset table for easy + * access to the characters in the bitmap + * + * params : pszFileName - File Name to open. + * + * returns: ptr to NULL string if Open goes off OK + * ptr to error message string otherwise + * + * side effects: lots + * + ****************************************************************************/ +CHAR * +FontLoad( + CHAR *pszFileName, + OFSTRUCT *pofsReOpenInfo + ) +{ + + CHAR HUGE_T *lpFontBodySav = NULL; /* local pointer to font body */ + DWORD len, fontlen; /* length of font body (bytes)*/ + UINT i; + INT mf; /* menu function ID */ + DWORD iWorkLen; /* length of work area (bytes) */ + HDC hDC; + CHAR * pszError; /* error msg if header is messed up */ + + DWORD row, height, width,phase; + DWORD offset; + GLYPHINFO_20 gi2GlyphTable20; /* Pointer into 2.0 style offsets table */ + GLYPHINFO_30 gi3GlyphTable30; /* Pointer into 3.0 style offsets table */ + PBYTE pjGlyphData; /* Pointer to Glyph information buffer. */ + + BYTE cDummy [CCHEXTRA]; /* dummy buffer for unneeded 3.0 header + * info + */ + + /* Put up an hourglass ... this may take a while */ + if (!hHourGlass) + hHourGlass = LoadCursor(NULL, IDC_WAIT); /* Get Hourglass */ + hOldCursor = SetCursor(hHourGlass); /* Show hourglass */ + + /* open file for read. */ + nNewFile = MOpenFile (pszFileName, pofsReOpenInfo, OF_READ); + + if (nNewFile < 0) { + + return vszErrorOpeningFile; + } + + //- ReadFile: Here is where we need to make some adjustments in order to + //- read the file in to a new DWORD aligned format. + { + BYTE jBuffer [200]; + + + /* Read the header */ + if (_lread ((HFILE) nNewFile, (LPSTR)&jBuffer, lSizeOfOldFontHeader) != + (UINT)lSizeOfOldFontHeader) { + + M_lclose(nNewFile); + return vszErrorReadingHdr; + } + + // + // Call conversion routine to give us a properly aligned buffer. + // + + vFontStructFromBuffer ( + (PBYTE)&jBuffer, + &fontBuffer + ); + + } + + /* Check the version number -- make sure it's a font */ + switch (fontBuffer.Version) + { + case 0x200: + iFontFormat = ID_FORMAT2; + break; + case 0x300: /* added 1/19/88 */ + iFontFormat = ID_FORMAT3; + /* read in the extra fields into a dummy buffer ... they don't + * mean anything to us at this stage. + */ + if ((M_lread(nNewFile, (LPSTR)cDummy, CCHEXTRA)) + != CCHEXTRA){ + M_lclose(nNewFile); + return vszErrorReadingHdr; + } + + break; + default: /* Anything else -- toughies */ + M_lclose(nNewFile); + return vszUnknownFormat; + } + + /* check if contents of font header are sensible. If not, + give an error message and quit */ + + if ((pszError = VerifyHeaderContents()) != NULL) { + + M_lclose(nNewFile); + return pszError; + } + + /* Ready to load -- Check if we will be overwriting */ + if (fLoaded) + { + DeleteBitmap(); + fLoaded = FALSE; + } + + /* Allocate space for font body and Face Name and read them in */ + len= (fontBuffer.Size - lSizeOfOldFontHeader); /* Compute size */ + + if ((lpFontBody = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, (LONG)len)) == 0) { + + M_lclose(nNewFile); + return vszNotEnoughMem; /* Get Handle to space */ + } + + if (iFontFormat == ID_FORMAT3) + fontlen = len - CCHEXTRA; + else + fontlen = len; + + lpFontBodySav = lpFontBody; /* save ptr to font body */ + while (fontlen >= (DWORD)SEGMENT_SIZE) { + + /* file read method if font file size is 64k bytes or greater. + file is read in in chunks of 65536 (SEGMENT_SIZE), taking care to + position buffer ptr at 64k boundary each time */ + + /* First read in the maximum number of bytes _lread can read (65534) */ + if ((M_lread(nNewFile, lpFontBodySav, WORD_LIMIT)) == WORD_LIMIT) { + + lpFontBodySav += WORD_LIMIT; /* buffer ptr moved up by 64k bytes */ + fontlen -= WORD_LIMIT; /* fontlen = no of bytes left to read */ + + } else { + + GlobalFree (lpFontBody); + M_lclose(nNewFile); + return vszErrorReadingBody; + } + + /* read in an additional two bytes to reach end of segment */ + if ((M_lread(nNewFile, lpFontBodySav, 2)) == 2) { + + lpFontBodySav += 2; /* buffer ptr moved up by 2 bytes */ + fontlen -= 2; /* fontlen = no of bytes left to read */ + + } else { + + GlobalFree (lpFontBody); + M_lclose(nNewFile); + return vszErrorReadingBody; + } + } + + /* read the partially filled segment */ + if ((_lread((HFILE)nNewFile, lpFontBodySav, (DWORD)fontlen)) != (UINT) fontlen) { + + GlobalFree (lpFontBody); + M_lclose (nNewFile); + return vszErrorReadingBody; + } + + /* Close the file */ + M_lclose (nNewFile); + + /* check if the offset table entries are within allowable limits. + If not give an error message, clean up and quit */ + if ((pszError = VerifyTableContents()) != NULL) { + + GlobalFree (lpFontBody); + return pszError; + } + + /* now that everything has been checked, move buffer to font */ + font = fontBuffer; + + /* Make local copies of FaceName and Device Name */ + if (font.Face){ + + lstrcpy((LPSTR)szFaceName, lpFontBody + font.Face - + (iFontFormat == ID_FORMAT2 ? + lSizeOfOldFontHeader : + lSizeOfOldFontHeader30-1)); + } else { + + lstrcpy((LPSTR)szFaceName, (LPSTR)""); + } + + for (i = 0; i <= 256; i++) /* Zero offsets Table for below */ + offsets[i] = 0; + + /* compute work space needed if a 3.0 file. This has to be done since + 3.0 files are compressed versions of 2.0 files and may need a + work bitmap bigger than the actual font body size */ + + if (iFontFormat == ID_FORMAT3) { + + cTable = (WORD) (6 * (font.LastChar - font.FirstChar + 2)); + iWorkLen = 0; + + pjGlyphData = lpFontBody; + + /* work bitmap size = sum of sizes of all characters in font */ + + for (i = font.FirstChar; i <= font.LastChar; i++) { + + vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); + + iWorkLen += ((gi3GlyphTable30.GIwidth +7) >> 3) * font.PixHeight; + + pjGlyphData += lSizeOfOldGlyph30; + } + + } else { /* 2.0 file */ + + cTable = (WORD)(4 * (font.LastChar - font.FirstChar + 2)); + /* compute table length */ + iWorkLen = len; /* work space for a 2.0 file is the same as the + length of the font body */ + } + + //- Add some extra space for dword alignment. + iWorkLen += (font.PixHeight * sizeof (DWORD)); + /* Get work space */ + + if ((lpWork = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (LONG)iWorkLen)) == 0) { + + GlobalFree (lpFontBody); + return vszNotEnoughMem; + } + + lp1 = lpWork; + + height = (DWORD) font.PixHeight; + offset = 0; + /* put the font file into bitmap format */ + if (iFontFormat == ID_FORMAT2){ /* table in 2.0 format */ + for (row = 0; row < height; row++){ + + /* view table as a 2.0 style table */ + pjGlyphData = lpFontBody + 1; + + phase = 0; + + for (i = 0; i < (UINT)(font.LastChar - font.FirstChar + 1); i++) { + + vGlyphInfo20FromBuffer (pjGlyphData, &gi2GlyphTable20); + + width = (DWORD) gi2GlyphTable20.GIwidth; + + /* size of each table element = 4bytes */ + lp2 = lpFontBody + (gi2GlyphTable20.GIoffset - + lSizeOfOldFontHeader) + row; + + pjGlyphData += lSizeOfOldGlyph20; + + /* offset ends up as the sum of the widths */ + if (row == 0) /* Once is enough */ + offsets[i + font.FirstChar + 1] = offset += width; + + /* create a single scan of bitmap for character */ + phase = ConvertToBitmapFormat (width, phase, height); + } + if ((lp1 - lpWork) & 1) + *lp1++ = 0; /* Round lp1 up to Word Boundary */ +#ifdef DWORDROUND + if ((lp1 - lpWork) & 2) { + *lp1++ = 0; /* Round lp1 up to DWord Boundary */ + *lp1++ = 0; /* Round lp1 up to DWord Boundary */ + } +#endif + //if (((offset + 7) >> 3) & 1) + //*lp1++ = 0; /* Round lp1 up to Word Boundary */ + //if (((offset + 7) >> 3) & 2) { + //*lp1++ = 0; /* Round lp1 up to DWord Boundary */ + //*lp1++ = 0; /* Round lp1 up to DWord Boundary */ + //} + } + } + /* separate loops written for the 2.0 and 3.0 font processing because + a single loop would involve too many checks (of font type) within + the loop and slow down processing */ + else { /* table in 3.0 format */ + + for (row = 0; row < height; row++){ + + phase = 0; + /* view table as a 3.0 style table */ + pjGlyphData = lpFontBody; + + for (i = 0; i < (UINT)(font.LastChar - font.FirstChar + 1); i++) { + + vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); + + width = gi3GlyphTable30.GIwidth; + + /* size of each table element = 6bytes */ + lp2 = lpFontBody + (gi3GlyphTable30.GIoffset - + lSizeOfOldFontHeader30 +1) + row; + + pjGlyphData += lSizeOfOldGlyph30; + + /* offset ends up as the sum of the widths */ + if (row == 0) /* Once is enough */ + offsets[i + font.FirstChar + 1] = offset += width; + + /* create a single scan of bitmap for character */ + phase = ConvertToBitmapFormat (width, phase, height); + } + if ((lp1 - lpWork) & 1) + *lp1++ = 0; /* Round lp1 up to Word Boundary */ +#ifdef DWORDROUND + if ((lp1 - lpWork) & 2) { + *lp1++ = 0; /* Round lp1 up to DWord Boundary */ + *lp1++ = 0; /* Round lp1 up to DWord Boundary */ + } +#endif + } + } + font.WidthBytes = (WORD) CJ_DIB_SCAN(offset); + /* fixup NEWFON error */ + + GlobalFree(lpFontBody); + lpFontBody = lpWork; /* So that below we free the other buffer */ + /* Create a WINDOWS bitmap to move the font definition bits into */ + + hDC = GetDC (hFont); /* DC to be compatible with */ + hBitmap = CreateBitmap( + (INT)font.WidthBytes << 3, /* Width of font in pixels */ + (INT)font.PixHeight, + 1, 1, (LPBYTE)NULL); + hMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + SelectObject(hMemDC, hBitmap); /* Relate the two of them */ + ReleaseDC(hFont, hDC); /* Done with font DC */ + + /* Move the bits in */ + SetBitmapBits(hBitmap, + (DWORD)font.WidthBytes * (DWORD)font.PixHeight,(CHAR HUGE_T *)lpWork); + + /* Free up the space we loaded the file into */ + GlobalFree(lpFontBody); + fLoaded = TRUE; + { + HMENU hMenu; + + hMenu = GetMenu(hBox); /* Gray menu if no clipboard bitmap */ + mf = (font.Family & 1) ? MF_ENABLED : MF_GRAYED; + EnableMenuItem(hMenu, FONT_SAVE, MF_ENABLED); + EnableMenuItem(hMenu, FONT_SAVEAS, MF_ENABLED); + EnableMenuItem(hMenu, 1, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, 4, MF_BYPOSITION | mf); + EnableMenuItem(hMenu, 5, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, 6, MF_BYPOSITION | MF_ENABLED); + DrawMenuBar(hBox); + } + SetCursor(hOldCursor); /* Restore regular cursor */ + return ""; +} + +/************************************** + * compares nBytes bytes of s1 and s2 * + **************************************/ +BOOL +ByteCompare ( + CHAR HUGE_T *s1, + CHAR HUGE_T *s2, + DWORD nBytes + ) +{ + for ( ; nBytes > 0; nBytes--) + if (*s1++ != *s2++) + return FALSE; + return TRUE; +} + +/*********************************** + * copies nBytes bytes of s2 to s1 * + ***********************************/ +BOOL +ByteCopy( + CHAR HUGE_T *s1, + CHAR HUGE_T *s2, + LONG nBytes + ) +{ + for ( ; nBytes > 0; nBytes--) + *s1++ = *s2++; + return TRUE; +} + +/**************************************************************************** + * VOID ConvertToFileFormat(width, phase, height) + * + * purpose : Takes a part of the bitmap (corresponding to a single character) + * and converts it to a string of bytes in the font file format + * + * params : WORD width : width of the character in pixels(bits) + * WORD phase : current deviation from byte alignment (pixels) + * WORD height: height of character(pixels) + * + * returns: WORD phase : new deviation from byte alignment (pixels) + * + * side effects : modifies pointers lp1 and lp2 (pointing to font body and work + * space respectively) + * + ****************************************************************************/ +DWORD PASCAL +ConvertToFileFormat( + DWORD width, + DWORD phase, + DWORD height + ) +{ + INT w; + + for (w = width; w > 0; w -= 8){ /* for each byte of font */ + if (phase == 0){ /* easy case */ + + BYTE b; + + b = *lp1++; + if (w < 8){ + + phase = (DWORD) w; + b >>= 8 - w; /* Clear left side bits */ + b <<= 8 - w; + } + *lp2 = b; + } + else{ + + DWORD j; + + lp1--; /* Re-read byte prevously read */ + //j = (DWORD) ((BYTE)*lp1++ << 8) | ((BYTE)*lp1++); + j = (DWORD)((BYTE)*lp1++ << 8); + j |= (DWORD) ((BYTE)*lp1++); + if (w < 8){ + + j >>= 16 - phase - (w & 7); /* shove it right */ + j <<= 8 - (w & 7); /* Left justify in low byte */ + phase += (DWORD) w; + if (phase <= 8) + lp1--; /* back up pointer */ + phase &= 7; + } + else + j >>= 8 - phase; + *lp2 = (BYTE)j; + } + lp2 += height; /* move to next column */ + } + return phase; +} + +/**************************************************************************** + * char * FontSave() + * + * purpose: saves the work bitmap in the required font file format (2.0 or + * 3.0 and cleans up + * + * params : none + * + * returns: ptr to a NULL string if Save goes off OK + * ptr to error message string otherwise + * + * side effects: lots + * + ****************************************************************************/ + +CHAR * +FontSave( + CHAR *pszFileName, + OFSTRUCT *pofsReOpenInfo + ) +{ + DWORD bytecount; /* number of bytes returned by lwrite */ + DWORD size; /* total size of font */ + + WORD height, row; + DWORD i, fontlen; + DWORD cBody, cFont,cFontsav, cFace; + CHAR *lpFont; /* ponter to font body */ + CHAR * sz; + DWORD iMax; + WORD widthsav; + PBYTE pjGlyphData; + PBYTE pjGlyphSave; + GLYPHINFO_20 gi2GlyphTable20; /* 2.0 style Glyph data struct */ + GLYPHINFO_30 gi3GlyphTable30; /* 3.0 style Glyph data struct */ + + NewAverage(); /* force ave width to be recomputed 8/17/87 BobM */ + + /* reset file pointer */ + nNewFile = MOpenFile (pszFileName, pofsReOpenInfo, OF_WRITE | OF_REOPEN); + + if (nNewFile < (HFILE) 0) { + + return vszErrorOpeningFile; + } + + /* Put up an houglass ... this may take a while */ + if (!hHourGlass) + hHourGlass = LoadCursor (NULL, IDC_WAIT); /* Get Hourglass */ + hOldCursor = SetCursor (hHourGlass); /* Show hourglass */ + + height = font.PixHeight; + cBody = (DWORD)height * (DWORD)font.WidthBytes; + + /* Recompute file size and update header */ + if (iFontFormat == ID_FORMAT2) + cHeader = (WORD)(lSizeOfOldFontHeader +1); + else + cHeader = (WORD)(lSizeOfOldFontHeader30 - 1); + + /* if of 2.0 type, check if size will exceed 64kbytes. If yes, saving + in 2.0 format will result in loss of information (because offset table + of 2.0 file is composed of 16bit words). Warn user and ask if file can + be saved as a 3.0 file */ + + if (iFontFormat == ID_FORMAT2) + { + if (((DWORD)cHeader + (DWORD)(lSizeOfOldGlyph20 * (font.LastChar - + font.FirstChar+2)) + (DWORD)cBody) >= WORD_LIMIT) + if (MessageBox(hBox, vszTooBigFor20, vszWarning, + IDOK | IDCANCEL |IDNO) == IDYES) + iFontFormat = ID_FORMAT3; + } + + if (iFontFormat == ID_FORMAT2) { + + /* allocate space for a 2.0 style offsets table */ + cTable = (WORD)(lSizeOfOldGlyph20 * + (font.LastChar - font.FirstChar + 2)); + + } else { + + /* allocate space for a 3.0 style offsets table */ + cTable = (WORD)(lSizeOfOldGlyph30 * + (font.LastChar - font.FirstChar + 2)); + } + + pjGlyphData = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (DWORD)cTable); + + if (pjGlyphData == 0) { + + M_lclose (nNewFile); + return vszNotEnoughMem; + } + + pjGlyphSave = pjGlyphData; + + size = cHeader + cTable; + iMax = font.LastChar - font.FirstChar + 1; + +#ifdef JAPAN + // Recreate maximum character width when the font is proportional + // since the WIDTH.. command may grow maxwidth but may not reduce. + if (font.Family & 1) + font.MaxWidth = 0; +#endif + /* create offsets table of font file */ + for (i = 0; i <= iMax; i++){ + + DWORD width, charSize; + + width = offsets[i + font.FirstChar + 1] - offsets[i + font.FirstChar]; + + if (i == iMax) { + width = 8; /* Sentinal blank */ + } + + if (iFontFormat == ID_FORMAT2){ + + gi2GlyphTable20.GIwidth = (SHORT)width; + gi2GlyphTable20.GIoffset = (SHORT)size; + + vBufferFromGlyphInfo20 (&gi2GlyphTable20, pjGlyphData); + + pjGlyphData += lSizeOfOldGlyph20; + + } else { + + gi3GlyphTable30.GIwidth = (SHORT)width; + gi3GlyphTable30.GIoffset = (INT)size; + + vBufferFromGlyphInfo30 (&gi3GlyphTable30, pjGlyphData); + + pjGlyphData += lSizeOfOldGlyph30; + } + +#ifdef JAPAN // DBCS_FIX + // update max width + if(font.Family & 1 ) { + if(width > font.MaxWidth ) + font.MaxWidth = (WORD)width ; + } + if(i == 0x81 && font.CharSet == SHIFTJIS_CHARSET) { + if(width * 2 > font.MaxWidth) { + font.MaxWidth = (WORD)width * 2 ; + } + } +#endif + charSize = height * ((width + 7) >> 3); /* size in bytes */ + + if ((size + charSize) < size){ /* Overflow? */ + + GlobalFree (pjGlyphData); + M_lclose (nNewFile); + return vszFileTooLarge; + + } + size += charSize; + } + + /* Update stuff in the header */ + + font.Face = (DWORD)size; + cFace = (WORD)lstrlen (szFaceName) + 1; /* Allow for \0 */ + size += cFace; + font.Size = (DWORD)size; /* new file size */ + font.BitsOffset = (DWORD)(cHeader + cTable); + font.Device = (DWORD)NULL; /* Device Name must be NULL */ + cFontsav = size - cHeader - cTable; + cFont =cFontsav; + + /* alloc extra byte for lp1 in case it needs it */ + if (!(lpFontBody = (LPSTR)GlobalAlloc (GMEM_ZEROINIT, (LONG)cBody + + height * 4))) { + + M_lclose (nNewFile); + return vszNotEnoughMem; + } + + GetBitmapBits (hBitmap, (DWORD)cBody, lpFontBody); + + /* save current WidthBytes */ + widthsav = font.WidthBytes; + + /* MD - reset WidthBytes from computed width */ + font.WidthBytes = (WORD) (cFont - cFace)/ height; + + /* Allocate a block to put bitmap into */ + if ((lpFont = lpWork = GlobalAlloc (GMEM_ZEROINIT,(LONG)cFont)) == 0) + { + GlobalFree (lpFontBody); + M_lclose (nNewFile); + return vszNotEnoughMem; + } + + lp1 = lpFontBody; + + /* convert bitmap to file format */ + if (iFontFormat == ID_FORMAT2){ /* offsets table in 2.0 format */ + INT nChars; + nChars = font.LastChar - font.FirstChar +1; + + for (row = 0; row < height; row++){ + + DWORD phase; + + phase = 0; + + pjGlyphData = pjGlyphSave; + + for (i = 0; i < (DWORD) nChars; i++) { + + INT width; + + vGlyphInfo20FromBuffer (pjGlyphData, &gi2GlyphTable20); + + width = gi2GlyphTable20.GIwidth; + + lp2 = (BYTE HUGE_T *)(lpWork + (gi2GlyphTable20.GIoffset - + cHeader - cTable + row)); + + pjGlyphData += lSizeOfOldGlyph20; + + phase = ConvertToFileFormat (width, phase, height); + } + if ((lp1 - lpWork) & 1) + lp1++; /* Round lp1 up to Word Boundary */ +#ifdef DWORDROUND + if ((lp1 - lpWork) & 2) { + lp1++; /* Round lp1 up to DWord Boundary */ + lp1++; /* Round lp1 up to DWord Boundary */ + } +#endif + //if(((offsets[font.LastChar + 1] + 7) >> 3) & 1) + //lp1++; /* Round lp1 up to Word Boundary */ + } + } + /* separate loops written for the 2.0 and 3.0 font processing because + a single loop would involve too many checks (of font type) within + the loop and slow down processing */ + else{ /* table in 3.0 format */ + + INT nChars; + nChars = font.LastChar - font.FirstChar +1; + for (row = 0; row < height; row++){ + + DWORD phase; + + phase = 0; + pjGlyphData = pjGlyphSave; + + for (i = 0; i < (DWORD) nChars; i++) { + + INT width; + + vGlyphInfo30FromBuffer (pjGlyphData, &gi3GlyphTable30); + + width = gi3GlyphTable30.GIwidth; + + lp2 = (BYTE HUGE_T *)(lpWork + (gi3GlyphTable30.GIoffset - + cHeader - cTable + row)); + + pjGlyphData += lSizeOfOldGlyph30; + + phase = ConvertToFileFormat (width, phase, height); + } + if ((lp1 - lpWork) & 1) + lp1++; /* Round lp1 up to Word Boundary */ +#ifdef DWORDROUND + if ((lp1 - lpWork) & 2) { + lp1++; /* Round lp1 up to DWord Boundary */ + lp1++; /* Round lp1 up to DWord Boundary */ + } +#endif + //if(((offsets[font.LastChar + 1] + 7) >> 3) & 1) + //lp1++; /* Round lp1 up to Word Boundary */ + } + } + + /* Restore start of data. */ + pjGlyphData = pjGlyphSave; + + lp2 -= height - 1; /* Back up to start of character */ + for (i = 0; i < height; i++) + *lp2++ = 0; /* Fill in guaranteed blank character */ + + font.Version = 0x200; + + /****** code for compaction in 3.0 fmt borrowed from CMPCTFON ******/ + if (iFontFormat== ID_FORMAT3){ + DWORD iDefBitmapSize = 0; /* size of default char */ + DWORD cch = 0; /* count of number of default char */ +#if 0 + GLYPHINFO_30 HUGE_T *cur_char; /* current element of offset table */ + GLYPHINFO_30 HUGE_T *move_char; + /* element from which moving is to be done */ + LONG iDefBitmapOffset; /* offset of default char */ + INT iDefBitmapWidth; /* width of default char */ + static LONG iEndOfBitmaps; /* address of end of font body */ + INT iFirstC; /* first char in font */ + INT iLastC; /* last char in font */ + INT i,j; + WORD width; + CHAR HUGE_T *rgbFont; /* pointer to font body */ + DWORD Offset; + + GDI seems to understand compressed 2.0 external formats but not + compressed 3.0 formats, and this is causing it to crash loading a 3.0 + format compressed font. Since compression does not affect the + validity of the font, This code is disabled temporarily till + this problem is verified. Again, the font is perfectly usable in this + form, though a trifle bigger than desired - LR 20/26/90 + + + Note that this will now not work after the conversion to NT. + the glyph table needs to accessed as above. t-davema 8/20/91 + + iFirstC = font.FirstChar & 0x0ff; + iLastC = font.LastChar & 0x0ff; + + iEndOfBitmaps = (LONG)font.BitsOffset+((LONG)font.WidthBytes * + (LONG)font.PixHeight); + rgbFont = (CHAR HUGE_T *)lpFont; /* start of font body */ + cur_char =(GLYPHINFO_30 HUGE_T *) lpTable; /* start of offset table */ + + /* calculate some parameters for the default char */ + iDefBitmapOffset = cur_char[font.DefaultChar].GIoffset; + iDefBitmapWidth = cur_char[font.DefaultChar].GIwidth; + iDefBitmapSize = (DWORD)cur_char[font.DefaultChar+1].GIoffset + - (DWORD)iDefBitmapOffset; + + /* scan the font body via the offsets table. If a default char + is recognised, move all the bytes to it's right left by the + size of the default char.Make all offset table entries of default + char point to one image of the char (the earliest occuring image) */ + for (i = iFirstC; i <= iLastC; ++i) { + + /* important: Check for limiting conditions (in case break char + was modified?)*/ + if (cur_char->GIoffset == iDefBitmapOffset){ + cur_char++; + continue; + } + + Offset = cur_char->GIoffset -cHeader -cTable; + /* proceed to compare images only if widths are equal */ + if ((cur_char->GIwidth == iDefBitmapWidth) && + (ByteCompare (&rgbFont [Offset], + &rgbFont[iDefBitmapOffset-cHeader-cTable], + (DWORD)iDefBitmapSize) == TRUE)){ + + /* set offset to earliest occurence of the default char */ + if (cur_char->GIoffset < iDefBitmapOffset){ + iDefBitmapOffset = cur_char->GIoffset; + } + else { + if (i != iLastC){ + /* move bytes to right of default char left by the + size of the char */ + ByteCopy (&rgbFont [ Offset], + &rgbFont [ Offset+ iDefBitmapSize], + (LONG)(iEndOfBitmaps - + ((cur_char + 1)->GIoffset))); + + /* correct the offset table entries */ + move_char = cur_char + 1; + for (j=i; j < iLastC; ++j){ + move_char->GIoffset -= (LONG)iDefBitmapSize; + move_char++; + } + } + iEndOfBitmaps -= iDefBitmapSize; + /* move End-of-font to the left */ + cur_char->GIoffset = iDefBitmapOffset; + /* point offset of cuurent char to default char */ + cch++; + } + } + cur_char++; + } +#endif + /* recalculate some font attributes */ + lp2 -= (cch * iDefBitmapSize + height); + for (i = 0; i < height; i++) + *lp2++ = 0; /* Fill in guaranteed blank character */ + + cFont -= cch * iDefBitmapSize; + font.WidthBytes = (WORD) (cFont - cFace)/ height; + font.Size = (DWORD) (cFont + cHeader + cTable); + font.Face = font.Size - cFace ; + font.Version = 0x300; + + /* copy info into 3.0 (new) format header and set the additional + fields */ + ByteCopy ((LPSTR)&font30, (LPSTR)&font, (DWORD)sizeof (font)); + font30.fsFlags = 0; + font30.fsFlags = (font.Family & 1 ? FSF_PROPORTIONAL : FSF_FIXED); + font30.fsAspace = 0; + font30.fsBspace = 0; + font30.fsCspace = 0; + font30.fsColorPointer = 0L; + for (i = 0; i < 4 ; i++) + font30.fsReserved[i] = 0L; + } + + /* Add the FaceName, if any, to the end of the bitmap */ + lstrcpy((LPSTR)lp2, (LPSTR)szFaceName); + + /* + * Again we need to do some tricky things to get the header output + * correct. We want to run it through the conversion backwards until + * we get the packed structure. + */ + { + BYTE jOutputBuffer [sizeof (font30)]; + + if (iFontFormat == ID_FORMAT2) { + + vBufferFromFontStruct (&font, (PBYTE)&jOutputBuffer); + + } else { + + vBufferFromFont30Struct (&font30, (PBYTE)&jOutputBuffer); + } + + bytecount = M_lwrite (nNewFile, (PBYTE)&jOutputBuffer, (DWORD)cHeader); + } + + /* Write out Header Information */ + if (bytecount == cHeader) { + + /* Write out OffsetsTable */ + if (cTable == 0 || (_lwrite((HFILE)nNewFile, pjGlyphData, (DWORD)cTable) + == (UINT)cTable)){ + /* Write out Body */ + fontlen = cFont; + while (fontlen >= SEGMENT_SIZE){ + + /* file write method if font size is 64k or greater + file is written in chunks of 65536 bytes (SEGMENT_SIZE)-lr */ + + /* First write as many bytes as _lwrite will allow(65534) */ + if (M_lwrite(nNewFile, (CHAR HUGE_T *)lpFont, WORD_LIMIT) == + WORD_LIMIT){ + fontlen -= WORD_LIMIT; + /* fontlen = no of bytes left to write*/ + lpFont+= WORD_LIMIT; /* buffer ptr moved up by 64k */ + } + else + sz = vszErrorWritingBody; + + /* write the two bytes remaining in the segment */ + if (M_lwrite(nNewFile, (CHAR HUGE_T *)lpFont, 2) == 2){ + fontlen -= 2; /* fontlen = no of bytes left to write*/ + lpFont+= 2; /* buffer ptr moved up by 2 */ + } + else + sz = vszErrorWritingBody; + } + /* segment only partially filled. Write the remaining bytes */ + if (_lwrite((HFILE)nNewFile, (CHAR HUGE_T *)lpFont, (DWORD)fontlen) == + (UINT) fontlen){ + fChanged = FALSE; + sz= ""; + } + else + sz = vszErrorWritingBody; + } + else + sz = vszErrorWritingOffsets; + } + else + sz = vszErrorWritingHdr; + + /* hack: Restore saved value of widthbytes, eliminating a variety + of minor scrolling problems that follow after a File/Save */ + font.WidthBytes = widthsav; + + M_lclose (nNewFile); + + /* Tidy up */ + + GlobalFree(lpFontBody); + GlobalFree(pjGlyphData); + GlobalFree(lpWork); + + SetCursor(hOldCursor); /* Restore regular cursor */ + + return sz; +} + +/**************************************************************************** + * BOOL ResizeWidths(wChar) + * + * params : WORD wChar : new width of a single character + * + * purpose: resize work bitmap according to new character width by stretching/ + * compressing all characters as neccesary + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + ****************************************************************************/ + + +BOOL +ResizeWidths( + DWORD wChar + ) +{ + DWORD width; + DWORD offset, i; + + /* Create a new bitmap to move the font definition bits into */ + width = (font.LastChar - font.FirstChar + 1) * wChar; /* In pixels */ + width = CJ_DIB_SCAN(width); + if (!GetNewMap(width, font.PixHeight)) + return (FALSE); + + /* Move the bits in */ + offset = 0; + oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); + for (i = font.FirstChar; i <= font.LastChar; i++) + { + + StretchBlt(hNewMemDC, offset, 0, + wChar, font.PixHeight, /* New character */ + hMemDC, offsets[i], 0, + font.PixWidth, font.PixHeight, /* Old character */ + SRCCOPY); + offsets[i] = offset; + offset += wChar; + } + SetStretchBltMode(hNewMemDC, oldMode); + offsets[font.LastChar + 1] = offset; + + UseNewMap(); /* Switch Pointers and release the space */ + + font.HorizRes = (WORD) Proport(font.HorizRes, wChar, font.PixWidth, 999); + font.WidthBytes = (WORD) width; /* Misc. ajustments */ + font.PixWidth = font.AvgWidth = (font.MaxWidth = (WORD) wChar); + +#ifdef JAPAN + font.MaxWidth = (WORD) wChar * 2; // set MaxWidth as DBCS width. +#endif + + return (TRUE); +} + + +/**************************************************************************** + * BOOL SpreadWidths(wChar) + * + * purpose: spread/compress work bitmap (with variable width characters) + * in proportion with the maximum character width + * + * params : WORD wChar : new width of a character + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + ****************************************************************************/ + +BOOL +SpreadWidths( + DWORD wChar + ) +{ + DWORD offset, i; + DWORD width, oldWidth, newWidths[257]; + + /* Create a new bitmap to move the font definition bits into */ + width = 0; /* Compute the new width */ + for (i = (DWORD) font.FirstChar; i <= (DWORD) font.LastChar; i++) + { + oldWidth = offsets[i + 1] - offsets[i]; + /* Compute new width to nearest whole number */ + newWidths[i] = Proport(oldWidth, wChar, font.MaxWidth, wBoxLim - 1); + width += newWidths[i]; + } + width = CJ_DIB_SCAN(width); + if (!GetNewMap(width, font.PixHeight)) + return(FALSE); + + /* Move the bits in */ + offset = 0; + oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); + for (i = font.FirstChar; i <= font.LastChar; i++) + { + oldWidth = offsets[i + 1] - offsets[i]; + StretchBlt(hNewMemDC, offset, 0, + newWidths[i], font.PixHeight, /* New character */ + hMemDC, offsets[i], 0, + oldWidth, font.PixHeight, /* Old character */ + SRCCOPY); + offsets[i] = offset; + offset += newWidths[i]; + } + SetStretchBltMode(hNewMemDC, oldMode); + offsets[font.LastChar + 1] = offset; + + UseNewMap(); /* Switch Pointers and release the space */ + font.HorizRes = (WORD) Proport(font.HorizRes, wChar, font.MaxWidth, 999); + font.WidthBytes = (WORD) width; /* Misc. ajustments */ + font.MaxWidth = (WORD) wChar; + NewAverage(); /* Compute new average width */ + + return (TRUE); +} + + +/**************************************************************************** + * NewAverage() + * + * purpose: recalculate average width of a character in font + * + * params : none + * + * returns: none + * + * side effects: alters the average width parameter in font header + * + ****************************************************************************/ +VOID +NewAverage( + VOID + ) +{ +#ifdef FOO + WORD i, totalwidth; + /* 12/23/85 -- use weighted avg of lower case letters (mikecr) */ + + /* width of the space */ + totalwidth = (offsets[' ' + 1] - offsets[' ']) * widthweights[ALPHA_CNT]; + + for (i = 0; i < ALPHA_CNT; i++) + totalwidth += (offsets['a' + i + 1] - offsets['a' + i]) * + widthweights[i]; + + font.AvgWidth = totalwidth / TOTAL_WEIGHTS; + + /* round up if necessary */ + if (totalwidth % TOTAL_WEIGHTS >= (TOTAL_WEIGHTS >> 1)) + font.AvgWidth++; + +#endif + + /* lets do a simple average here */ + font.AvgWidth = (WORD) (((offsets[font.LastChar+1] - + offsets[font.FirstChar]) + (font.LastChar - font.FirstChar)/2) / + (font.LastChar - font.FirstChar + 1)); + + if (font.AvgWidth == 0) { + font.AvgWidth++; + } +#ifdef JAPAN + if (font.AvgWidth < 1) { + font.AvgWidth = 1; + } +#endif +} + + +/**************************************************************************** + * BOOL ResizeBody(width, height) + * + * purpose: adjust work bitmap according to new specified dimensions + * + * params : WORD width : new width of font in pixels + * WORD height : new height of font in pixels + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + ****************************************************************************/ + +BOOL +ResizeBody( + DWORD width, + DWORD height + ) +{ + + /* Create a new bitmap to move the font definition bits into */ + if (!GetNewMap(width, height)) + return(FALSE); + + /* Move the bits in */ + oldMode = SetStretchBltMode(hNewMemDC, COLORONCOLOR); + StretchBlt(hNewMemDC, 0, 0, + width << 3, height, /* New Char. */ + hMemDC, 0, 0, + width << 3, font.PixHeight, /* Old Char. */ + SRCCOPY); + SetStretchBltMode(hNewMemDC, oldMode); + + UseNewMap(); /* Switch Pointers and release the space */ + + font.ExtLeading = (WORD) Proport(font.ExtLeading, height, font.PixHeight, 999); + font.IntLeading = (WORD) Proport(font.IntLeading, height, font.PixHeight, 999); + font.Ascent = (WORD) Proport(font.Ascent, height, font.PixHeight, 32); + font.VertRes = (WORD) Proport(font.VertRes, height, font.PixHeight, 999); + font.Points = (WORD) Proport(font.Points, height, font.PixHeight, 999); + font.PixHeight = (WORD) height; /* Fix misc. header values */ + font.WidthBytes = (WORD) width; + + return (TRUE); +} + + +/**************************************************************************** + * BOOL NewFirstChar(first) + * + * purpose: redefines first character in font and resizes work bitmap + * accordingly + * + * params : WORD first : new first character to be defined + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + ****************************************************************************/ + +BOOL +NewFirstChar( + DWORD first + ) +{ + DWORD width, wDefault; + DWORD offset, i; + INT dw; + + if (first > font.FirstChar) /* Smaller? */ + { + ShrinkFont(first, font.LastChar); + font.FirstChar = (BYTE) first; + /*return(FALSE);*/ + return(TRUE); + } + + /* If not smaller we must pad with the default character */ + wDefault = offsets[font.DefaultChar + 1] - offsets[font.DefaultChar]; + dw = wDefault * (font.FirstChar - first); /* Extra width */ + width = offsets[font.LastChar + 1] + dw; /* New width (pixels) */ + width = CJ_DIB_SCAN(width); + if (!GetNewMap(width, font.PixHeight)) + return(FALSE); /* New work area */ + + /* Move it in in two parts */ + /* First move in default characters */ + offset = 0; + for (i = first; i < font.FirstChar; i++) + { + BitBlt(hNewMemDC, offset, 0, + wDefault, font.PixHeight, + hMemDC, offsets[font.DefaultChar], 0, + SRCCOPY); + offsets[i] = offset; + offset += wDefault; + } + /* Now move in the rest */ + BitBlt(hNewMemDC, offset, 0, + offsets[font.LastChar + 1], font.PixHeight, + hMemDC, 0, 0, + SRCCOPY); + + UseNewMap(); /* Switch Pointers and release the space */ + + /* Now fix up offsets table */ + for (i = font.FirstChar; i <= (DWORD)(font.LastChar + 1); i++) + offsets[i] = offsets[i] + dw; /* Shift the rest right */ + font.WidthBytes = (WORD) width; + font.FirstChar = (BYTE) first; + + return (TRUE); +} + + +/**************************************************************************** + * ShrinkFont(first, last) + * + * purpose: redefine the first and last charcter in the font and shrink + * work bitmap accordingly + * + * params : WORD first : new first character to be defined + * WORD last : new last character " " " + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + ****************************************************************************/ + +VOID +ShrinkFont( + DWORD first, + DWORD last + ) +{ + DWORD width, widthPixels; + DWORD i; + INT dw; + + dw = offsets[first] - offsets[font.FirstChar]; /* left shift if any */ + widthPixels = offsets[last + 1] - offsets[first]; /* Width in pixels */ + width = CJ_DIB_SCAN(widthPixels); + if (!GetNewMap(width, font.PixHeight)) + return; /* New work area.*/ + + /* Now move the font into the reduced space */ + + BitBlt(hNewMemDC, 0, 0, + widthPixels, font.PixHeight, + hMemDC, offsets[first], 0, + SRCCOPY); + + UseNewMap(); /* Switch Pointers and release the space */ + + if (dw) /* Ajust offsets */ + { + for (i = first; i <= last + 1; i++) + offsets[i] -= dw; + } + + font.WidthBytes = (WORD) width; + +} + + +/**************************************************************************** + * BOOL NewLastChar(last) + * + * purpose: redefines the last character in the font + * + * params : WORD last : number of character to be made the last character + * + * returns: none + * + * side effects: Work bitmap changes.Some header info (regarding font dimensions + * altered as well + * + ****************************************************************************/ + +BOOL +NewLastChar( + DWORD last + ) +{ + DWORD width, wDefault; + DWORD offset, i; + INT dw; + + if (last < font.LastChar) /* Smaller? */ + { + ShrinkFont(font.FirstChar, last); + font.LastChar = (BYTE) last; + return(FALSE); + } + + /* If not smaller we must pad with the default character */ + wDefault = offsets[font.DefaultChar + 1] - offsets[font.DefaultChar]; + dw = wDefault * (last - font.LastChar); /* Extra width */ + offset = offsets[font.LastChar + 1]; /* Current end */ + width = offset + dw; /* New width (pixels) */ + width = CJ_DIB_SCAN(width); + if (!GetNewMap(width, font.PixHeight)) + return(FALSE); /* New work area */ + + /* Move it in in two parts */ + /* First move in the existing font */ + BitBlt(hNewMemDC, 0, 0, + offset, font.PixHeight, + hMemDC, 0, 0, + SRCCOPY); + /* Then move in default characters */ + for (i = font.LastChar + 1; i <= last;) + { + BitBlt(hNewMemDC, offset, 0, + wDefault, font.PixHeight, + hMemDC, offsets[font.DefaultChar], 0, + SRCCOPY); + offset += wDefault; + offsets[++i] = offset; + } + + UseNewMap(); /* Switch Pointers and release the space */ + + font.WidthBytes = (WORD) width; + font.LastChar = (BYTE) last; + + return (TRUE); +} + + +/**************************************************************************** + * BOOL CharWidth(iChar, wBox) + * + * purpose: resizes selected char according to new dimensions. (only for + * variable pitch) + * + * params : BYTE iChar : character to resize + * WORD wBox : new width of char in pixels + * + * returns: none + * + * side effects: work bitmap pixel values and header info(regarding font + * dimensions) altered + * + ****************************************************************************/ + +BOOL +CharWidth( + BYTE iChar, /* Character to change */ + DWORD wBox /* New width */ + ) +{ + DWORD width, nChars; + DWORD w1, w2, i; + INT dw; + + nChars = font.LastChar - font.FirstChar + 1; /* Character count */ + dw = wBox - (offsets[iChar + 1] - offsets[iChar]); /* Width change */ + width = offsets[font.LastChar + 1] + dw; /* New width (pixels) */ + width = CJ_DIB_SCAN(width); + if (!GetNewMap(width, font.PixHeight)) + return(FALSE); /* New work area */ + + /* Move it in in two parts */ + /* First move up to and including iChar */ + w1 = offsets[iChar + 1]; /* Width (in pixels) to move */ + BitBlt(hNewMemDC, 0, 0, + w1 + dw, font.PixHeight, + hMemDC, 0, 0, + SRCCOPY); + /* Now move in the rest */ + if (iChar < (BYTE) font.LastChar) /* Part to right of elision */ + { + w2 = offsets[font.LastChar + 1] - offsets[iChar + 1]; + BitBlt(hNewMemDC, offsets[iChar] + wBox, 0, + w2, font.PixHeight, + hMemDC, offsets[iChar + 1], 0, + SRCCOPY); + } + + UseNewMap(); /* Switch Pointers and release the space */ + + /* Now fix up offsets table */ + for (i = iChar + 1; /* Where changes start */ + i <= (DWORD)(font.LastChar + 1); i++) /* Ajust offsets */ + offsets[i] = offsets[i] + dw; /* .. by adding dw */ + font.WidthBytes = (WORD) width; + NewAverage(); + + return (TRUE); +} + +/**************************************************************************** + * BoxToClipboard(ptA, width, height) + * + * purpose: write char (or part of it) to clipboard + * + * params : POINT ptA : upper left coordinate + * DWORD width : width of char in pixels + * DWORD height : height of char in pixels + * returns: none + * + * side effects: none + * + ****************************************************************************/ +VOID +BoxToClipboard( + POINT ptA, /* Upper left point */ + DWORD width, + DWORD height /* Size */ + ) +{ + HDC hDC; + DWORD x, y; + + hDC = GetDC(hFont); /* DC to be compatible with */ + hNewBitmap = CreateBitmap( + width, height, + 1, 1, (LPBYTE)NULL); + hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ + ReleaseDC(hFont, hDC); /* Done with font DC */ + + for (x = 0; x < width; x++) + for (y = 0; y < height; y++) + SetPixel(hNewMemDC, x, y, matBox[x + ptA.x][y + ptA.y] == TRUE ? + BLACK : WHITE); + + /* Now wake up Clipboard and empty it */ + if (!OpenClipboard(hFont)) + ErrorBox(hBox, vszCannotOpenClip); // , vszCopyingToClip); + else /* Ok: We got the Clipboard */ + { + EmptyClipboard(); + SetClipboardData(CF_BITMAP, hNewBitmap); /* Tell Clipboard */ + } + + /* Tidy things up */ + CloseClipboard(); + DeleteDC(hNewMemDC); +} + + +/**************************************************************************** + * WORD ClipboardToBox(ptA, width, height, fFit) + * + * purpose: copies char (or part of char ) from clipboard to work bitmap + * stretching it if need be + * + * params : PIONT ptA : upper left coordinate + * DWORD width : width of char in pixels + * DWORD height : height of char in pixels + * BOOL fFit : flag to indicate if default width is to be used + * returns: none + * + * side effects: pixel values of bitmap may change for char + * + ****************************************************************************/ + +DWORD +ClipboardToBox( + POINT ptA, /* Upper left point */ + DWORD width, + DWORD height, /* Size */ + BOOL fFit /* Use default width if TRUE */ + ) +{ + BITMAP bitmap; + HDC hDC; + DWORD x, y; + HANDLE hT; + + if (!OpenClipboard(hFont)) { + ErrorBox(hBox, vszCannotOpenClip); + return 0; + } + hNewBitmap = GetClipboardData(CF_BITMAP); + + /* Check if we got something like a character */ + if (GetObject(hNewBitmap, sizeof(BITMAP), (LPSTR)&bitmap) != sizeof(BITMAP)) + { /* What did we get */ + ErrorBox(hBox, vszErrorClip); + CloseClipboard(); + return 0; + } + + + if (fFit && ((WORD)bitmap.bmWidth <= font.MaxWidth)) + width = bitmap.bmWidth; + + hDC = GetDC(hFont); /* DC to be compatible with */ + hBoxBitmap = CreateBitmap( + width, height, + 1, 1, (LPBYTE)NULL); + hBoxMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + hT = SelectObject(hBoxMemDC, hBoxBitmap); /* Relate them */ + if (hT == NULL || hDC == NULL || hBoxBitmap == NULL || hBoxMemDC == NULL) { + ErrorBox(hBox, vszErrorClip); + CloseClipboard(); + DeleteDC(hBoxMemDC); + DeleteObject(hBoxBitmap); + return 0; + } + + /* Get a DC to relate to the Bitmap we just got */ + hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + hT = SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ + ReleaseDC(hFont, hDC); /* Done with font DC */ + if (hT == NULL || hNewMemDC == NULL) { + ErrorBox(hBox, vszErrorClip); + CloseClipboard(); + DeleteDC(hNewMemDC); + DeleteDC(hBoxMemDC); + DeleteObject(hBoxBitmap); + return 0; + } + + /* Now StretchBlt whatever was on the clipboard into the character */ + oldMode = SetStretchBltMode(hBoxMemDC, COLORONCOLOR); + fFit = StretchBlt(hBoxMemDC, 0, 0, width, height, + hNewMemDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY); + if (!fFit || !oldMode) { + ErrorBox(hBox, vszErrorClip); + CloseClipboard(); + DeleteDC(hNewMemDC); + DeleteDC(hBoxMemDC); + DeleteObject(hBoxBitmap); + return 0; + } + (void)SetStretchBltMode(hBoxMemDC, oldMode); + for (x = 0; x < width; x++) + for (y = 0; y < height; y++) + matBox[x + ptA.x] [y + ptA.y] = (CHAR)(GetPixel(hBoxMemDC, x, y) ? + 0 : 1); + /* Tidy things up */ + DeleteDC(hNewMemDC); + DeleteDC(hBoxMemDC); + DeleteObject(hBoxBitmap); + CloseClipboard(); + return(width); +} + + +/**************************************************************************** + * ToClipboard(iChar, width, height) + * + * purpose: write char in edit box to clipboard + * + * params : BYTE iChar : number of char to be copied to clipboard + * DWORD width : width of char in pixels + * DWORD height : height of char in pixels + * + * returns: none + * + * side effects: none + * + ****************************************************************************/ + +VOID +ToClipboard( + BYTE iChar, + DWORD width, /* Here in Pixels */ + DWORD height /* Also in Pixels */ + ) +{ + HDC hDC; + + hDC = GetDC(hFont); /* DC to be compatible with */ + hNewBitmap = CreateBitmap( + width, /* Width of font in pixels */ + height, + 1, 1, (LPBYTE)NULL); + hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ + ReleaseDC(hFont, hDC); /* Done with font DC */ + + BitBlt(hNewMemDC, 0, 0, width, height, /* Move Character in */ + hMemDC, offsets[iChar], 0, NOTSRCCOPY); + + /* Now wake up Clipboard and empty it */ + if (!OpenClipboard(hFont)) + ErrorBox(hBox, vszCannotOpenClip); // , vszCopyingToClip); + else /* Ok: We got the Clipboard */ + { + EmptyClipboard(); + SetClipboardData(CF_BITMAP, hNewBitmap); /* Tell Clipboard */ + } + + /* Tidy things up */ + CloseClipboard(); + DeleteDC(hNewMemDC); +} + + +/**************************************************************************** + * GetNewMap(width, height) + * + * purpose: create new bitmap of the given width and height. + * + * params : WORD width : width of bitmap in pixels + * WORD height : height of bitmap in pixels + * + * returns: TRUE if successful, FALSE otherwise + * + * side effects: Handle and DC values of new DC assigned + * + ****************************************************************************/ + +BOOL +GetNewMap( + DWORD width, + DWORD height /* New size */ + ) +{ + HDC hDC; + + if (height==0) /* Check if something stupid is happening */ + height=font.PixHeight; /* Fix it */ + + /* Put up an houglass ... this may take a while */ + if (!hHourGlass) + hHourGlass = LoadCursor(NULL, IDC_WAIT); /* Get Hourglass */ + hOldCursor = SetCursor(hHourGlass); /* Show hourglass */ + + /* Create a new bitmap to move the font definition bits into */ + hDC = GetDC(hFont); /* DC to be compatible with */ + hNewBitmap = CreateBitmap( + width << 3, /* Width of font in pixels */ + height, + 1, 1, (LPBYTE)NULL); + if (!hNewBitmap) + { + ErrorBox(hBox, vszNotEnoughMem); // , vszAllocatingSpace); + ReleaseDC(hFont, hDC); /* bug# 2380 */ + return FALSE; + } + + hNewMemDC = CreateCompatibleDC(hDC); /* Create a DC */ + SelectObject(hNewMemDC, hNewBitmap); /* Relate them */ + ReleaseDC(hFont, hDC); /* Done with font DC */ + PatBlt(hNewMemDC, 0, 0, width << 3, height, BLACKNESS); /* Clear it */ + return TRUE; +} + + +/**************************************************************************** + * UseNewMap() + * + * params : none + * + * purpose: discard old bitmap and replace it with new one + * + * returns: none + * + * side effects: Handle to old bitmap and handle to old bitmap DC replaced + * by those of new bitmap respectively + * + ****************************************************************************/ + +VOID +UseNewMap( + VOID + ) +{ + DeleteDC(hMemDC); + DeleteObject(hBitmap); /* Release old space */ + hBitmap = hNewBitmap; + hMemDC = hNewMemDC; /* Release old space */ + SetCursor(hOldCursor); /* Restore regular cursor */ +} + + + +VOID +DeleteBitmap( + VOID + ) +{ + if (hMemDC) + DeleteDC(hMemDC); + if (hBitmap) + DeleteObject(hBitmap); +} + + +DWORD +Proport( + DWORD value, + DWORD top, + DWORD bottom, + DWORD limit + ) + /* Reproportion a value by the ratio top/bottom to the nearest integer + * and make sure we are still in range */ +{ + return min(limit, (DWORD)((1 + 2 * value * top) / (2 * bottom))); +} diff --git a/private/sdktools/fontedit/lio.h b/private/sdktools/fontedit/lio.h new file mode 100644 index 000000000..d379d3d71 --- /dev/null +++ b/private/sdktools/fontedit/lio.h @@ -0,0 +1,14 @@ +INT APIENTRY OpenPathname( LPSTR, INT ); +INT APIENTRY DeletePathname( LPSTR ); +INT APIENTRY +++HFILE+++M_lopen(LPSTR, INT); +VOID APIENTRY M_lclose(+++HFILE+++INT); +INT APIENTRY +++HFILE+++M_lcreat(LPSTR, INT);; +BOOL APIENTRY _ldelete( LPSTR ); +WORD APIENTRY _ldup( INT ); +DWORD APIENTRY M_llseek(+++HFILE+++INT, LONG, +++WPARAM+++INT); +WORD APIENTRY M_lread(+++HFILE+++INT, LPSTR, +++WPARAM+++INT); +WORD APIENTRY M_lwrite(+++HFILE+++INT, LPSTR, +++WPARAM+++INT); + +#define READ 0 /* Flags for _lopen */ +#define WRITE 1 +#define READ_WRITE 2 diff --git a/private/sdktools/fontedit/makefile b/private/sdktools/fontedit/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/sdktools/fontedit/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/sdktools/fontedit/sources b/private/sdktools/fontedit/sources new file mode 100644 index 000000000..892436f98 --- /dev/null +++ b/private/sdktools/fontedit/sources @@ -0,0 +1,45 @@ +!IF 0 + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +!ENDIF + +MAJORCOMP=sdktools +MINORCOMP=fontedit + +TARGETNAME=fontedit +TARGETPATH=obj +TARGETTYPE=LIBRARY +TARGETLIBS= + +INCLUDES=. +GPSIZE=32 + +C_DEFINES=-DWIN32 + +SOURCES= FONTCHAR.C \ + FONTEDIT.C \ + FONTEDIT.RC \ + FONTHEAD.C \ + FONTLOAD.C \ + FONTDLG.C \ + FONTCVT.C \ + TYPECVT.C + +UMTYPE=windows +UMAPPL=fontedit +UMENTRY=winmain +UMLIBS=obj\*\fontedit.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + obj\*\fontedit.res diff --git a/private/sdktools/fontedit/typecvt.c b/private/sdktools/fontedit/typecvt.c new file mode 100644 index 000000000..649b07482 --- /dev/null +++ b/private/sdktools/fontedit/typecvt.c @@ -0,0 +1,1357 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + typecvt.c + +Abstract: + + Routines for generically converting between structure formats without + regard to alignment boundries. + +Author: + + David J. Marsyla (t-davema) 22-Jul-1991 + +Revision History: + + +--*/ + + +#include "windows.h" +#include <port1632.h> +#include "typecvt.h" + +// We want to assert errors for now. +#define ASSERT_ERRORS + +#ifdef ASSERT_ERRORS +int sprintf (); +int exit (); +#endif + +// +// For lack of any place better to put a general description of the type +// conversion functions, The following will attempt to explain what is +// needed set up for, and use, the functions. +// +// The main purpose of these functions is to convert non-aligned structures +// to aligned structures and back again. +// +// In order to convert bewteen two structures it is first necessary to define +// what each one looks like. This is done most easily by statically allocating +// and array of StructDefineInfo or SDI structures. Here is an example: +// +// The two structures +// struct struct +// { { +// CHAR chElem1; LONG rglElem2 [10]; +// WORD rgwElem2 [5]; ULONG ulElem1; +// } src; } dest; +// could be described by. +// +// SDI rgsdiSrcStructDef [] = { +// { sizeof (CHAR), sizeof (src.chElem1) }, +// { sizeof (WORD), sizeof (src.rgwElem2) }, +// { 0, 0 } }; +// +// SDI rgsdiDestStructDef [] = { +// { sizeof (LONG), sizeof (dest.rglElem2) }, +// { sizeof (ULONG), sizeof (dest.ulElem1) }, +// { 0, 0 } }; +// +// Once both structures have been defined the conversion between the structures +// in different alignments and endian types can be performed with +// PerformConversion (). +// +// For an example of how this is implemented see Fontcvt.c +// + + +// +// An advantage of the conversions routines is that they are a portable +// method of handling machines with Big Endian integer storage. See header +// file typecvt.h for complete description of big and little endian. +// +// The folowing variables are used to select the endian type of the source +// and the destination structures. The default is Little Endian. +// Also, these are not meant to be accessed outside of this module. +// Routines have been defined to access these. +// + +INT vfFileEndianType = CVT_FILE_ENDIAN_DEFAULT; +INT vfSysEndianType = CVT_ENDIAN_UNKNOWN; // Set to unknown. + + +LONG +lCalculateStructOffsets ( + PSDI rgsdiStructDefine, + INT fAlignmentType, + INT cSizeOfStruct + ) + +/*++ + +Routine Description: + + This function is used to calculate the offsets of each element in the + Struct Define Info array. These values are stored back int the SDI array + which was passed to us. The offsets are based on the alignment type + sent to this routine. It will also return the sizeof that structure as + it would be with the alignment or -1 if there is an error. + +Arguments: + + rgsdiStruceDefine - Definition of this structure as an array of SDI + structures. Note, see beginning of this file for + a complete description of how to define this + structure. + + fAlignmentType - This is an optional parameter which can be used to + request the count of bytes for a particular alignment + CVT_ALIGN_PACKED - Return the sizeof the structure + if the alignment were packed. + CVT_ALIGN_WORD - Return the sizeof the structure + if the alignment were WORD aligned. + CVT_ALIGN_DWORD - Return the sizeof the structure + if the alignment were DWORD aligned. + Zero or any other value, return 0 on success. + + cSizeOfStruct - This value is used only for error detection. + It should be the size of the structure you are + converting in the current system alignment. + (ex. sizeof (FontHeaderType)). The function will + compare this to it's calculate offset and return + an error if they differ. + Note that if this value is 0, no error checking will + be performed. + +Return Value: + + Postitive Value = The total size of the structure we are looking at. + This should be the same as if we did a sizeof (struct) in the + proper alignment. + -1 = There was an error with the definition of the structure. + Here is how errors are detected. Along with determining all of + the offsets in the specified alignment type, it will also do it + in CVT_ALIGN_SYSTEM. If the system alignment does not match the + initial offsets, an error is reported. + +--*/ + + +{ + LONG oPackedOffset = 0; // Counter for packed offset. + LONG oWordOffset = 0; // Counter for WORD aligned offset. + LONG oDWordOffset = 0; // Counter for DWORD aligned offset. + + // + // Make sure that the system endian type has been computed. + // We will probably need this for calls to PerformConversion. + // + + if (vfSysEndianType == CVT_ENDIAN_UNKNOWN) { + + vfSysEndianType = fDetermineSysEndianType (); + } + + // + // Keep looping while there are defined elements. + // + + while (rgsdiStructDefine->cTypeSize) { + + // + // Make sure we are aligned to either the type boundry or the + // alignment count, whichever is smaller. + // + + if (rgsdiStructDefine->cTypeSize >= 2) { + + oWordOffset += (oWordOffset & 1); // Make sure both are on + oDWordOffset += (oDWordOffset & 1); // a WORD boundry. + } + + if (rgsdiStructDefine->cTypeSize >= 4) { + + // Add 2 to the DWORD alignment if it is not on a DWORD boundry. + // Note that the previous check would already have WORD aligned it. + + oDWordOffset += (oDWordOffset & 2); + + } + + // + // Store the offset to that element within the structure itsself. + // + + rgsdiStructDefine->oPackedAlign = oPackedOffset; + rgsdiStructDefine->oWordAlign = oWordOffset; + rgsdiStructDefine->oDWordAlign = oDWordOffset; + + // + // Increase by actual size of the element. + // + + oPackedOffset += rgsdiStructDefine->cActualSize; + oWordOffset += rgsdiStructDefine->cActualSize; + oDWordOffset += rgsdiStructDefine->cActualSize; + + rgsdiStructDefine++; + } + + // + // Be sure that the structure fits within alignement. + // Add word and DWORD padding accordingly. + // + + oWordOffset += (oWordOffset & 1); + oDWordOffset += (oDWordOffset & 1); + oDWordOffset += (oDWordOffset & 2); + + // + // Check to see if we successfully reached the end of the structure array. + // We assume that they have sent us a sizeof(struct) in system alignment. + // If not then return an error, -1. Otherwise, everything is fine so + // return the sizeof the structure we just got. + // Note we only do it if they have given us something to compare. + // + + if (cSizeOfStruct) { + + switch (CVT_ALIGN_SYSTEM) { + + case CVT_ALIGN_PACKED: + if (cSizeOfStruct != oPackedOffset) { + return (-1); + } + break; + + case CVT_ALIGN_WORD: + if (cSizeOfStruct != oWordOffset) { + return (-1); + } + break; + + case CVT_ALIGN_DWORD: + if (cSizeOfStruct != oDWordOffset) { + return (-1); + } + break; + } + } + + // + // Check and see what type of stucture they want us to return to + // them. Generally on NT it will be the packed value they want. + // + + switch (fAlignmentType) { + + case CVT_ALIGN_PACKED: + return (oPackedOffset); + + case CVT_ALIGN_WORD: + return (oWordOffset); + break; + + case CVT_ALIGN_DWORD: + return (oDWordOffset); + break; + + default: + return (0); + } +} + + +VOID +vPerformConversion ( + PSDI rgsdiStructDefine, + PBYTE pjSrcBuffer, + INT fSrcAlignment, + INT fSrcEndianType, + PBYTE pjDestBuffer, + INT fDestAlignment, + INT fDestEndianType + ) + +/*++ + +Routine Description: + + WARNING: CalcStructureOffsets must have previously been called with + rgsdiStructDesc as it's argument. + + This function is the heart of the generic conversion system. It steps + through the (PSDI) structure definition array and converts each element + from the source buffer to the destination buffer. To do this it uses the + precomputed offset information stored in the structure definition. + Also, if the source endian type is different from the destination, it + will swap all data in the transfer. + +Arguments: + + rgsdiStruceDefine - Definition of this structure as an array of SDI + structures. Note, see beginning of this file for + a complete description of how to define this + structure. + + pjSrcBuffer - This is a pointer to the source strucure in memory. + This structure does not need to be aligned. + + fSrcAlignment - This is the alignment of the source structure. + The permissible values of this field are: + CVT_ALIGN_PACKED - structure is packed. + CVT_ALIGN_WORD - structure is WORD aligned. + CVT_ALIGN_DWORD - structure is DWORD aligned. + CVT_ALIGN_SYSTEM - use system default alignment. + + fSrcEndianType - This is the byte ordering of the source data. + The permissible values of this field are: + CVT_LITTLE_ENDIAN - data is little endian format. + CVT_BIG_ENDIAN - data is big endian format. + CVT_ENDIAN_FILE - use current file endian type. + CVT_ENDIAN_SYSTEM - use current system endian type. + + pjDestBuffer - This is a pointer to the destination structure. + This structure does not need to be aligned. + + fDestAlignment - This is the alignment of the source structure. + The permissible values of this field: Same as above. + + fDestEndianType - This is the byte ordering of the source data. + The permissible values of this field: Same as above. + +Return Value: + + None. Any detectable errors would have been found in the initialization + of the SDI structure. + +--*/ + +{ + register PSDI rgsdiStrDef = rgsdiStructDefine; + INT *poSrcAlign; + INT *poDestAlign; + PBYTE pjSrc; + PBYTE pjDest; + + // + // Get the alignment pointers set to the proper offset into the + // structure. Here is the general trick we use here. First we set the + // offset pointer to the start of the structure array. We then find out + // what offset into that structure will point us to the alignment type + // we want. After that, since we have an array we just add the sizeof + // the SDI struct to the pointer and it will give us the next offset. + // + + poSrcAlign = (INT *)rgsdiStrDef; + + switch (fSrcAlignment) { + + case CVT_ALIGN_PACKED: + ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign - + (CHAR *)rgsdiStrDef); + break; + + case CVT_ALIGN_WORD: + ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign - + (CHAR *)rgsdiStrDef); + break; + + case CVT_ALIGN_DWORD: + ((CHAR *)poSrcAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign - + (CHAR *)rgsdiStrDef); + break; + } + + // + // Same with dest. + // + + poDestAlign = (INT *)rgsdiStrDef; + + switch (fDestAlignment) { + + case CVT_ALIGN_PACKED: + ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oPackedAlign - + (CHAR *)rgsdiStrDef); + break; + + case CVT_ALIGN_WORD: + ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oWordAlign - + (CHAR *)rgsdiStrDef); + break; + + case CVT_ALIGN_DWORD: + ((CHAR *)poDestAlign) += ((CHAR *)&rgsdiStrDef->oDWordAlign - + (CHAR *)rgsdiStrDef); + break; + } + + + if (fSrcEndianType == fDestEndianType) { + + INT cTotalCount; + + // + // Keep converting while there exists elements with a valid convert + // structure. + // + + while (rgsdiStrDef->cTypeSize) { + + // + // Store the actual size we need to transfer. Also, store the + // pointers to the offsets within the current structures. + // + + cTotalCount = rgsdiStrDef->cActualSize; + pjSrc = pjSrcBuffer + *poSrcAlign; + pjDest = pjDestBuffer + *poDestAlign; + + // + // MemCpy the bytes, probably faster to do it inline. + // + + while (cTotalCount--) { + + *pjDest++ = *pjSrc++; + } + + // + // Now we step our three pointers to the next structure in + // the array. + // + + ((CHAR *)poSrcAlign) += sizeof (SDI); + ((CHAR *)poDestAlign) += sizeof (SDI); + rgsdiStrDef++; + } + + } else { + + INT cArrayCount; + INT cElemSize; + INT wT; + + + // + // Keep converting while there exists elements with a valid convert + // structure. + // + + while (rgsdiStrDef->cTypeSize) { + + cArrayCount = rgsdiStrDef->cActualSize / rgsdiStrDef->cTypeSize; + + // + // Store the actual size we need to transfer. Also, store the + // pointers to the offsets within the current structures. + // + + cElemSize = rgsdiStrDef->cActualSize; + pjSrc = pjSrcBuffer + *poSrcAlign; + pjDest = pjDestBuffer + *poDestAlign; + + // + // Handle each array element seperately. + // + + while (cArrayCount--) { + + for (wT = 1; wT <= cElemSize; wT++) { + + // + // Copy in reverse order. + // + + *pjDest++ = *(pjSrc + (cElemSize - wT)); + } + + pjSrc += cElemSize; + } + + // + // Now we step our three pointers to the next structure in + // the array. + // + + ((CHAR *)poSrcAlign) += sizeof (SDI); + ((CHAR *)poDestAlign) += sizeof (SDI); + rgsdiStrDef++; + } + } +} + + +VOID +vSetFileEndianType ( + BOOL fNewEndianType + ) + +/*++ + +Routine Description: + + This routine is used to set the endian type of the disk file. Normally + the define CVT_FILE + +Arguments: + + fNewEndianType - Endian format type to set the source to. + The only valid types are CVT_LITTLE_ENDIAN and + CVT_BIG_ENDIAN. + Portable calls to this function should always + use either CVT_ENDIAN_SYSTEM or CVT_ENDIAN_FILE. + +Return Value: + + None. + +--*/ + +{ + // Set the endian type of the source data. + vfFileEndianType = fNewEndianType; +} + + +INT +fDetermineSysEndianType ( + VOID + ) + +/*++ + +Routine Description: + + This function is used to determine how the current system stores its + integers in memory. + +Arguments: + + None. + +Return Value: + + CVT_LITTLE_ENDIAN - The system stores integers in little endian + format. (this is 80x86 default). + CVT_BIG_ENDIAN - The system stores integers in big endian format. + +--*/ + +{ + INT nCheckInteger; + CHAR rgchTestBytes [sizeof (INT)]; + + // + // Clear the test bytes to zero. + // + + *((INT *)rgchTestBytes) = 0; + + // + // Set first to some value. + // + + rgchTestBytes [0] = (TCHAR)0xFF; + + // + // Map it to an integer. + // + + nCheckInteger = *((INT *)rgchTestBytes); + + // + // See if value was stored in low order of integer. + // If so then system is little endian. + // + + if (nCheckInteger == 0xFF) { + + return (CVT_LITTLE_ENDIAN); + } else { + + return (CVT_LITTLE_ENDIAN); + } +} + + +VOID +vCharToShort ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source CHAR to the destination SHORT. Note that sign extension + is performed. The destination buffer does not need to be WORD aligned. + This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a CHAR. + pjDest - Returns the copied SHORT at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source CHAR and use it as an argument for destination SHORT. + + vDestBuffFromSHORT ( + (SHORT)*pjSrc, + pjDest + ); +} + + +VOID +vCharToUShort ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source CHAR to the destination USHORT. Note that sign + extension is not perfomed. The destination buffer does not need to be + WORD aligned. This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a CHAR. + pjDest - Returns the copied SHORT at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source CHAR and use it as an argument for destination USHORT. + + vDestBuffFromUSHORT ( + (USHORT)*pjSrc, + pjDest + ); +} + + +VOID +vCharToLong ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source CHAR to the destination LONG. Note that sign extension + is performed. The destination buffer does not need to be DWORD aligned. + This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a CHAR. + pjDest - Returns the copied LONG at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source CHAR and use it as an argument for destination LONG. + + vDestBuffFromLONG ( + (LONG)*pjSrc, + pjDest + ); +} + + +VOID +vCharToULong ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source CHAR to the destination ULONG. Note that sign extension + is not performed. The destination buffer does not need to be DWORD + aligned. This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a CHAR. + pjDest - Returns the copied ULONG at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source CHAR and use it as an argument for destination ULONG. + + vDestBuffFromULONG ( + (ULONG)*pjSrc, + pjDest + ); +} + + +VOID +vShortToShort ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source SHORT to the destination SHORT. Neither buffers need + to be WORD aligned. This is generally used for transfering file mapped + data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a SHORT. + pjDest - Returns the copied SHORT at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source SHORT and use it as an argument for destination SHORT. + + vDestBuffFromSHORT ( + sSHORTFromSrcBuff (pjSrc), + pjDest + ); +} + + +VOID +vShortToLong ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source SHORT to the destination LONG. Note that sign extension + is perfomed. Neither buffers need to be WORD or DWORD aligned. + This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a SHORT. + pjDest - Returns the copied LONG at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source SHORT and use it as an argument for destination LONG. + + vDestBuffFromLONG ( + (LONG)sSHORTFromSrcBuff (pjSrc), + pjDest + ); +} + + +VOID +vShortToULong ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source SHORT to the destination ULONG. Note that sign extension + is perfomed. Neither buffers need to be WORD or DWORD aligned. + This is generally used for transfering file mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a SHORT. + pjDest - Returns the copied ULONG at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source SHORT and use it as an argument for destination ULONG. + + vDestBuffFromULONG ( + (LONG)sSHORTFromSrcBuff (pjSrc), + pjDest + ); +} + + +VOID +vLongToLong ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source LONG to the destination LONG. Neither buffers need to + be WORD or DWORD aligned. This is generally used for transfering file + mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a LONG. + pjDest - Returns the copied LONG at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source LONG and use it as an argument for destination LONG. + + vDestBuffFromLONG ( + (LONG)lLONGFromSrcBuff (pjSrc), + pjDest + ); +} + + +VOID +vLongToShort ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source LONG to the destination SHORT. Neither buffers need to + be WORD or DWORD aligned. This is generally used for transfering file + mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a LONG. + pjDest - Returns the copied SHORT at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source LONG and use it as an argument for destination SHORT. + + vDestBuffFromSHORT ( + (SHORT)lLONGFromSrcBuff (pjSrc), + pjDest + ); +} + + +VOID +vLongToChar ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source LONG to the destination CHAR. Neither buffers need to + be WORD or DWORD aligned. This is generally used for transfering file + mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a LONG. + pjDest - Returns the copied CHAR at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source LONG and use it as an argument for destination CHAR. + + *pjDest = (CHAR)lLONGFromSrcBuff (pjSrc); +} + + +VOID +vShortToChar ( + PBYTE pjSrc, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies the source SHORT to the destination CHAR. Neither buffers need to + be WORD or DWORD aligned. This is generally used for transfering file + mapped data. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a SHORT. + pjDest - Returns the copied CHAR at the location pointed to. + +Return Value: + + None. + +--*/ + +{ + // Get the source SHORT and use it as an argument for destination CHAR. + + *pjDest = (CHAR)sSHORTFromSrcBuff (pjSrc); +} + + +SHORT +sSHORTFromSrcBuff ( + PBYTE pjSrc + ) + +/*++ + +Routine Description: + + Copies two byte short from buffer into a signed short. The buffer does + not need to be WORD aligned. This is generally used for copying from + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fSrcEndianType is checked before copy. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a SHORT. + +Return Value: + + Signed short which is obtained from the buffer. + +--*/ + + +{ + SHORT sStorage; + +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + sStorage = (SHORT) // Source is little endian, shift + ( // the high bytes high. + (pjSrc [1] << 8) | + (pjSrc [0]) + ); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + sStorage = (SHORT) // Source is big endian, shift + ( // the high bytes low. + (pjSrc [0] << 8) | + (pjSrc [1]) + ); + } + +#endif + + return (sStorage); +} + + +USHORT +usUSHORTFromSrcBuff ( + PBYTE pjSrc + ) + +/*++ + +Routine Description: + + Copies two byte short from buffer into an unsigned short. The buffer does + not need to be WORD aligned. This is generally used for copying from + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fSrcEndianType is checked before copy. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a USHORT. + +Return Value: + + Unsigned short which is obtained from the buffer. + +--*/ + + +{ + USHORT usStorage; + +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + usStorage = (USHORT) // Source is little endian, shift + ( // the high bytes high. + (pjSrc [1] << 8) | + (pjSrc [0]) + ); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + usStorage = (USHORT) // Source is big endian, shift + ( // the high bytes low. + (pjSrc [0] << 8) | + (pjSrc [1]) + ); + } + +#endif + + return (usStorage); +} + + +LONG +lLONGFromSrcBuff ( + PBYTE pjSrc + ) + +/*++ + +Routine Description: + + Copies four byte long from buffer into a signed long. The buffer does + not need to be DWORD aligned. This is generally used for copying from + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fSrcEndianType is checked before copy. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a LONG. + +Return Value: + + Signed long which is obtained from the buffer. + +--*/ + + +{ + LONG lStorage; + +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + lStorage = (LONG) // Source is little endian, shift + ((pjSrc [3] << 24) | // the high bytes high. + (pjSrc [2] << 16) | + (pjSrc [1] << 8) | + (pjSrc [0]) + ); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + lStorage = (LONG) // Source is big endian, shift the + ((pjSrc [0] << 24) | // high bytes low. + (pjSrc [1] << 16) | + (pjSrc [2] << 8) | + (pjSrc [3]) + ); + } + +#endif + + return (lStorage); +} + + +ULONG +ulULONGFromSrcBuff ( + PBYTE pjSrc + ) + +/*++ + +Routine Description: + + Copies four byte long from buffer into an unsigned long. The buffer does + not need to be DWORD aligned. This is generally used for copying from + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fSrcEndianType is checked before copy. + +Arguments: + + pjSrc - Supplies pointer to the source buffer containing a ULONG. + +Return Value: + + Unsigned long which is obtained from the buffer. + +--*/ + + +{ + ULONG ulStorage; + +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + ulStorage = (ULONG) // Source is little endian, shift + ((pjSrc [3] << 24) | // the high bytes high. + (pjSrc [2] << 16) | + (pjSrc [1] << 8) | + (pjSrc [0]) + ); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + ulStorage = (ULONG) // Source is big endian, shift the + ((pjSrc [0] << 24) | // high bytes low. + (pjSrc [1] << 16) | + (pjSrc [2] << 8) | + (pjSrc [3]) + ); + } + +#endif + + return (ulStorage); +} + + +VOID +vDestBuffFromSHORT ( + SHORT sSource, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies two byte signed short into a destination buffer. The buffer does + not need to be WORD aligned. This is generally used for copying to + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fDestEndianType is checked before copy. + +Arguments: + + sSource - Signed short to convert to buffer. + pjDest - Supplies pointer to destination buffer for the USHORT. + +Return Value: + + None. + +--*/ + + +{ +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + pjDest [0] = ((sSource) & 0xFF); + pjDest [1] = ((sSource >> 8) & 0xFF); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + pjDest [1] = ((sSource) & 0xFF); + pjDest [0] = ((sSource >> 8) & 0xFF); + } + +#endif +} + + +VOID +vDestBuffFromUSHORT ( + USHORT usSource, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies two byte unsigned short into a destination buffer. The buffer + does not need to be WORD aligned. This is generally used for copying to + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fDestEndianType is checked before copy. + +Arguments: + + usSource - Unsigned short to convert to buffer. + pjDest - Supplies pointer to destination buffer for the USHORT. + +Return Value: + + None. + +--*/ + + +{ +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + pjDest [0] = ((usSource) & 0xFF); + pjDest [1] = ((usSource >> 8) & 0xFF); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + pjDest [1] = ((usSource) & 0xFF); + pjDest [0] = ((usSource >> 8) & 0xFF); + } + +#endif +} + + +VOID +vDestBuffFromLONG ( + LONG lSource, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies four byte long into a destination buffer. The buffer does not + need to be DWORD aligned. This is generally used for copying to + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fDestEndianType is checked before copy. + +Arguments: + + lSource - Signed long to convert to buffer. + pjDest - Supplies pointer to destination buffer for the LONG. + +Return Value: + + None. + +--*/ + + +{ +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + pjDest [0] = ((lSource) & 0xFF); + pjDest [1] = ((lSource >> 8) & 0xFF); + pjDest [2] = ((lSource >> 16) & 0xFF); + pjDest [3] = ((lSource >> 24) & 0xFF); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + pjDest [3] = ((lSource) & 0xFF); + pjDest [2] = ((lSource >> 8) & 0xFF); + pjDest [1] = ((lSource >> 16) & 0xFF); + pjDest [0] = ((lSource >> 24) & 0xFF); + } + +#endif +} + + +VOID +vDestBuffFromULONG ( + ULONG ulSource, + PBYTE pjDest + ) + +/*++ + +Routine Description: + + Copies four byte long into a destination buffer. The buffer does not + need to be DWORD aligned. This is generally used for copying to + mapped disk files. If CVT_BIG_ENDIAN_SUPPORT is defined then the + fDestEndianType is checked before copy. + +Arguments: + + ulSource - Unsigned long to convert to buffer. + pjDest - Supplies pointer to destination buffer for the ULONG. + +Return Value: + + None. + +--*/ + + +{ +#ifdef CVT_BIG_ENDIAN_SUPPORT + if (fSrcEndianType == CVT_LITTLE_ENDIAN) { +#endif + pjDest [0] = ((BYTE)(ulSource) & 0xFF); + pjDest [1] = ((BYTE)(ulSource >> 8) & 0xFF); + pjDest [2] = ((BYTE)(ulSource >> 16) & 0xFF); + pjDest [3] = ((BYTE)(ulSource >> 24) & 0xFF); + +#ifdef CVT_BIG_ENDIAN_SUPPORT + } else { + pjDest [3] = ((BYTE)(ulSource) & 0xFF); + pjDest [2] = ((BYTE)(ulSource >> 8) & 0xFF); + pjDest [1] = ((BYTE)(ulSource >> 16) & 0xFF); + pjDest [0] = ((BYTE)(ulSource >> 24) & 0xFF); + } + +#endif +} diff --git a/private/sdktools/fontedit/typecvt.h b/private/sdktools/fontedit/typecvt.h new file mode 100644 index 000000000..b44f40a51 --- /dev/null +++ b/private/sdktools/fontedit/typecvt.h @@ -0,0 +1,273 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + typecvt.h + +Abstract: + + Header file for typecvt.c. Contains any defines, structures and prototypes + which are needed by programs to call the typecvt routines. + +Author: + + David J. Marsyla (t-davema) 22-Jul-1991 + +Revision History: + + +--*/ + + +// Make sure we are not already defined. + +#ifndef _TYPECVT_ + +#define _TYPECVT_ + +// +// The following preprocessor directives are used to control possible +// differences between the way integers are stored on the machine and +// how they are stored in the file. Normally Intel and MIPS chips will +// all be little endian so these should not be necessray. Some time in +// the future we may port to a machine which is only big endian. +// If this is the case CVT_BIG_ENDIAN_SUPPORT should be defined. +// + +// +// The following defines are used to set the type of source and destination +// structures. For those of us who are confused by little endian and big +// endian formats, here is a breif recap. +// +// Little Endian: (This is used on Intel chips. The MIPS chip is switchable +// but for NT is will run in little endian format.) +// This is where the high order bytes of a short or long are stored higher +// in memory. For example the number 0x80402010 is stored as follows. +// Address: Value: +// 00 10 +// 01 20 +// 02 40 +// 03 80 +// This looks backwards when memory is dumped in order: 10 20 40 80 +// +// Big Endian: (This is not currently used on any NT systems but hey, this +// is supposed to be portable!!) +// This is where the high order bytes of a short or long are stored lower +// in memory. For example the number 0x80402010 is stored as follows. +// Address: Value: +// 00 80 +// 01 40 +// 02 20 +// 03 10 +// This looks correct when memory is dumped in order: 80 40 20 10 +// + +#define CVT_ENDIAN_UNKNOWN 0 // Endian type is unknown. (do not use). +#define CVT_LITTLE_ENDIAN 1 // Format is little endian. +#define CVT_BIG_ENDIAN 2 // Format is big endian. + +// +// Define the endian type of the file. CVT_FILE_ENDIAN_DEFAULT defines how +// most files are stored on disk. The default is in little endian since most +// Microsoft standards are set based on the Intel chip. +// + +#define CVT_FILE_ENDIAN_DEFAULT CVT_LITTLE_ENDIAN + +// +// The following variables are used to make "changeable defines." They +// allow the caller to specify a constant which changes from system to +// system. +// + +extern INT vfFileEndianType; +extern INT vfSysEndianType; + +#define CVT_ENDIAN_FILE vfFileEndianType +#define CVT_ENDIAN_SYSTEM vfSysEndianType + +// +// Fake structure used to determine system alignment type. +// + +struct tagAlignmentCheck +{ + char chElem1; // Note that this structure will be different + long lElem2; // sizes based on the system alignment scheme. + // The different values follow. +}; + +// +// Note that the following defines must correspond to the size of the +// preceeding structure in different packing schemes. +// + +#define CVT_ALIGN_PACKED 5 // Packed = 1-byte boundry ... +#define CVT_ALIGN_WORD 6 // WORD = 2-byte boundry ... +#define CVT_ALIGN_DWORD 8 // DWORD = 4-byte boundry ... + +// +// The following will correspond to one of the above alignment methods and +// will then reflect the system that this is compiled under. +// + +#define CVT_ALIGN_SYSTEM sizeof(struct tagAlignmentCheck) + + +// +// The next two structures are the heart of the conversion process. The +// goal here is to describe two structures individually. Each element should +// be defined in a SDI structure. An array of these structures will make up +// the complete definition. +// + +typedef struct tagStructDefineInfo +{ + INT cTypeSize; // Size of type. (ex. sizeof (int)). + INT cActualSize; // Actual size (ex. sizeof (cTypeSize)). + INT oPackedAlign; // Offset of element in PACKED alginment. + INT oWordAlign; // Offset of element in WORD alginment. + INT oDWordAlign; // Offset of element in DWORD alginment. +} SDI, * PSDI; + +// +// Prototypes for base functions which user can call to perfom the conversion. +// + +LONG +lCalculateStructOffsets ( + PSDI rgsdiStructDefine, + INT fAlignmentType, + INT cSizeOfStruct + ); + +VOID +vPerformConversion ( + PSDI rgsdiStructDefine, + PBYTE pjSrcBuffer, + INT fSrcAlignment, + INT fSrcEndianType, + PBYTE pjDestBuffer, + INT fDestAlignment, + INT fDestEndianType + ); + +VOID +vSetFileEndianType ( + BOOL fNewEndianType + ); + +INT +fDetermineSysEndianType ( + VOID + ); + +// +// Prototypes for convertion functions available to external programs. +// These functions are never actually used by +// + +VOID +vCharToShort ( + PBYTE pjSrc, + PBYTE pjDest + ); +VOID +vCharToUShort ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vCharToLong ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vCharToULong ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vShortToShort ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vShortToLong ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vShortToULong ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vLongToLong ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vLongToShort ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vLongToChar ( + PBYTE pjSource, + PBYTE pjDest + ); +VOID +vShortToChar ( + PBYTE pjSource, + PBYTE pjDest + ); + +// +// The following functions are the ones called by the utility functions. +// They could also be used in some other situations so I will make them +// public. +// + +SHORT +sSHORTFromSrcBuff ( + PBYTE pjSrc + ); +USHORT +usUSHORTFromSrcBuff ( + PBYTE pjSrc + ); +LONG +lLONGFromSrcBuff ( + PBYTE pjSrc + ); +ULONG +ulULONGFromSrcBuff ( + PBYTE pjSrc + ); + + +VOID +vDestBuffFromSHORT ( + SHORT sSource, + PBYTE pjDest + ); +VOID +vDestBuffFromUSHORT ( + USHORT usSource, + PBYTE pjDest + ); +VOID +vDestBuffFromLONG ( + LONG lSource, + PBYTE pjDest + ); +VOID +vDestBuffFromULONG ( + ULONG ulSource, + PBYTE pjDest + ); + +#endif // _TYPECVT_ |