home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
- REP_FMT.C
- ReportEase Plus formatting and font functions.
-
- ReportEase Plus
- Sub Systems, Inc.
- ReportEase Plus, Copyright (c) 1993, Sub Systems, Inc. All Rights Reserved.
- 159 Main Street, #8C, Stoneham, MA 02180
- (617) 438-8901.
-
- Software License Agreement (1993)
- ----------------------------------
- This license agreement allows the purchaser the right to modify the
- source code to incorporate in their application.
- The target application must not be distributed as a standalone report writer
- or a mail merge product.
- Sub Systems, Inc. reserves the right to prosecute anybody found to be
- making illegal copies of the executable software or compiling the source
- code for the purpose of selling there after.
-
- ===============================================================================*/
- #include "windows.h"
-
- #if defined (_WIN32)
- #if !defined(WIN32)
- #define WIN32
- #endif
- #endif
- #if !defined(WIN32)
- #include "print.h"
- #endif
-
- #include "stdio.h"
- #include "stdlib.h"
- #include "ctype.h"
- #include "fcntl.h"
- #include "io.h"
- #include "sys\types.h"
- #include "sys\stat.h"
- #include "math.h"
- #include "string.h"
- #include "setjmp.h"
-
- #include "commdlg.h"
-
- #include "rep.h"
-
- #define PREFIX extern
- #include "rep1.h"
-
- /******************************************************************************
- FrFonts:
- Allow the user to select a font for the current item.
- ******************************************************************************/
- FrFonts()
- {
- int i,NewFont,SaveHeight,SaveWidth,GroupItem;
- CHOOSEFONT cFont;
- LOGFONT lFont;
- int font;
-
- if (SelItem<0) return TRUE; // no item selected
- if (item[SelItem].type!=LABEL && item[SelItem].type!=FIELD && item[SelItem].type!=GROUP) return TRUE; // aplicable to label and field only
- if (item[SelItem].type==FIELD && field[item[SelItem].field].type==TYPE_PICT) return TRUE; // picture type item does not use font
-
- // make a copy of the old font
- font=item[SelItem].font;
- FarMove(&(FrFont[font].lFont),&lFont,sizeof(LOGFONT));
-
- // convert the height and width to the pixel units (ChooseFont requirement)
- SaveHeight=lFont.lfHeight;
- lFont.lfHeight=UnitToPixY(SaveHeight);
- if (SaveHeight>=0) { // compensate for rouding
- if (SaveHeight>PixToUnitY(lFont.lfHeight)) lFont.lfHeight++;
- }
- else {
- if (SaveHeight<PixToUnitY(lFont.lfHeight)) lFont.lfHeight--;
- }
-
- SaveWidth=lFont.lfWidth;
- lFont.lfWidth=UnitToPixX(SaveWidth);
- if (SaveWidth>PixToUnitX(lFont.lfWidth)) lFont.lfWidth++;
-
-
- // fill the CHOOSEFONT structure
- FarMemSet(&cFont,0,sizeof(CHOOSEFONT));
- cFont.lStructSize=sizeof(CHOOSEFONT);
- cFont.hwndOwner=hFrWnd;
- cFont.hDC=hPrtDC; // print device context
- cFont.lpLogFont=&lFont;
- cFont.Flags=CF_BOTH|CF_EFFECTS|CF_INITTOLOGFONTSTRUCT;
- cFont.rgbColors=item[SelItem].TextColor;
-
- if (!ChooseFont(&cFont)) return FALSE;
-
- // apply the chosen color to the item
- item[SelItem].TextColor=cFont.rgbColors;
-
- // convert the height and width to the logical units
- lFont.lfHeight=PixToUnitY(lFont.lfHeight);
- lFont.lfWidth=PixToUnitX(lFont.lfWidth);
-
- // apply the chosen font to the item
- for (i=0;i<TotalFonts;i++) { // check for any exising font
- if (!FrFont[i].InUse) continue;
- if (FrFont[i].IsPict) continue;
- if (IsSameFont(&(FrFont[i].lFont),&(lFont))) { // matching font already exists
- item[SelItem].font=i; // select the match font
- break;
- }
- }
-
- if (i==TotalFonts) { // create new font
- // create a new font slot
- NewFont=FindOpenSlot();
- if (NewFont==-1) {
- MessageBox(hFrWnd,"Ran out of Font Table",NULL,MB_OK);
- return FALSE;
- }
-
- // copy the font specifications
- FarMove(&lFont,&(FrFont[NewFont].lFont),sizeof(LOGFONT));
- if (!CreateOneFont(hFrDC,NewFont)) {
- InitFrObject(NewFont);
- return FALSE;
- }
-
- item[SelItem].font=NewFont; // select the new font
- }
- if (item[SelItem].type==FIELD) CreateFieldLabel(item[SelItem].field,item[SelItem].label,item[SelItem].width,item[SelItem].font); // create field label
- if (item[SelItem].type==LABEL) UpdateLabelSize(SelItem);
-
- // if the current item is a group item, apply this font to all group items
- if (item[SelItem].type==GROUP) {// update all items in the group
- GroupItem=SelItem;
- MarkGroupItems(); // mark the items in the group
- for (i=0;i<TotalItems;i++) {
- if (item[i].InGroup) {
- if (item[i].type==LABEL || item[i].type==FIELD) {
- item[i].font=item[GroupItem].font;
- item[i].TextColor=item[GroupItem].TextColor;
- }
- if (item[i].type==FIELD) CreateFieldLabel(item[i].field,item[i].label,item[i].width,item[i].font); // create field label
- if (item[i].type==LABEL) UpdateLabelSize(i);
- item[i].InGroup=FALSE;
- }
- }
- }
-
- FrPaint();
- FrModified=TRUE;
-
- return TRUE;
- }
-
- /******************************************************************************
- FindOpenSlot:
- Find an empty slot in the FrFont arrays to create a new font/picture.
- If not slots are available, the document is checked for duplicate
- and deleted fonts to free up a slot.
- If successful, the routine returns the index to the FrFont array,
- otherwise it returns -1
- ******************************************************************************/
- FindOpenSlot()
- {
- int i,j,NewFont,SimilarFont[MAX_FONTS];
- BOOL FontUsed[MAX_FONTS];
- BYTE font1,font2;
- BOOL OneSlotFreed;
-
-
- // find an unused slot
- LOOK_FOR_UNUSED_SLOT:
- for (i=0;i<TotalFonts;i++) {
- if (!(FrFont[i].InUse)) {
- InitFrObject(i);
- return i;
- }
- }
-
- if (TotalFonts<MAX_FONTS) { // create a new font in a new slot
- NewFont=TotalFonts;
- TotalFonts++;
- InitFrObject(NewFont);
- return NewFont;
- }
-
- // consolidate fonts in the current file to open up a slot
-
- // examine the font table for similar fonts
- SimilarFont[0]=0;
- for (i=1;i<MAX_FONTS;i++) {
- SimilarFont[i]=i;
- if (FrFont[i].IsPict) continue; // don't touch the pictures
-
- for(j=0;j<=i;j++) { // compare this font with earlier fonts
- if(!(FrFont[j].IsPict)
- && IsSameFont(&(FrFont[j].lFont),&(FrFont[i].lFont)) ){
- SimilarFont[i]=j;
- break;
- }
- }
- }
-
- //* adjust the fonts in the document
- for (i=0;i<MAX_FONTS;i++) FontUsed[i]=FALSE; // initialize 'font use' table
-
- for (i=0;i<TotalItems;i++) {
- if (item[i].type!=LABEL && item[i].type!=FIELD) continue;
- font1=item[i].font;
- font2=SimilarFont[font1];
- item[i].font=font2; // use the new font
- FontUsed[font2]=TRUE; // keep track of fonts actually used
- }
-
- //** mark the freed fonts as unused **
- OneSlotFreed=FALSE;
- for (i=1;i<MAX_FONTS;i++) { // the default font (1) never freed
- if (FrFont[i].InUse && SimilarFont[i]!=i) {DeleteFrObject(i);OneSlotFreed=TRUE;} // delete font/picture
- if (FrFont[i].InUse && !FontUsed[i]) {DeleteFrObject(i);OneSlotFreed=TRUE;}
- }
-
- if (OneSlotFreed) goto LOOK_FOR_UNUSED_SLOT;
- else {
- MessageBox(hFrWnd,"Ran Out of Font/Picture Table",NULL,MB_OK);
- return -1;
- }
- }
-
- /******************************************************************************
- IsSameFont:
- This routine compares two LOGFONT structures and returns a TRUE value
- if they are the same.
- ******************************************************************************/
- BOOL IsSameFont(LOGFONT far *lFont1,LOGFONT far *lFont2)
- {
- if (lFont1->lfHeight!=lFont2->lfHeight) return FALSE;
- if (lFont1->lfWidth!=lFont2->lfWidth) return FALSE;
- if (lFont1->lfEscapement!=lFont2->lfEscapement) return FALSE;
- if (lFont1->lfOrientation!=lFont2->lfOrientation) return FALSE;
- if (lFont1->lfWeight!=lFont2->lfWeight) return FALSE;
- if (lFont1->lfItalic!=lFont2->lfItalic) return FALSE;
- if (lFont1->lfUnderline!=lFont2->lfUnderline) return FALSE;
- if (lFont1->lfStrikeOut!=lFont2->lfStrikeOut) return FALSE;
- if (lFont1->lfCharSet!=lFont2->lfCharSet) return FALSE;
- if (lFont1->lfOutPrecision!=lFont2->lfOutPrecision) return FALSE;
- if (lFont1->lfClipPrecision!=lFont2->lfClipPrecision) return FALSE;
- if (lFont1->lfQuality!=lFont2->lfQuality) return FALSE;
- if (lFont1->lfPitchAndFamily!=lFont2->lfPitchAndFamily) return FALSE;
- if (lstrcmp(lFont1->lfFaceName,lFont2->lfFaceName)!=0) return FALSE;
- return TRUE;
- }
-
- /******************************************************************************
- SelectBestFont:
- This routine creates a font of the specified typeface and pointsize.
- This routine constructs the LOGFONT structure for the font and creates
- the font handle.
- ******************************************************************************/
- SelectBestFont(HDC hDC,int NewFont,LPSTR Typeface,int PointSize)
- {
- LOGFONT far *lFont;
-
- if (FrFont[NewFont].IsPict) return TRUE; // not a true font
-
-
- // File the logfont structure
- lFont=&(FrFont[NewFont].lFont);
- FarMemSet(lFont,0,sizeof(LOGFONT));
- lFont->lfHeight=-(int)((PointSize*(long)UNITS_PER_INCH)/72); // specify in logical units.
- lstrcpy(lFont->lfFaceName,Typeface);
-
- if (!CreateOneFont(hDC,NewFont)) return FALSE; // create a font
-
- return TRUE;
- }
-
- /******************************************************************************
- CreateOneFont:
- This routine creates a font whose table index is given by the argument.
- This table must already have the LOGFONT structure filled.
- This routine selects the new font into the display context.
- The new font is created for the specified display context.
- ******************************************************************************/
- CreateOneFont(HDC hDC,int NewFont)
- {
- int i;
- TEXTMETRIC met;
- LOGFONT lFont;
-
- if (FrFont[NewFont].IsPict) return TRUE; // not a true font
-
- if (FrFont[NewFont].hFont) { // delete old font
- hFrCurFont=GetStockObject(SYSTEM_FONT); // deselect first
- SelectObject(hFrDC,hFrCurFont);
- SelectObject(hMemDC,hFrCurFont);
-
- DeleteObject(FrFont[NewFont].hFont);
- FrFont[NewFont].hFont=NULL;
- }
-
- lFont=FrFont[NewFont].lFont;
- FrFont[NewFont].hFont=CreateFontIndirect(&lFont);
-
- if (FrFont[NewFont].hFont==NULL) return FALSE;
-
- //** setup the character width table for the new font
- if (NULL==SelectObject(hDC,FrFont[NewFont].hFont)) return FALSE;
- if (!GetTextMetrics(hDC,&met)) return FALSE;
- if (met.tmAscent==0) return FALSE;
- if (NewFont==0) FrTextMet=met; // default font metrics
-
- // build the character width table
- if (SessionType=='F' && GetCharWidth(hDC,0,255,FrFont[NewFont].CharWidth)) {
- for (i=0;i<256;i++) { // adjust the character width table
- FrFont[NewFont].CharWidth[i]=FrFont[NewFont].CharWidth[i]-met.tmOverhang;
- }
- }
- else { // try alternate method now
- SIZE size;
- FrFont[NewFont].CharWidth[0]=0;
- for (i=1;i<256;i++) {
- msg[0]=i; //get the text extent of each character
- msg[1]=0;
- GetTextExtentPoint(hDC,msg,1,&size);
- FrFont[NewFont].CharWidth[i]=size.cx;
- }
- }
-
- //** calculate the distance from the base of the font to the top of the font
- FrFont[NewFont].BaseHeight=met.tmAscent;
- FrFont[NewFont].height=met.tmHeight; // actual font height
-
- FrFont[NewFont].InUse=TRUE;
-
- return TRUE;
- }
-
- /******************************************************************************
- FrCreateDIB:
- This routine creates a device indenpendent bitmap from a source
- bitmap. The source bitmap is assumed to be compatible with the
- current display context.
- The newly created device independent bitmap is stored in the FrFont
- structure in an open slot.
- If successful, the routine returns the index of the newly created
- bitmap, otherwise it returns -1.
- ******************************************************************************/
- FrCreateDIB(HBITMAP hBM)
- {
- HANDLE hInfo,hImage;
- LPSTR pImage;
- LPBITMAPINFOHEADER pInfo;
- int pict;
- DWORD InfoSize,ImageSize;
- BITMAP bm;
-
- //**** find an empty slot in the font/picture table ****
- if ((pict=FindOpenSlot())==-1) return -1;
-
- GetObject(hBM,sizeof(BITMAP),(LPSTR)&bm); // get the dimension of bit map
-
- //********** create the device independent bitmap ***********************
- InfoSize=sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD); // create a 16 color bitmap structure
-
- if (NULL==(hInfo=GlobalAlloc(GMEM_MOVEABLE,InfoSize))
- ||NULL==(pInfo=(LPBITMAPINFOHEADER)GlobalLock(hInfo)) ) {
- MessageBox(hFrWnd,"Ran out of memory for Bitmap Info!",NULL,MB_OK);
- return -1;
- }
-
- //***** fill in the info structure ******
- pInfo->biSize=sizeof(BITMAPINFOHEADER);
- pInfo->biWidth=bm.bmWidth;
- pInfo->biHeight=bm.bmHeight;
- pInfo->biPlanes=1; // DIB have plane = 1
- pInfo->biBitCount=8; // 8 bits per pixel or color
- pInfo->biCompression=BI_RGB;
- pInfo->biSizeImage=0; // initialize to zero
- pInfo->biXPelsPerMeter=0;
- pInfo->biYPelsPerMeter=0;
- pInfo->biClrUsed=256; // 256 colors
- pInfo->biClrImportant=0; // all colors important
-
- if (!GetDIBits(hFrDC,hBM,0,bm.bmHeight,NULL,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
- MessageBox(hFrWnd,"Error Creating Device Independent Bitmap Structure!",NULL,MB_OK);
- return -1;
- }
-
-
- ImageSize=pInfo->biSizeImage;
- if (NULL==(hImage=GlobalAlloc(GMEM_MOVEABLE,ImageSize))
- ||NULL==(pImage=GlobalLock(hImage)) ) {
- MessageBox(hFrWnd,"Ran out of memory for Bitmap Image!",NULL,MB_OK);
- return -1;
- }
-
- if (!GetDIBits(hFrDC,hBM,0,bm.bmHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
- MessageBox(hFrWnd,"Error Creating Device Independent Bitmap Image!",NULL,MB_OK);
- return -1;
- }
-
- GlobalUnlock(hInfo);
- GlobalUnlock(hImage);
-
- FrFont[pict].InUse=TRUE;
- FrFont[pict].PictHeight=(UINT)((DWORD)(bm.bmHeight)*72L/(DWORD)ResY); // dimension in point sizes
- FrFont[pict].PictWidth=(UINT)((DWORD)(bm.bmWidth)*72L/(DWORD)ResX);
- FrFont[pict].ImageSize=ImageSize;
- FrFont[pict].hImage=hImage;
- FrFont[pict].InfoSize=InfoSize;
- FrFont[pict].hInfo=hInfo;
- FrFont[pict].IsPict=TRUE;
-
- return pict;
- }
-
- /******************************************************************************
- FrXlateDIB:
- This routine creates a device specific bitmap from a device independent
- bit map. The first argument specifies the device context to build
- the bitmap for. The second argument specifies an index into the FrFont
- structure that contains the handle to the device independent image and
- information.
- ******************************************************************************/
- FrXlateDIB(HDC hDC,int pict)
- {
- int i;
- BYTE planes,BitsPerPixel;
- LPBITMAPINFOHEADER pInfo;
- LPSTR pImage;
- BITMAP bm;
-
-
- if (!(FrFont[pict].IsPict)) return TRUE; // not a picutre element
-
- //*********** lock the DIB handles ***********
- if (NULL==(pImage=GlobalLock(FrFont[pict].hImage))
- || NULL==(pInfo=(LPBITMAPINFOHEADER)GlobalLock(FrFont[pict].hInfo)) ) {
- MessageBox(hFrWnd,"Ran out of memory for Bitmap Image and info!",NULL,MB_OK);
- return FALSE;
- }
-
- //******** delete old bitmap if present *******
- if (FrFont[pict].hBM) { // delete the old bit map
- DeleteObject(FrFont[pict].hBM);
- FrFont[pict].hBM=0;
- }
-
- //********* create our bitmap *******************************************
- planes=GetDeviceCaps(hDC,PLANES); // get the device charistrics
- BitsPerPixel=GetDeviceCaps(hDC,BITSPIXEL);
-
- if (NULL==(FrFont[pict].hBM=CreateBitmap((UINT)(pInfo->biWidth),(UINT)(pInfo->biHeight),planes,BitsPerPixel,NULL))) {
- MessageBox(hFrWnd,"Error Creating the Bitmap",NULL,MB_OK);
- return FALSE;
- }
-
- if (!SetDIBits(hDC,FrFont[pict].hBM,0,(UINT) pInfo->biHeight,pImage,(LPBITMAPINFO)pInfo,DIB_RGB_COLORS)) {
- MessageBox(hFrWnd,"Error Initializing the Bitmap",NULL,MB_OK);
- return FALSE;
- }
-
- GetObject(FrFont[pict].hBM,sizeof(BITMAP),(LPSTR)&bm); // get the dimension of bit map
- FrFont[pict].bmHeight=bm.bmHeight; // actual dimensions
- FrFont[pict].bmWidth=bm.bmWidth;
-
- //************ calculate the display height ******************
- FrFont[pict].height=FrFont[pict].BaseHeight=(int)(((long)FrFont[pict].PictHeight*(long)UNITS_PER_INCH)/72L);
- FrFont[pict].CharWidth[0]=(int)(((long)FrFont[pict].PictWidth*(long)UNITS_PER_INCH)/72L);
- for (i=1;i<256;i++) FrFont[pict].CharWidth[i]=FrFont[pict].CharWidth[0];
-
- //******** unlock the DIB info and image ********************
- GlobalUnlock(FrFont[pict].hImage);
- GlobalUnlock(FrFont[pict].hInfo);
-
- return TRUE;
-
- }
-
- /******************************************************************************
- DeleteFrObject:
- This routine deletes the font or bitmap for a specified FrFont element.
- ******************************************************************************/
- DeleteFrObject(int idx)
- {
- if (FrFont[idx].InUse) {
- if (FrFont[idx].IsPict) {
- if (FrFont[idx].hBM) DeleteObject(FrFont[idx].hBM); // delete bitmap
- if (FrFont[idx].hImage) GlobalFree(FrFont[idx].hImage); // delete DIB image
- if (FrFont[idx].hInfo) GlobalFree(FrFont[idx].hInfo); // delete DIB info
- }
- else {
- if (FrFont[idx].hFont) DeleteObject(FrFont[idx].hFont);
- }
- InitFrObject(idx);
- }
- return TRUE;
- }
-
- /******************************************************************************
- InitFrObject:
- Initialize a Fr Font Object (font or picutre)
- ******************************************************************************/
- InitFrObject(int idx)
- {
- FrFont[idx].InUse=FALSE;
- FrFont[idx].IsPict=FALSE;
- FrFont[idx].hFont=NULL;
- FarMemSet(&(FrFont[idx].lFont),0,sizeof(LOGFONT));
- FrFont[idx].hBM=NULL;
- FrFont[idx].ImageSize=FrFont[idx].InfoSize=0;
- FrFont[idx].hImage=FrFont[idx].hInfo=NULL;
- return TRUE;
- }
-