亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? fonttext.cpp

?? Windows 圖形編程 書籍
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : fonttext.cpp						                                 //
//  Description: Generic font and text routines and classes                          //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#define WIN32_LEAN_AND_MEAN

#pragma pack(push, 4)
#include <windows.h>
#pragma pack(pop)

#include <tchar.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>

#include "fonttext.h"

// convert point size to logical coordinate space size
int PointSizetoLogical(HDC hDC, int points, int divisor)
{
	POINT P[2] = // two POINTs in device space whose distance is the needed height
	{
		{ 0, 0 },
		{ 0, ::GetDeviceCaps(hDC, LOGPIXELSY) * points } 
	};

	DPtoLP(hDC, P, 2); // map device coordinate to logical size
	
	return abs(P[1].y - P[0].y) / 72 / divisor;
}


// Create a font as large as EM square size for accurate metrics
HFONT CreateReferenceFont(HFONT hFont, int & emsquare)
{
	LOGFONT           lf;
	OUTLINETEXTMETRIC otm[3]; // big enough for the strings

	HDC hDC      = GetDC(NULL);
	HGDIOBJ hOld = SelectObject(hDC, hFont);
	int size = GetOutlineTextMetrics(hDC, sizeof(otm), otm);
	SelectObject(hDC, hOld);
	ReleaseDC(NULL, hDC);

	if ( size )								// TrueType
	{
		GetObject(hFont, sizeof(lf), & lf);

		emsquare    = otm[0].otmEMSquare; // get EM square size
		lf.lfHeight = - emsquare;		  // font size for 1:1 mapping
		lf.lfWidth  = 0;				  // original proportion

		return CreateFontIndirect(&lf);
	}
	else
		return NULL;
}


// justify text string within a left..right margin
BOOL TextOutJust(HDC hDC, int left, int right, int y, LPCTSTR lpStr, int nCount, bool bAllowNegative, TCHAR cBreakChar)
{
	SIZE size;
	
	SetTextJustification(hDC, 0, 0);

	GetTextExtentPoint32(hDC, lpStr, nCount, & size);

	int nBreak = 0;
	for (int i=0; i<nCount; i++)
		if ( lpStr[i]==cBreakChar )
			nBreak ++;

	int breakextra = right - left - size.cx;
	
	if ( (breakextra<0) && ! bAllowNegative )
		breakextra =0;

	SetTextJustification(hDC, breakextra, nBreak);

	return TextOut(hDC, left, y, lpStr, nCount);
}


// ABC extent of a text string
// ( A0, B0, C0 ) + ( A1, B1, C1 ) = ( A0, B0+C0+A1+B1, C1 }
BOOL GetTextABCExtent(HDC hDC, LPCTSTR lpString, int cbString, long * pHeight, ABC * pABC)
{
	SIZE size;

	if ( ! GetTextExtentPoint32(hDC, lpString, cbString, & size) )
		return FALSE;

	* pHeight  = size.cy;
	pABC->abcB = size.cx;

	ABC abc; 
	GetCharABCWidths(hDC, lpString[0],          lpString[0],          & abc); // first
	pABC->abcB -= abc.abcA;
	pABC->abcA  = abc.abcA;

	GetCharABCWidths(hDC, lpString[cbString-1], lpString[cbString-1], & abc); // last
	pABC->abcB -= abc.abcC;
	pABC->abcC  = abc.abcC;

	return TRUE;
}


