//******************************************************************************
//
// MIDITrail / MTFontTexture
//
// フォントテクスチャクラス
//
// Copyright (C) 2010-2017 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "YNBaseLib.h"
#import "MTFontTexture.h"
#import <CoreText/CoreText.h>


//******************************************************************************
// コンストラクタ
//******************************************************************************
MTFontTexture::MTFontTexture(void)
{
	m_pFontName = nil;
	m_FontSize = 0;
	m_TexHeight = 0;
	m_TexWidth = 0;
}

//******************************************************************************
// デストラクタ
//******************************************************************************
MTFontTexture::~MTFontTexture(void)
{
	Clear();
}

//******************************************************************************
// クリア
//******************************************************************************
void MTFontTexture::Clear()
{
	[m_pFontName release];
	m_pFontName = nil;
	m_Texture.Release();
}

//******************************************************************************
// フォント設定
//******************************************************************************
int MTFontTexture::SetFont(
		NSString* pFontName,
		float fontSize,
		OGLCOLOR color,
		bool isForceFixedPitch
	)
{
	int result = 0;
	
	[pFontName retain];
	[m_pFontName release];
	m_pFontName = pFontName;
	m_FontSize = fontSize;
	m_Color = color;
	m_isForceFiexdPitch = isForceFixedPitch;
	
EXIT:;
	return result;
}

//******************************************************************************
// テクスチャ生成
//******************************************************************************
int MTFontTexture::CreateTexture(
		OGLDevice* pOGLDevice,
		NSString* pStr
	)
{
	int result = 0;
	UIFont* pFont = nil;
	UIColor* pTextColor = nil;
	UIImage* pImage = nil;
	CGSize frameSize;
	size_t bmpWidth = 0.0f;
	size_t bmpHeight = 0.0f;
	GLubyte* pBmpBuf = NULL;
	CGContextRef pContext = NULL;
	CGColorSpaceRef pColorSpace = NULL;
	CGImageRef cgImageRef = NULL;
    NSMutableParagraphStyle* pStyle = nil;
    NSDictionary* pAttributes = nil;
    
    //フォント
	pFont = [UIFont fontWithName:m_pFontName size:m_FontSize];
	if (pFont == nil) {
		result = YN_SET_ERR(@"Invalid font name.", 0, 0);
		goto EXIT;
	}
	
	//テキスト色
	pTextColor = [UIColor colorWithRed:m_Color.r
								 green:m_Color.g
								  blue:m_Color.b
								 alpha:m_Color.a];
	
	//フォント描画時のサイズを取得
	//frameSize = [pStr sizeWithFont:pFont];
    frameSize = [pStr sizeWithAttributes:@{NSFontAttributeName:pFont}];
	
    //小数点以下の値は切り上げる
	bmpWidth = ceil((double)(frameSize.width));
	bmpHeight = ceil((double)(frameSize.height));
    
    //テクスチャ画像の最大サイズを超える場合はクリップする
    if (bmpWidth > OGL_TEXTURE_IMAGE_MAX_WIDTH) {
		bmpWidth = OGL_TEXTURE_IMAGE_MAX_WIDTH;
		//NSLog(@"WARNING: The texture image was clipped. width:%f", frameSize.width);
	}
	if (bmpHeight > OGL_TEXTURE_IMAGE_MAX_HEIGHT) {
		bmpHeight = OGL_TEXTURE_IMAGE_MAX_HEIGHT;
		//NSLog(@"WARNING: The texture image was clipped. height:%f", frameSize.height);
	}	
	
	//描画に必要なサイズのメモリを確保
	pBmpBuf = (GLubyte*)malloc(bmpWidth * bmpHeight * 4);
	if (pBmpBuf == NULL) {
		result = YN_SET_ERR(@"Could not allocate memory.", bmpWidth, bmpHeight);
		goto EXIT;
	}
	memset(pBmpBuf, 0, bmpWidth * bmpHeight * 4);
	
	//ビットマップコンテキストを作成：確保したメモリを描画先とする
	pColorSpace= CGColorSpaceCreateDeviceRGB();
	pContext = CGBitmapContextCreate(
						pBmpBuf,			//描画位置
						bmpWidth,			//幅(pixcel)
						bmpHeight,			//高さ(pixcel)
						8,					//コンポーネントごとのビット数
						bmpWidth * 4,		//1ラインごとのメモリサイズ(byte)
						pColorSpace,		//カラースペース
						kCGImageAlphaPremultipliedLast	//ビットマップ情報：RGBA
					);
	if (pContext == NULL) {
		result = YN_SET_ERR(@"Quartz API error.", 0, 0);
		goto EXIT;
	}
	
	//コンテキストを登録
	UIGraphicsPushContext(pContext);
	
	//アンチエイリアスを有効化
	CGContextSetAllowsAntialiasing(pContext, true);
	
	//文字列が上下反転して描画されるため座標変換を指示する
	//  座標原点移動
	CGContextTranslateCTM(pContext, 0, bmpHeight);
	//  スケール変換：X軸ファクタ(1) Y軸ファクタ(-1)
	CGContextScaleCTM(pContext, 1, -1);	

	//描画色をセット
	[pTextColor set]; 
	
	//描画
	//[pStr drawInRect:CGRectMake(0, 0, bmpWidth, bmpHeight)
	//		withFont:pFont
	//   lineBreakMode:UILineBreakModeClip
	//	   alignment:UITextAlignmentLeft];
    pStyle = [[NSMutableParagraphStyle alloc] init];
    [pStyle setLineBreakMode:NSLineBreakByClipping];
    [pStyle setAlignment:NSTextAlignmentLeft];
    pAttributes = @{NSFontAttributeName:pFont,
                    NSParagraphStyleAttributeName:pStyle};
    [pStr drawInRect:CGRectMake(0, 0, bmpWidth, bmpHeight) withAttributes:pAttributes];
    
	//コンテキストを解除
	UIGraphicsPopContext();
	
	//コンテキストからUIImageを作成
	cgImageRef = CGBitmapContextCreateImage(pContext);
	pImage = [UIImage imageWithCGImage:cgImageRef];
	
	//テクスチャ生成
	result = m_Texture.LoadBitmap(pImage);
	if (result != 0) goto EXIT;
	
	m_TexWidth = m_Texture.GetWidth();
	m_TexHeight = m_Texture.GetHeight();
	
EXIT:;
	if (pBmpBuf != NULL) free(pBmpBuf);
	if (pContext != NULL) CFRelease(pContext);
	if (pColorSpace != NULL) CFRelease(pColorSpace);
	if (cgImageRef != NULL) CFRelease(cgImageRef);
	//autoreleaseされているオブジェクトは破棄しない
	//[pFont release];
	//[pTextColor release];
	//[pImage release];
    //[pStyle release];
    //[pAttributes release];
    return result;
}

//******************************************************************************
// テクスチャポインタ取得
//******************************************************************************
OGLTexture* MTFontTexture::GetTexture()
{
	return &m_Texture;
}

//******************************************************************************
// テクスチャサイズ取得
//******************************************************************************
void MTFontTexture::GetTextureSize(
		unsigned int* pHeight,
		unsigned int* pWidth
	)
{
	*pHeight = m_TexHeight;
	*pWidth = m_TexWidth;
}


