home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic 4 Unleashed
/
Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso
/
repease
/
rep_fmt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-14
|
19KB
|
516 lines
/*==============================================================================
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;
}