BOOL GetOpaqueBox(HDC hDC, LPCTSTR lpString, int cbString, RECT * pRect, int x, int y)
{
	long height;
	ABC  abc;

	if ( ! GetTextABCExtent(hDC, lpString, cbString, & height, & abc) )
		return FALSE;

	switch ( GetTextAlign(hDC) & (TA_LEFT | TA_RIGHT | TA_CENTER) )
	{
		case TA_LEFT    : break;
		case TA_RIGHT   : x -=   abc.abcB; break;
		case TA_CENTER  : x -= abc.abcB/2; break;
		default:		  assert(false);
	}

	switch ( GetTextAlign(hDC) & (TA_TOP | TA_BASELINE | TA_BOTTOM) )
	{
		case TA_TOP     : break;
		case TA_BOTTOM  : y = - height; break;
		case TA_BASELINE: 
			{
				TEXTMETRIC tm;
				GetTextMetrics(hDC, & tm);
				y = - tm.tmAscent;
			}
			break;
		default:		  assert(false);
	}

	pRect->left   = x + min(abc.abcA, 0);
	pRect->right  = x + abc.abcA + abc.abcB + max(abc.abcC, 0);
	pRect->top    = y;
	pRect->bottom = y + height;

	return TRUE;
}


// Pixel-level precise text alignment
BOOL PreciseTextOut(HDC hDC, int x, int y, LPCTSTR lpString, int cbString)
{
	long height;
	ABC  abc;

	if ( GetTextABCExtent(hDC, lpString, cbString, & height, & abc) )
		switch ( GetTextAlign(hDC) & (TA_LEFT | TA_RIGHT | TA_CENTER) )
		{
			case TA_LEFT  : x -= abc.abcA;    break;
			case TA_RIGHT : x += abc.abcC;    break;
			case TA_CENTER: x -= (abc.abcA-abc.abcC)/2;  break;
		}

	return TextOut(hDC, x, y, lpString, cbString);
}


KGlyph::~KGlyph(void)
{
	if ( m_pPixels )
	{
		delete [] m_pPixels;
		m_pPixels = NULL;
	}
}


DWORD KGlyph::GetGlyph(HDC hDC, UINT uChar, UINT uFormat, const MAT2 * pMat2)
{
	MAT2 mat2;

	if ( pMat2==NULL )
	{
		memset(&mat2, 0, sizeof(mat2));
		mat2.eM11.value = 1;
		mat2.eM22.value = 1;
		pMat2 = & mat2;
	}
	
	// query size
	m_nDataSize = GetGlyphOutline(hDC, uChar, uFormat, & m_metrics, 0, NULL, pMat2);

	if ( (m_nDataSize==0) || (m_nDataSize==GDI_ERROR) )
		return m_nDataSize;

	if ( m_pPixels && (m_nDataSize > m_nAllocSize) ) // deallocate if too small
	{
		delete m_pPixels;
		m_pPixels = NULL;
	}
		
	if ( m_pPixels==NULL )
	{
		m_pPixels = new BYTE[m_nDataSize];	// new buffer allocation
		assert(m_pPixels);
		m_nAllocSize   = m_nDataSize;
	}

	m_uFormat = uFormat;
	// real data
	m_nDataSize = GetGlyphOutline(hDC, uChar, uFormat, & m_metrics, m_nAllocSize, m_pPixels, pMat2);

	return m_nDataSize;
}


typedef struct
{
	BITMAPINFOHEADER bmiHeader;
	RGBQUAD			 bmiColors[256];
}	BITMAPINFO8BPP;



