## Image Annotation - Calculate total height of textbox - Help! -:)

Hi

PROBLEM 1:

I want to add multiple lines of text to an image (using the ImageMagick Wand api).
This prg will create postcards, so the text must fit in a X * Y rectangle (depends on size of the card), and
I would like to write a function to calculate the width and height of the rectangle necessary to store the text.

Well, unfortunately it doesn't work properly, sometimes it makes a mistake, and the height will be insufficent.
Don't know what to do.. - What am I doing wrong?

Here is the idea:

Width (var w) should be the width of the longest line
Height should be: number of lines * height (returned by GetTypeMetrics)

PROBLEM 2:

When DrawAnnotation adds the text, the first line disappears.
Why? Both x & y coords are 0, so it should start the job in the upper-left corner of the image.

Here is the code. It compiles w/o warnings or errors for me. Currently i'm using it as a stand-alone prg, it takes the following args:

- argv[1] - Text file to read
- argv[2] - Maximum width of a line
- argv[3] - Maximum height

Code:
```char* URLDecode(char* encoded) {

....

// this works fine..

}

// just small func to strip newlines & tabs

char* trimchr(char* str,char* set) {

char* res = (char*) malloc(strlen(str)+1);
res = (char*) memset(res,0,strlen(str)+1);

int i,j;

for(i = 0, j = 0; i <= strlen(str); i++, j++) {
if((strchr(set,str[i])) != NULL) {
j -= 1;
} else {
res[(j == 0) ? i : j] = str[i];
}
}

res[i] = '\0';
return res;

}

int main(int argc, char *argv[])
{

FILE *file;
struct stat inf;
Image *Pic;
DrawInfo *Info;
ExceptionInfo exception;
TypeMetric Metric;
int j, k = 0, i, s = 0, WidthOffset = atoi(argv[2]), ml = 0;
float w = 0,h;

// txt file's path is generated by PHP, it's an URI, that's why the URLDecode
// func is here.

stat(URLDecode(argv[1]),&inf);

unsigned char* pic_text = (char*) malloc(inf.st_size+1);
pic_text = (char*) memset(pic_text,0,inf.st_size);

file = fopen(URLDecode(argv[1]),"r");
fclose(file);

pic_text = trimchr(pic_text,"\n\t");

char *line = (char*) malloc(strlen(pic_text) + sizeof(char) + 1);
line = (char*) memset(line,0,strlen(pic_text)+ sizeof(char) + 1);

char *buffer = (char*) malloc((strlen(pic_text) + 1)*2);
buffer = (char*) memset(buffer,0,(strlen(pic_text)+ 1)*2);

InitializeMagick(*argv);
GetExceptionInfo(&exception);
ImageInfo *Ni=CloneImageInfo((ImageInfo *) NULL);

// I added this because GetTypeMetrics needs a pic to run. I can't use the
// real picture here, since the height / width is unknown.
// Is it important to use a real image here? I tested it with several
// different imgs (ReadImage) and there was no difference. Why does

int *Pixel = (int*) malloc(sizeof(int)*2);
Pixel[0] = 255;
Pic = ConstituteImage(1,1,"I",IntegerPixel,Pixel,&exception);
free(Pixel);

Info  = CloneDrawInfo((ImageInfo *)NULL, (DrawInfo *)NULL);
Info->density = "72x72";
Info->pointsize = 11.0;
Info->font = "../fonts/arial.ttf";
Info->family = "arial";

for(i = 0; j != strlen(pic_text)+1; i++) {
line[i]  = pic_text[(j == 0) ? i : j];
Info->text = line;
(void) GetTypeMetrics(Pic,Info,&Metric);

if(j >= strlen(pic_text)) {
strncpy(&buffer[strlen(buffer)],line,strlen(line));
buffer[strlen(buffer)] = '\0';
h += Metric.height;
s += 1; break;
}

if(Metric.width >= WidthOffset) {
line[i+1] = '\n';
line[i+2] = '\0';

if(Metric.width > WidthOffset) {
k = 0;
while(Metric.width > WidthOffset) {
Info->text[strlen(Info->text)-1] = '\0';
line[strlen(line)-1] = '\0';
Info->text[strlen(Info->text)-1] = '\n';
line[strlen(line)-1] = '\n';
(void) GetTypeMetrics(Pic,Info,&Metric);
k -= 2;
}
//k -= 1;
} else {
k = 0;
}

if(s == 0) {
buffer = strcpy(buffer,line);
buffer[strlen(buffer)] = '\0';

} else {
strncpy(&buffer[strlen(buffer)],line,strlen(line));
buffer[strlen(buffer)] = '\0';
}

free(line);
line = (char*) malloc(strlen(pic_text) + 1);
line = (char*) memset(line,0,strlen(pic_text) + 1);

j = (j == 0) ? i+k : j+k;
s++; i = -1;
w = (Metric.width > w) ? Metric.width : w; h += Metric.height;

}

if(h > atof(argv[3]) || (ml != 0 && s >= ml)) {
printf("Text is too long, do something...",
&pic_text[(j == 0) ? i : j]);
system("PAUSE");
exit(EXIT_SUCCESS);
}

if(j != 0) j++;

}

Info->text = buffer;

// This is only for testing, just to make sure the text fits.

unsigned char * PxArray = malloc((sizeof(unsigned char)*w*h)*3);

for(i=0; i<(w*h*3); i+=3) {
PxArray[i] =   (unsigned char) ScaleCharToQuantum(242);
PxArray[i+1] = (unsigned char) ScaleCharToQuantum(240);
PxArray[i+2] = (unsigned char) ScaleCharToQuantum(213);
}

Image* img = ConstituteImage(w,h,"RGB",CharPixel,PxArray,&exception);

DrawingWand *Wand = NewDrawingWand();

Wand = DrawAllocateWand(Info, img);

DrawAnnotation(Wand,0,0,buffer);
DrawRender(Wand);

(void) strcpy(img->filename,"/newpic1234.jpg");

printf("'%s\n\nH: %f W: %f Lines: %d'\n",buffer,h,w,s);

WriteImage(Ni,img);

DestroyDrawInfo(Info);
DestroyImage(Pic);
DestroyExceptionInfo(&exception);

system("PAUSE");

return 0;
}```
Any help would be appreciated!