// Last updated 2008/12/03 11:44

// From: https://imagemagick.org.cn/discourse-server/viewtopic.php?f=18&t=12079
#include <windows.h>
#include <wand/magick_wand.h>

/*
	 0 character width
	 1 character height
	 2 ascender
	 3 descender
	 4 text width
	 5 text height
	 6 maximum horizontal advance
	 7 bounding box: x1
	 8 bounding box: y1
	 9 bounding box: x2
	10 bounding box: y2
	11 origin: x
	12 origin: y

example font metrics from my tcl script test_metrics.tcl

Arial 48
CWxCH = 48.0 x 48.0 AxD = 44.0 x -11.0 TWxTH = 248.0 x 55.0 MHA = 96.0
   BB = (0.0,0.0) (48.0,35.0) origin = 249.0 x 0.0

Arial 24
CWxCH = 24.0 x 24.0 AxD = 22.0 x -6.0 TWxTH = 125.0 x 28.0 MHA = 48.0
   BB = (0.0,0.0) (23.0,17.0) origin = 126.0 x 0.0

Times-New-Roman 18
CWxCH = 18.0 x 18.0 AxD = 17.0 x -4.0 TWxTH = 87.0 x 21.0 MHA = 36.0
   BB = (0.0,0.0) (16.859375,13.0) origin = 87.0 x 0.0

Times-New-Roman 72
CWxCH = 72.0 x 72.0 AxD = 65.0 x -16.0 TWxTH = 352.0 x 83.0 MHA = 144.0
   BB = (0.0,-1.0) (67.453125,50.0) origin = 352.0 x 0.0
*/
// Set up the drawingwand "dw" for the given font name, font size, and colour.
// If the font or size changes return the new width of a space (metric[4]) in sx
// (the magickwand is required if it is necessary to query the font metrics)
void draw_setfont(MagickWand *mw,DrawingWand *dw,unsigned char *font,int size,unsigned char *colour,int *sx)
{
	double *fm;
	PixelWand *pw = NULL;
	int sflag = 0;

	if(font && *font) {
		DrawSetFont(dw,font);
		sflag = 1;
	}
	if(colour && *colour) {
		pw = NewPixelWand();
		PixelSetColor(pw,colour);
		DrawSetFillColor(dw,pw);
		DestroyPixelWand(pw);
		sflag = 1;
	}
	if(size) {
		DrawSetFontSize(dw,size);
	}
	// If either the font or the fontsize (or both) have changed
	// we need to get the size of a space again
	if(sflag) {
		fm = MagickQueryFontMetrics(mw, dw, " ");
		*sx = (int)fm[4];
		RelinquishMagickMemory(fm);
	}
}

// sx is the width of a space in the current font and fontsize. 
// If the font or fontsize is changed a new value for the space
// width must be obtained before calling this again (by calling draw_setfont)

// The easiest (?) way to handle vertical text placement is
// not to use gravity at all because then you know that all the text is
// placed relative to ImageMagick's (0,0) coordinate which is the top left of
// the screen and the baseline will be y=0.
void draw_metrics(MagickWand *mw,DrawingWand *dw,int *dx,int *dy,int sx,unsigned char *text)
{
	double *fm;

	MagickAnnotateImage(mw, dw, *dx, *dy, 0, text);
	MagickDrawImage(mw,dw);
	// get the font metrics
	fm = MagickQueryFontMetrics(mw, dw, text);
	if(fm) {
		// Adjust the new x coordinate
		*dx += (int)fm[4]+sx;
		RelinquishMagickMemory(fm);
	}
}

void test_wand(LPTSTR lpCmdLine)
{

	MagickWand *mw = NULL;
	DrawingWand *dw = NULL;
	PixelWand *pw = NULL;
	// Current coordinates of text
	int dx,dy;
	// Width of a space in current font/size	
	int sx;
	double *fm = NULL;

	MagickWandGenesis();
	mw = NewMagickWand();
	dw = NewDrawingWand();
	pw = NewPixelWand();
	// Set the size of the image
	MagickSetSize(mw,300,100);
//	MagickSetImageAlphaChannel(mw,SetAlphaChannel);
	MagickReadImage(mw,"xc:white");

	// DO NOT SET GRAVITY - it makes text placement more complicated
	// (unless it does exactly what you wanted anyway).

	// Start near the left edge
	dx = 10;
	
	// If we know the largest font we're using, we can set the y coordinate
	// fairly accurately. In this case it is the 72 point Times font, so to
	// place the text such that the largest almost touches the top of the image
	// we just add the text height to the descender to give the coordinate for
	// our baseline.
	// In this case the largest is the 72 point Times-New-Roman so I'll use that
	// to compute the baseline
	DrawSetFontSize(dw,72);
	DrawSetFont(dw,"Times-New-Roman");
	fm = MagickQueryFontMetrics(mw, dw,"M");
	dy = fm[1]+fm[3];
	// Note that we must free up the fontmetric array once we're done with it
	RelinquishMagickMemory(fm);


// this
	draw_setfont(mw,dw,"Arial",48,"#40FF80",&sx);
	draw_metrics(mw,dw,&dx,&dy,sx,"this");

// is
	// A NULL signals to draw_setfont that the font stays the same
	draw_setfont(mw,dw,NULL,24,"#8040BF",&sx);
	draw_metrics(mw,dw,&dx,&dy,sx,"is");

// my
	draw_setfont(mw,dw,"Times-New-Roman",18,"#BF00BF",&sx);
	draw_metrics(mw,dw,&dx,&dy,sx,"my");

// text
	draw_setfont(mw,dw,NULL,72,"#0F0FBF",&sx);
	draw_metrics(mw,dw,&dx,&dy,sx,"text");
	MagickDrawImage(mw,dw);

	// Now write the magickwand image
	MagickWriteImage(mw,"metric1.gif");

	if(mw)mw = DestroyMagickWand(mw);
	if(dw)dw = DestroyDrawingWand(dw);
	if(pw)pw = DestroyPixelWand(pw);

	MagickWandTerminus();
}