BOOL KGlyph::DrawGlyphROP(HDC hDC, int x, int y, DWORD rop, COLORREF crBack, COLORREF crFore)
{
	int levels;

	switch (m_uFormat & 0x0F )
	{
		case GGO_BITMAP:       levels =  2; break;
		case GGO_GRAY2_BITMAP: levels =  5; break;
		case GGO_GRAY4_BITMAP: levels = 17; break;
		case GGO_GRAY8_BITMAP: levels = 65; break;

		default:
			return FALSE;
	}

	BITMAPINFO8BPP bmi;
	memset(& bmi, 0, sizeof(bmi));
	
	bmi.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth    =     m_metrics.gmBlackBoxX;
	bmi.bmiHeader.biHeight   = 0 - m_metrics.gmBlackBoxY; // top-down DIB
	bmi.bmiHeader.biPlanes   = 1;
	
	if ( levels==2 )
	{
		bmi.bmiHeader.biBitCount = 1;

		bmi.bmiColors[0].rgbRed   = GetRValue(crBack);
		bmi.bmiColors[0].rgbGreen = GetGValue(crBack);
		bmi.bmiColors[0].rgbBlue  = GetBValue(crBack);

		bmi.bmiColors[1].rgbRed   = GetRValue(crFore);
		bmi.bmiColors[1].rgbGreen = GetGValue(crFore);
		bmi.bmiColors[1].rgbBlue  = GetBValue(crFore);
	}
	else
	{
		bmi.bmiHeader.biBitCount = 8;
		
//		KColor back(crBack); back.ToHLS();
//		KColor fore(crFore); fore.ToHLS();
	
		for (int i=0; i<levels; i++)
		{
//			KColor m;

//			m.hue        = (back.hue        * (levels-i-1) + fore.hue        * i ) / (levels-1);
//			m.lightness  = (back.lightness  * (levels-i-1) + fore.lightness  * i ) / (levels-1);
//			m.saturation = (back.saturation * (levels-i-1) + fore.saturation * i ) / (levels-1);
//			m.ToRGB();

//			bmi.bmiColors[i].rgbRed   = m.red;
//			bmi.bmiColors[i].rgbGreen = m.green;
//			bmi.bmiColors[i].rgbBlue  = m.blue;

			bmi.bmiColors[i].rgbRed   = (GetRValue(crBack) * (levels-i-1) + GetRValue(crFore) * i ) / (levels-1);
			bmi.bmiColors[i].rgbGreen = (GetGValue(crBack) * (levels-i-1) + GetGValue(crFore) * i ) / (levels-1);
			bmi.bmiColors[i].rgbBlue  = (GetBValue(crBack) * (levels-i-1) + GetBValue(crFore) * i ) / (levels-1);
		}
	}

	return StretchDIBits(hDC, 
				x, y, m_metrics.gmBlackBoxX, m_metrics.gmBlackBoxY,
				0, 0, m_metrics.gmBlackBoxX, m_metrics.gmBlackBoxY,
				m_pPixels,
				(const BITMAPINFO *) & bmi,
				DIB_RGB_COLORS, rop);
}


// assuming TA_LEFT | TA_BASELINE alignment
BOOL KGlyph::DrawGlyph(HDC hDC, int x, int y, int & dx, int & dy)
{
	dx = m_metrics.gmCellIncX; // advancement
	dy = m_metrics.gmCellIncY;

	if ( GetBkMode(hDC)==OPAQUE ) // may overlap with next glyph
	{
		// black box is not big enough, need to calculate actual background box
		RECT opaque;

		TEXTMETRIC tm;
		GetTextMetrics(hDC, & tm);

		opaque.left   = min(x,                        x + m_metrics.gmptGlyphOrigin.x);
		opaque.right  = max(x + m_metrics.gmCellIncX, x + m_metrics.gmptGlyphOrigin.x + (int) m_metrics.gmBlackBoxX);
		opaque.top    = y - tm.tmAscent;
		opaque.bottom = y + tm.tmDescent;

		HBRUSH hBackBrush = CreateSolidBrush(GetBkColor(hDC));
		FillRect(hDC, & opaque, hBackBrush);
		DeleteObject(hBackBrush);
	}

	// if foreground color, use pen color, otherwise donot change desitnation

	HBRUSH hBrush = CreateSolidBrush(GetTextColor(hDC));
	HBRUSH hOld   = (HBRUSH) SelectObject(hDC, hBrush);

	BOOL rslt = DrawGlyphROP(hDC, 
					x + m_metrics.gmptGlyphOrigin.x, 
					y - m_metrics.gmptGlyphOrigin.y, 
					0xE20746,				// D^(S&(P^D)) -> if (S) P else D
					RGB(0,    0,    0),		// 0 -> 0
					RGB(0xFF, 0xFF, 0xFF));	// 1 -> 1

	SelectObject(hDC, hOld);
	DeleteObject(hBrush);

	return rslt;
}



