/////////////////////////////////////////////////////////////////////////
//
//
#include "stdafx.h"
#include "textfrmt.h"
#define END_OF_LINE '\n'
// charsinwidth returns the number of characters that will fit within a certain width.
int Charsinwidth(CDC &mydc,LPCSTR strtocalc,int width )
{ // width is the width in logical units of the maximum output width
TEXTMETRIC metric; // structure used to get font information
LPCSTR stemp; // temp string
SIZE ssize;
if(!*strtocalc)
return FALSE;
mydc.GetTextMetrics( &metric); // get the font information
ssize.cx=0;
if(*strtocalc==END_OF_LINE)
return 1;
stemp=strtocalc; // Start at first word
if(!*stemp)
return FALSE;
// first make an educated guess...
{
int guess = width/metric.tmAveCharWidth; // how many chars we think are in here...
int loop;
for(loop=0;loop<guess;loop++)
{
if(!*(stemp+loop) || *(stemp+loop)==END_OF_LINE)
break;
}
stemp+=loop;
}
// keep advancing word by word untill we're at least 1 word too long
// we could already be much further if the educated guess was way off...
while(ssize.cx<width && *stemp && *stemp!=END_OF_LINE)
{
// while we're shorter than the width that they want, but not at end of string or a C/R
// keep going to the next word
while(*stemp!=32 && *stemp && *stemp!=END_OF_LINE)// advance a char at a time
stemp++; // up to next word break
ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0); // now, find out how wide this string is
if(!*stemp || *stemp==END_OF_LINE)
break;
stemp++;// if we're short, we want to skip over this space for next loop iteration :)
}
// now we're too long, so back up a word at a time untill we are right.
while(ssize.cx>width && stemp>strtocalc) // don't back up to before where we started!
{
stemp--;// decrement one more time so next time we aren't at the
// same stupid space. we can over-run the beginning of the string this
// way, but that won't matter cause we'll catch it in the next
// section of code.
while(*stemp!=32 && *stemp!='\t' && stemp>strtocalc)
stemp--; // back up untill we hit a space
ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0) ;
}
// is there only one word on the line?
if(stemp<=strtocalc)
{
stemp=strtocalc+1; // if so, advance one character at a time.
while(*stemp!=END_OF_LINE && *stemp) // to do this just advance up one character at a time untill
{ // we dont fit within the margin... then back up one char, and
// return that as the width.
// slow and painfull, but there's no other way
ssize=mydc.GetTabbedTextExtent(strtocalc,stemp-strtocalc,0,0);
if(ssize.cx>width)
{
stemp--;
break;
}
stemp++;
}
}
// add trailing spaces to this thing.
while(*stemp==' ')
{
stemp++;
}
if(stemp==strtocalc) // did we not get rid of any characters?
stemp++; // we have to get rid of at least one character in this routine.
return(stemp-strtocalc); // return number of characters that will fit
}
int CharsInColumns(LPCSTR str, BOOL bWordWrap,int columns)
{
int charat=0;
LPCSTR strstart=str;
while(*str && *str!=END_OF_LINE && charat < columns)
{
str++;
charat++;
}
if(bWordWrap && charat>79) // wrapping by words?
{
LPCSTR strstartwrap=str;
while(*str!=' ' && *str+1!=' ' && str>strstart && *str!=END_OF_LINE && *str)
str--;
if(str<=strstart)
str=strstartwrap;
}
// kill the leading space off of the next line.
if(*str==' ')
str++;
return (str-strstart);
}
int MyAnsiNext(LPCSTR pStr)
{
if(!*pStr)
{
TRACE("\nError, calling MyAnsiNext with pointer to null.");
return 0;
}
LPCSTR pAbort = pStr;
if(*pStr!=27)
return 1;
pStr++;
if(strchr("c78ABCDFGHIJKMZ=>12<",*pStr))
return 2;
if(*pStr=='#' && *(pStr+1)>'2' && *(pStr+1)<'9')
return 3;
if( (*pStr=='(' || *pStr==')')&& strchr("AB012",*(pStr+1)))
return 3;
if(*pStr!='[')
goto abort;
pStr++;
if(strchr("KJm",*pStr))
return 3;
do{
if(*pStr==';')
pStr++; // move off of '[' or ';'
// get first digit
if(isdigit(*pStr))
pStr++;
else
goto abort;
// get second digit
if(isdigit(*pStr))
pStr++;
}
while(*pStr==';');
if(strchr("rmABCDRnHfsuJkKycqg",*pStr))
return (pStr-pAbort)+1;
abort:
TRACE("\nInvalid ansi sequence.");
return 1;
}
int AnsiChars(LPCSTR str, int columns /* = 80 */)
{
int charat=0;
LPCSTR strstart=str;
while(*str && *str!=END_OF_LINE && charat < columns)
{
int num=MyAnsiNext(str);
str+= num;
if(num==1)
charat++;
}
// kill the leading space off of the next line.
if(*str==' ')
str++;
return (str-strstart);
}
int Ansimemcpy(LPSTR pDest,LPCSTR pSrc,int iFirstChar,int iLength)
{
if(iFirstChar)
pSrc+=AnsiChars(pSrc,iFirstChar);
int charat=0;
while(*pSrc && charat < iLength)
{
int num=MyAnsiNext(pSrc);
if(num==1)
{
*pDest=*pSrc;
charat++;
pDest++;
}
pSrc+= num;
}
*pDest=0;
return charat;
}