FIXED MakeFixed(double value)
{
	long val = (long) (value * 65536);

	return * (FIXED *) & val;
}


BOOL OutlineTextOut(HDC hDC, int x, int y, const TCHAR * str, int count)
{
	if ( count<0 )
		count = _tcslen(str);

	KGlyph             glyph;
	KGlyphOutline<512> outline;

//	MAT2 mat2;
//	mat2.eM11 = MakeFixed(cos(0.1));
//	mat2.eM12 = MakeFixed(sin(0.1));
//	mat2.eM21 = MakeFixed(-sin(0.1));
//	mat2.eM22 = MakeFixed(cos(0.1));

	while ( count>0 )
	{
		if ( glyph.GetGlyph(hDC, * str, GGO_NATIVE/*, & mat2*/)>0 )
			if ( outline.DecodeOutline(glyph) )
				outline.Draw(hDC, x, y);

		x += glyph.m_metrics.gmCellIncX;
		y += glyph.m_metrics.gmCellIncY;

		str ++; 
		count --;
	}

	return TRUE;
}


BOOL BitmapTextOut(HDC hDC, int x, int y, const TCHAR * str, int count, int format)
{
	if ( count<0 )
		count = _tcslen(str);

	KGlyph glyph;

	while ( count>0 )
	{
		int dx=0, dy=0;

		if ( glyph.GetGlyph(hDC, * str, format)>0 )
			glyph.DrawGlyph(hDC, x, y, dx, dy);

		x += dx;
		y += dy;

		str ++; 
		count --;
	}

	return TRUE;
}


BOOL BitmapTextOutROP(HDC hDC, int x, int y, const TCHAR * str, int count, DWORD rop)
{
	if ( count<0 )
		count = _tcslen(str);

	KGlyph glyph;

	COLORREF crBack = GetBkColor(hDC);
	COLORREF crFore = GetTextColor(hDC);

	while ( count>0 )
	{
		if ( glyph.GetGlyph(hDC, * str, GGO_BITMAP)>0 )
			glyph.DrawGlyphROP(hDC, 
					x + glyph.m_metrics.gmptGlyphOrigin.x, 
					y - glyph.m_metrics.gmptGlyphOrigin.y, 
					rop, crBack, crFore);

		x += glyph.m_metrics.gmCellIncX;
		y += glyph.m_metrics.gmCellIncY;

		str ++; 
		count --;
	}

	return TRUE;
}


/////////////////////////////////////////////////////////////

// pixelsize: in logical space
BOOL KTextFormator::SetupPixel(HDC hDC, HFONT hFont, float pixelsize)
{
	OUTLINETEXTMETRIC otm[3]; // big enough for the strings

	if ( GetOutlineTextMetrics(hDC, sizeof(otm), otm)==0 )
		return FALSE;

	LOGFONT   lf;

	GetObject(hFont, sizeof(lf), & lf);

	int emsquare= otm[0].otmEMSquare; // get EM square size
	lf.lfHeight = - emsquare;		  // font size for 1:1 mapping
	lf.lfWidth  = 0;				  // original proportion

	HFONT hRefFont = CreateFontIndirect(&lf);

	HDC     hRefDC = CreateCompatibleDC(hDC);
	HGDIOBJ hOld   = SelectObject(hRefDC, hRefFont);
		
	int nCharWidth[MaxCharNo];

	GetCharWidth(hRefDC, 0, MaxCharNo-1, nCharWidth);
		
	if ( GetOutlineTextMetrics(hRefDC, sizeof(otm), otm)==0 )
		return FALSE;

	SelectObject(hRefDC, hOld);
		
	DeleteObject(hRefDC);
	DeleteObject(hRefFont);

	m_fHeight    = otm[0].otmTextMetrics.tmHeight * pixelsize / emsquare;
	m_fLinespace = ( otm[0].otmTextMetrics.tmHeight + otm[0].otmTextMetrics.tmExternalLeading) * pixelsize / emsquare;
	
	for (int i=0; i<MaxCharNo; i++)
		m_fCharWidth[i] = ((float) nCharWidth[i]) * pixelsize / emsquare;
		
	return TRUE;
}


BOOL KTextFormator::Setup(HDC hDC, HFONT hFont, float pointsize)
{
	return SetupPixel(hDC, hFont, pointsize * GetDeviceCaps(hDC, LOGPIXELSY) / 72);
}


BOOL KTextFormator::GetTextExtent(HDC hdc, LPCTSTR lpString, int cbString, float & width, float & height)
{
	if ( cbString<=0 )
		cbString = _tcslen(lpString);

	width = 0;
		
	for (int i=0; i<cbString; i++)
		width = width + m_fCharWidth[lpString[i]];

	height = m_fHeight;

	return TRUE;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久精品国内一区二区三区| 日韩一区欧美一区| 日韩亚洲欧美一区| 精品久久久久一区二区国产| 国产亚洲欧洲一区高清在线观看| 久久精品一区四区| 亚洲午夜私人影院| 免费视频一区二区| 一本色道久久综合亚洲91| 欧美无乱码久久久免费午夜一区| 日韩一二三四区| 亚洲欧美日韩国产手机在线 | 五月婷婷久久综合| 国产高清在线精品| 欧美图片一区二区三区| 久久综合狠狠综合久久激情| 一个色妞综合视频在线观看| 国内精品久久久久影院色| 日韩欧美一区在线观看| 亚洲欧洲国产日韩| 国产精品一级在线| 日韩欧美高清一区| 五月婷婷综合网| 欧美一区二区视频在线观看| 亚洲一区二区在线播放相泽| 成人激情电影免费在线观看| 精品国产伦理网| 久久电影国产免费久久电影| 欧美日韩激情在线| 亚洲国产中文字幕在线视频综合| 成人免费的视频| 中文字幕乱码亚洲精品一区| 国内欧美视频一区二区| 在线观看视频一区二区欧美日韩| 久久精品一区二区三区不卡| 久久99久国产精品黄毛片色诱| aaa亚洲精品一二三区| 国产午夜精品久久久久久久| 免费成人在线视频观看| 欧美高清激情brazzers| 亚洲成人黄色小说| 欧美日韩你懂得| 午夜精品福利一区二区三区蜜桃| 狠狠色丁香久久婷婷综| 日韩久久久精品| 香蕉影视欧美成人| 欧美日韩一级黄| 久久99精品久久久久久国产越南| 91麻豆精品国产| 国产一区二区电影| 日本视频一区二区| 成人高清免费观看| 91精品在线一区二区| 日韩中文字幕不卡| 久久久亚洲精品石原莉奈| av亚洲精华国产精华| 亚洲一区二区在线免费看| 欧美一区二区三区日韩| 国产一区二三区| 亚洲人成小说网站色在线| 在线播放一区二区三区| 成人网男人的天堂| 亚洲最新在线观看| 久久色在线观看| 色老汉一区二区三区| 亚洲久草在线视频| 欧美精品一区二区三区视频 | 成人午夜视频在线| 一区二区三区欧美在线观看| 精品久久久三级丝袜| 成人va在线观看| 美女视频黄a大片欧美| 亚洲精品欧美激情| 国产亚洲污的网站| 日韩精品一区二区三区视频 | 不卡一卡二卡三乱码免费网站| 午夜伦欧美伦电影理论片| 欧美国产精品中文字幕| 欧美电影免费提供在线观看| 在线观看视频一区二区欧美日韩| 福利一区二区在线| 国产精品自在欧美一区| 人妖欧美一区二区| 亚洲va韩国va欧美va| 久久精品99久久久| 免费看黄色91| 国产日韩av一区二区| 欧美在线free| 欧美揉bbbbb揉bbbbb| 色综合久久久久综合99| 91天堂素人约啪| 91亚洲午夜精品久久久久久| 粉嫩av一区二区三区| 成人动漫一区二区在线| av一区二区三区在线| av不卡在线观看| 欧美视频一区二区三区| 欧美日韩精品系列| 日韩精品一区二区三区视频播放| 欧美大片免费久久精品三p| 91福利视频久久久久| 91麻豆精品国产91久久久久久久久| 欧美一三区三区四区免费在线看 | 亚洲人吸女人奶水| 一区二区三区成人在线视频| 亚洲精品自拍动漫在线| 日本91福利区| 成人av在线资源网站| 在线观看av一区| 欧美成va人片在线观看| 精品99一区二区三区| 伊人夜夜躁av伊人久久| 国产在线精品一区二区夜色| 九色综合国产一区二区三区| av在线播放一区二区三区| 精品人在线二区三区| 亚洲乱码中文字幕综合| 国产精品一线二线三线| 色婷婷久久综合| 亚洲国产成人午夜在线一区 | 一区二区三区不卡视频在线观看 | 不卡一区二区三区四区| 欧美日韩精品是欧美日韩精品| 国产精品毛片a∨一区二区三区| 亚洲成人动漫av| 欧洲视频一区二区| 中文字幕日韩一区| 成人av电影在线观看| 国产精品久久久久久久久免费樱桃| 日本sm残虐另类| 欧美成人三级在线| 免费观看在线综合| 欧美美女一区二区在线观看| 亚洲欧美经典视频| 色综合av在线| 亚洲丝袜制服诱惑| 欧美性三三影院| 亚洲一二三四在线观看| 在线免费观看日韩欧美| 亚洲精品日产精品乱码不卡| 91国偷自产一区二区开放时间 | 日韩一区精品视频| 色av成人天堂桃色av| 一区二区国产视频| 日韩精品中午字幕| 激情亚洲综合在线| 亚洲精品日日夜夜| 日韩一区二区三区三四区视频在线观看| 亚洲一区日韩精品中文字幕| 91麻豆精品国产91| 国产成人精品www牛牛影视| 久久亚洲免费视频| 欧美视频在线一区| 久久精品国产精品亚洲红杏| 日本一区二区久久| 欧美三级日韩在线| 粉嫩在线一区二区三区视频| 亚洲欧美日韩在线| 精品国产一区二区三区忘忧草| 久久er精品视频| 亚洲免费资源在线播放| 精品日韩一区二区三区免费视频| 国产不卡视频在线播放| 日本午夜精品一区二区三区电影| 欧美激情一区在线观看| 欧美一区二区三区在线视频| 97se狠狠狠综合亚洲狠狠| 久久99热这里只有精品| 亚洲大片免费看| 亚洲美女屁股眼交| 日本一区二区三区国色天香 | 欧美成人在线直播| 91精品国产综合久久精品性色| aaa欧美色吧激情视频| av激情亚洲男人天堂| 精品综合久久久久久8888| 轻轻草成人在线| 国产高清在线观看免费不卡| 粉嫩绯色av一区二区在线观看| 99国产一区二区三精品乱码| 欧美在线啊v一区| 精品日本一线二线三线不卡| 国产欧美日韩麻豆91| 亚洲一区中文在线| 极品美女销魂一区二区三区免费| 激情小说亚洲一区| 色吊一区二区三区| 欧美精品一区二区三区很污很色的 | 国产日产欧美一区二区视频| 日韩美女久久久| 精品一区二区三区日韩| 91在线视频播放| 久久―日本道色综合久久| 亚洲欧美国产三级| 国产一区不卡视频| 91精品国产福利| 亚洲福利国产精品| 成人黄色av电影| 26uuu国产日韩综合| 三级亚洲高清视频|