Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// character_manager.cpp: implementation of the TFont class.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//////////////////////////////////////////////////////////////////////
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpixelgr.h"
Toshihiro Shimizu 890ddd
#include "tfont.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
//#include "tcurves.h"
Toshihiro Shimizu 890ddd
#include "traster.h"
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
#include <iostream></iostream>
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
//#include <tstring.h></tstring.h>
Toshihiro Shimizu 890ddd
#include <tmathutil.h></tmathutil.h>
Toshihiro Shimizu 890ddd
//#include <tdebugmessage.h></tdebugmessage.h>
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef map<wstring, logfontw=""> WindowsFontTable;</wstring,>
Toshihiro Shimizu 890ddd
typedef map<pair<unsigned short="" short,="" unsigned="">, int> KerningPairs;</pair<unsigned>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TFont::Impl {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_hasKerning;
Toshihiro Shimizu 890ddd
	bool m_hasVertical;
Toshihiro Shimizu 890ddd
	HFONT m_font;
Toshihiro Shimizu 890ddd
	HDC m_hdc;
Toshihiro Shimizu 890ddd
	TEXTMETRICW m_metrics;
Toshihiro Shimizu 890ddd
	KerningPairs m_kerningPairs;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Impl(const LOGFONTW &font, HDC hdc);
Toshihiro Shimizu 890ddd
	~Impl();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont::TFont(const LOGFONTW &font, HDC hdc)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pimpl = new Impl(font, hdc);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont::~TFont()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_pimpl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont::Impl::Impl(const LOGFONTW &logfont, HDC hdc)
Toshihiro Shimizu 890ddd
	: m_hdc(hdc)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_font = CreateFontIndirectW(&logfont);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_font)
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	HGDIOBJ hObj = SelectObject(hdc, m_font);
Toshihiro Shimizu 890ddd
	if (!hObj || hObj == HGDI_ERROR)
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!GetTextMetricsW(hdc, &m_metrics))
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DWORD pairsCount = GetKerningPairsW(hdc, 0, 0);
Toshihiro Shimizu 890ddd
	if (pairsCount) {
Toshihiro Shimizu 890ddd
		m_hasKerning = true;
Toshihiro Shimizu 890ddd
		KERNINGPAIR *tempKernPairs = new KERNINGPAIR[pairsCount];
Toshihiro Shimizu 890ddd
		GetKerningPairsW(hdc, pairsCount, tempKernPairs);
Toshihiro Shimizu 890ddd
		for (UINT i = 0; i < pairsCount; i++) {
Toshihiro Shimizu 890ddd
			pair<unsigned short="" short,="" unsigned=""> key = make_pair(tempKernPairs[i].wFirst, tempKernPairs[i].wSecond);</unsigned>
Toshihiro Shimizu 890ddd
			m_kerningPairs[key] = tempKernPairs[i].iKernAmount;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		delete[] tempKernPairs;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_hasKerning = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_hasVertical = (logfont.lfFaceName)[0] == '@';
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont::Impl::~Impl()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//delete m_advances;
Toshihiro Shimizu 890ddd
	DeleteObject(m_font);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
inline TThickPoint toThickPoint(POINTFX point)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double app1 = point.x.value + ((double)point.x.fract) / (std::numeric_limits<word>::max)();</word>
Toshihiro Shimizu 890ddd
	double app2 = point.y.value + ((double)point.y.fract) / (std::numeric_limits<word>::max)();</word>
Toshihiro Shimizu 890ddd
	return TThickPoint(app1, app2, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TFont::drawChar(TVectorImageP &image, wchar_t charcode, wchar_t nextCharCode) const
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	GLYPHMETRICS gm;
Toshihiro Shimizu 890ddd
	MAT2 mat2;
Toshihiro Shimizu 890ddd
	mat2.eM11.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM12.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM21.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM22.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM11.value = 1;
Toshihiro Shimizu 890ddd
	mat2.eM12.value = 0;
Toshihiro Shimizu 890ddd
	mat2.eM21.value = 0;
Toshihiro Shimizu 890ddd
	mat2.eM22.value = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT j = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DWORD charMemorySize = GetGlyphOutlineW(m_pimpl->m_hdc, charcode, GGO_NATIVE, &gm, 0, 0, &mat2);
Toshihiro Shimizu 890ddd
	if (charMemorySize == GDI_ERROR) {
Toshihiro Shimizu 890ddd
		assert(0);
Toshihiro Shimizu 890ddd
		return TPoint();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LPVOID lpvBuffer = new char[charMemorySize];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	charMemorySize = GetGlyphOutlineW(m_pimpl->m_hdc, charcode, GGO_NATIVE, &gm, charMemorySize, lpvBuffer, &mat2);
Toshihiro Shimizu 890ddd
	if (charMemorySize == GDI_ERROR) {
Toshihiro Shimizu 890ddd
		assert(0);
Toshihiro Shimizu 890ddd
		return TPoint();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)lpvBuffer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while ((char *)header < (char *)lpvBuffer + charMemorySize) {
Toshihiro Shimizu 890ddd
		points.clear();
Toshihiro Shimizu 890ddd
		TThickPoint startPoint = toThickPoint(header->pfxStart);
Toshihiro Shimizu 890ddd
		points.push_back(startPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (header->dwType != TT_POLYGON_TYPE) {
Toshihiro Shimizu 890ddd
			assert(0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		int memorySize = header->cb;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTPOLYCURVE *curve = (TTPOLYCURVE *)(header + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		while ((char *)curve < (char *)header + memorySize) {
Toshihiro Shimizu 890ddd
			switch (curve->wType) {
Toshihiro Shimizu 890ddd
			case TT_PRIM_LINE:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (j = 0; j < curve->cpfx; j++) {
Toshihiro Shimizu 890ddd
					TThickPoint p0 = points.back();
Toshihiro Shimizu 890ddd
					TThickPoint p1 = toThickPoint(((*curve).apfx[j]));
Toshihiro Shimizu 890ddd
					points.push_back((p0 + p1) * 0.5);
Toshihiro Shimizu 890ddd
					points.push_back(p1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			case TT_PRIM_QSPLINE:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (j = 0; (int)j + 2 < curve->cpfx; j++) {
Toshihiro Shimizu 890ddd
					TThickPoint p1 = toThickPoint(((*curve).apfx[j]));
Toshihiro Shimizu 890ddd
					TThickPoint p2 = toThickPoint(((*curve).apfx[j + 1]));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					points.push_back(p1);
Toshihiro Shimizu 890ddd
					points.push_back((p1 + p2) * 0.5);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				points.push_back(toThickPoint(((*curve).apfx[j++])));
Toshihiro Shimizu 890ddd
				points.push_back(toThickPoint(((*curve).apfx[j++])));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			case TT_PRIM_CSPLINE:
Toshihiro Shimizu 890ddd
				assert(0);
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			default:
Toshihiro Shimizu 890ddd
				assert(0);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			curve = (TTPOLYCURVE *)(&(curve->apfx)[j]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TThickPoint p0 = points.back();
Toshihiro Shimizu 890ddd
		if (!isAlmostZero(p0.x - startPoint.x) || !isAlmostZero(p0.y - startPoint.y)) {
Toshihiro Shimizu 890ddd
			points.push_back((p0 + startPoint) * 0.5);
Toshihiro Shimizu 890ddd
			points.push_back(startPoint);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStroke *stroke = new TStroke();
Toshihiro Shimizu 890ddd
		stroke->reshape(&(points[0]), points.size());
Toshihiro Shimizu 890ddd
		stroke->setSelfLoop(true);
Toshihiro Shimizu 890ddd
		image->addStroke(stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		header = (TTPOLYGONHEADER *)curve;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete[] lpvBuffer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	image->group(0, image->getStrokeCount());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return getDistance(charcode, nextCharCode);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint appDrawChar(TRasterGR8P &outImage, HDC hdc, wchar_t charcode)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	GLYPHMETRICS gm;
Toshihiro Shimizu 890ddd
	MAT2 mat2;
Toshihiro Shimizu 890ddd
	mat2.eM11.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM12.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM21.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM22.fract = 0;
Toshihiro Shimizu 890ddd
	mat2.eM11.value = 1;
Toshihiro Shimizu 890ddd
	mat2.eM12.value = 0;
Toshihiro Shimizu 890ddd
	mat2.eM21.value = 0;
Toshihiro Shimizu 890ddd
	mat2.eM22.value = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DWORD charMemorySize = GetGlyphOutlineW(hdc, charcode, GGO_GRAY8_BITMAP, &gm, 0, 0, &mat2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (charMemorySize == GDI_ERROR) {
Toshihiro Shimizu 890ddd
		assert(0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int lx = gm.gmBlackBoxX;
Toshihiro Shimizu 890ddd
	int ly = gm.gmBlackBoxY;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int wrap = ((lx + 3) >> 2) << 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterGR8P appImage = TRasterGR8P(wrap, ly);
Toshihiro Shimizu 890ddd
	appImage->clear();
Toshihiro Shimizu 890ddd
	outImage = appImage->extract(0, 0, lx - 1, ly - 1);
Toshihiro Shimizu 890ddd
	outImage->lock();
Toshihiro Shimizu 890ddd
	GetGlyphOutlineW(hdc, charcode, GGO_GRAY8_BITMAP, &gm, wrap * ly, outImage->getRawData(), &mat2);
Toshihiro Shimizu 890ddd
	outImage->unlock();
Toshihiro Shimizu 890ddd
	TPoint glyphOrig;
Toshihiro Shimizu 890ddd
	glyphOrig.x = gm.gmptGlyphOrigin.x;
Toshihiro Shimizu 890ddd
	glyphOrig.y = gm.gmptGlyphOrigin.y;
Toshihiro Shimizu 890ddd
	return glyphOrig;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//valori compresi tra 0 e 64 (si si, proprio 64 e non 63: sono 65 valori)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TFont::drawChar(TRasterGR8P &outImage, TPoint &glyphOrigin, wchar_t charcode, wchar_t nextCharCode) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterGR8P grayAppImage;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPoint glyphOrig = appDrawChar(grayAppImage, m_pimpl->m_hdc, charcode);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (glyphOrig.x < 0) {
Toshihiro Shimizu 890ddd
		glyphOrigin.x = glyphOrig.x;
Toshihiro Shimizu 890ddd
		glyphOrig.x = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		glyphOrigin.x = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (glyphOrig.y < 0) {
Toshihiro Shimizu 890ddd
		glyphOrigin.y = glyphOrig.y;
Toshihiro Shimizu 890ddd
		glyphOrig.y = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		glyphOrigin.y = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int srcLx = grayAppImage->getLx();
Toshihiro Shimizu 890ddd
	int srcLy = grayAppImage->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int dstLx = srcLx + glyphOrig.x;
Toshihiro Shimizu 890ddd
	int dstLy = getMaxHeight();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	outImage = TRasterGR8P(dstLx, dstLy);
Toshihiro Shimizu 890ddd
	outImage->clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int ty = m_pimpl->m_metrics.tmDescent - 1 + glyphOrig.y;
Toshihiro Shimizu 890ddd
	assert(ty < dstLy);
Toshihiro Shimizu 890ddd
	assert(ty >= srcLy - 1);
Toshihiro Shimizu 890ddd
	grayAppImage->lock();
Toshihiro Shimizu 890ddd
	outImage->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int sy = 0; sy < srcLy; ++sy, --ty) {
Toshihiro Shimizu 890ddd
		TPixelGR8 *srcPix = grayAppImage->pixels(sy);
Toshihiro Shimizu 890ddd
		TPixelGR8 *tarPix = outImage->pixels(ty) + glyphOrig.x;
Toshihiro Shimizu 890ddd
		for (int x = 0; x < srcLx; ++x) {
Toshihiro Shimizu 890ddd
			assert(srcPix->value < 65);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			switch (srcPix->value) {
Toshihiro Shimizu 890ddd
			case 0:
Toshihiro Shimizu 890ddd
				tarPix->value = 0;
Toshihiro Shimizu 890ddd
			DEFAULT:
Toshihiro Shimizu 890ddd
				tarPix->value = (srcPix->value << 2) - 1;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			++srcPix;
Toshihiro Shimizu 890ddd
			++tarPix;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	grayAppImage->unlock();
Toshihiro Shimizu 890ddd
	outImage->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return getDistance(charcode, nextCharCode);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TFont::drawChar(TRasterCM32P &outImage, TPoint &glyphOrigin, int inkId, wchar_t charcode, wchar_t nextCharCode) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterGR8P grayAppImage;
Toshihiro Shimizu 890ddd
	TPoint glyphOrig = appDrawChar(grayAppImage, m_pimpl->m_hdc, charcode);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (glyphOrig.x < 0) {
Toshihiro Shimizu 890ddd
		glyphOrigin.x = glyphOrig.x;
Toshihiro Shimizu 890ddd
		glyphOrig.x = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		glyphOrigin.x = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (glyphOrig.y < 0) {
Toshihiro Shimizu 890ddd
		glyphOrigin.y = glyphOrig.y;
Toshihiro Shimizu 890ddd
		glyphOrig.y = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		glyphOrigin.y = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int srcLx = grayAppImage->getLx();
Toshihiro Shimizu 890ddd
	int srcLy = grayAppImage->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int dstLx = srcLx + glyphOrig.x;
Toshihiro Shimizu 890ddd
	int dstLy = getMaxHeight();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	outImage = TRasterCM32P(dstLx, dstLy);
Toshihiro Shimizu 890ddd
	outImage->clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(TPixelCM32::getMaxTone() == 255);
Toshihiro Shimizu 890ddd
	// TPixelCM32 bgColor(BackgroundStyle,BackgroundStyle,TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
	TPixelCM32 bgColor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int ty = m_pimpl->m_metrics.tmDescent - 1 + glyphOrig.y;
Toshihiro Shimizu 890ddd
	assert(ty < dstLy);
Toshihiro Shimizu 890ddd
	assert(ty >= srcLy - 1);
Toshihiro Shimizu 890ddd
	grayAppImage->lock();
Toshihiro Shimizu 890ddd
	outImage->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int sy = 0; sy < srcLy; ++sy, --ty) {
Toshihiro Shimizu 890ddd
		TPixelGR8 *srcPix = grayAppImage->pixels(sy);
Toshihiro Shimizu 890ddd
		TPixelCM32 *tarPix = outImage->pixels(ty) + glyphOrig.x;
Toshihiro Shimizu 890ddd
		for (int x = 0; x < srcLx; ++x) {
Toshihiro Shimizu 890ddd
			int tone = 256 - (srcPix->value << 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			// grayScale  ToonzImage tone   Meaning
Toshihiro Shimizu 890ddd
			//         0  255               Bg = PurePaint
Toshihiro Shimizu 890ddd
			//         1  252
Toshihiro Shimizu 890ddd
			//                 ...
Toshihiro Shimizu 890ddd
			//        63    4
Toshihiro Shimizu 890ddd
			//        64    0               Fg = Pure Ink
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (tone < 0)
Toshihiro Shimizu 890ddd
				tone = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (tone >= 255)
Toshihiro Shimizu 890ddd
				*tarPix = bgColor;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				*tarPix = TPixelCM32(inkId, 0, tone); // BackgroundStyle,tone);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			++srcPix;
Toshihiro Shimizu 890ddd
			++tarPix;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	grayAppImage->unlock();
Toshihiro Shimizu 890ddd
	outImage->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return getDistance(charcode, nextCharCode);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TFont::getDistance(wchar_t firstChar, wchar_t secondChar) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int advance;
Toshihiro Shimizu 890ddd
	BOOL result = GetCharWidth32W(m_pimpl->m_hdc, firstChar, firstChar, &advance);
Toshihiro Shimizu 890ddd
	assert(result);
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_hasKerning && secondChar) {
Toshihiro Shimizu 890ddd
		KerningPairs::iterator it = m_pimpl->m_kerningPairs.find(make_pair(firstChar, secondChar));
Toshihiro Shimizu 890ddd
		if (it != m_pimpl->m_kerningPairs.end()) {
Toshihiro Shimizu 890ddd
			advance += it->second;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return TPoint(advance, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TFont::getMaxHeight() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_pimpl->m_metrics.tmHeight;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TFont::getMaxWidth() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_pimpl->m_metrics.tmMaxCharWidth;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TFont::getLineAscender() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_pimpl->m_metrics.tmAscent;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TFont::getLineDescender() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return -m_pimpl->m_metrics.tmDescent;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TFont::hasKerning() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_pimpl->m_hasKerning;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TFont::hasVertical() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_pimpl->m_hasVertical;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//====================      TFontManager  =====================================
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TFontManager::Impl {
Toshihiro Shimizu 890ddd
	WindowsFontTable m_families;
Toshihiro Shimizu 890ddd
	bool m_loaded;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LOGFONTW m_currentLogFont;
Toshihiro Shimizu 890ddd
	TFont *m_currentFont;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// this option is set by library user when he wants to write vertically.
Toshihiro Shimizu 890ddd
	// In this implementation, if m_vertical is true and the font
Toshihiro Shimizu 890ddd
	// has the @-version, the library use it.
Toshihiro Shimizu 890ddd
	bool m_vertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFontManager::Impl()
Toshihiro Shimizu 890ddd
		: m_loaded(false), m_currentFont(0), m_vertical(false)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFontManager::TFontManager()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pimpl = new TFontManager::Impl();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFontManager::~TFontManager()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_pimpl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFontManager *TFontManager::instance()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static TFontManager theManager;
Toshihiro Shimizu 890ddd
	return &theManager;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
BOOL CALLBACK EnumFamCallBack(
Toshihiro Shimizu 890ddd
	CONST LOGFONTW *lplf,
Toshihiro Shimizu 890ddd
	CONST TEXTMETRICW *,
Toshihiro Shimizu 890ddd
	DWORD FontType,
Toshihiro Shimizu 890ddd
	LPARAM data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (FontType & TRUETYPE_FONTTYPE) {
Toshihiro Shimizu 890ddd
		LOGFONTW newLplf = *lplf;
Toshihiro Shimizu 890ddd
		newLplf.lfHeight = 200;
Toshihiro Shimizu 890ddd
		newLplf.lfWidth = 0;
Toshihiro Shimizu 890ddd
		WindowsFontTable &table = *(WindowsFontTable *)data;
Toshihiro Shimizu 890ddd
		table[lplf->lfFaceName] = newLplf;
Toshihiro Shimizu 890ddd
		return TRUE;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::loadFontNames()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_loaded)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	HDC hdc = CreateCompatibleDC(NULL);
Toshihiro Shimizu 890ddd
	if (!hdc)
Toshihiro Shimizu 890ddd
		throw TFontLibraryLoadingError();
Toshihiro Shimizu 890ddd
	EnumFontFamiliesW(hdc,
Toshihiro Shimizu 890ddd
					  (LPCWSTR)NULL,
Toshihiro Shimizu 890ddd
					  (FONTENUMPROCW)EnumFamCallBack,
Toshihiro Shimizu 890ddd
					  (LPARAM) & (m_pimpl->m_families));
Toshihiro Shimizu 890ddd
	DeleteDC(hdc);
Toshihiro Shimizu 890ddd
	hdc = 0;
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_families.empty())
Toshihiro Shimizu 890ddd
		throw TFontLibraryLoadingError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_pimpl->m_loaded = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::setFamily(const wstring family)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	wstring userFamilyName = ((family.c_str())[0] == L'@') ? wstring(family.c_str() + 1) : family;
Toshihiro Shimizu 890ddd
	wstring realFamilyName = (m_pimpl->m_vertical && (family.c_str())[0] != L'@') ? L"@" + family : family;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	wstring currentFamilyName = wstring(m_pimpl->m_currentLogFont.lfFaceName);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (currentFamilyName == realFamilyName)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LOGFONTW logfont;
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_vertical) {
Toshihiro Shimizu 890ddd
		WindowsFontTable::iterator it = m_pimpl->m_families.find(realFamilyName);
Toshihiro Shimizu 890ddd
		if (it != m_pimpl->m_families.end())
Toshihiro Shimizu 890ddd
			logfont = it->second;
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			it = m_pimpl->m_families.find(userFamilyName);
Toshihiro Shimizu 890ddd
			assert(it != m_pimpl->m_families.end());
Toshihiro Shimizu 890ddd
			if (it != m_pimpl->m_families.end())
Toshihiro Shimizu 890ddd
				logfont = it->second;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				throw TFontCreationError();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		WindowsFontTable::iterator it = m_pimpl->m_families.find(userFamilyName);
Toshihiro Shimizu 890ddd
		assert(it != m_pimpl->m_families.end());
Toshihiro Shimizu 890ddd
		if (it != m_pimpl->m_families.end())
Toshihiro Shimizu 890ddd
			logfont = it->second;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			throw TFontCreationError();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_currentFont) {
Toshihiro Shimizu 890ddd
		logfont.lfHeight = m_pimpl->m_currentLogFont.lfHeight;
Toshihiro Shimizu 890ddd
		logfont.lfItalic = m_pimpl->m_currentLogFont.lfItalic;
Toshihiro Shimizu 890ddd
		logfont.lfWeight = m_pimpl->m_currentLogFont.lfWeight;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		logfont.lfHeight = 200;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		HDC hdc = CreateCompatibleDC(NULL);
Toshihiro Shimizu 890ddd
		TFont *newfont = new TFont(logfont, hdc);
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = newfont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentLogFont = logfont;
Toshihiro Shimizu 890ddd
	} catch (TException &) {
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::setTypeface(const wstring typeface)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	LOGFONTW logfont = m_pimpl->m_currentLogFont;
Toshihiro Shimizu 890ddd
	logfont.lfItalic = (typeface == L"Italic" ||
Toshihiro Shimizu 890ddd
						typeface == L"Bold Italic")
Toshihiro Shimizu 890ddd
						   ? TRUE
Toshihiro Shimizu 890ddd
						   : FALSE;
Toshihiro Shimizu 890ddd
	logfont.lfWeight = (typeface == L"Bold" ||
Toshihiro Shimizu 890ddd
						typeface == L"Bold Italic")
Toshihiro Shimizu 890ddd
						   ? 700
Toshihiro Shimizu 890ddd
						   : 400;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		HDC hdc = CreateCompatibleDC(NULL);
Toshihiro Shimizu 890ddd
		TFont *newfont = new TFont(logfont, hdc);
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = newfont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentLogFont = logfont;
Toshihiro Shimizu 890ddd
	} catch (TException &) {
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::setSize(int size)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	LOGFONTW logfont = m_pimpl->m_currentLogFont;
Toshihiro Shimizu 890ddd
	logfont.lfHeight = size;
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		HDC hdc = CreateCompatibleDC(NULL);
Toshihiro Shimizu 890ddd
		TFont *newfont = new TFont(logfont, hdc);
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = newfont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentLogFont = logfont;
Toshihiro Shimizu 890ddd
	} catch (TException &) {
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
wstring TFontManager::getCurrentFamily() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	wstring currentFamilyName = (m_pimpl->m_currentLogFont.lfFaceName[0] == L'@') ? wstring(m_pimpl->m_currentLogFont.lfFaceName + 1) : wstring(m_pimpl->m_currentLogFont.lfFaceName);
Toshihiro Shimizu 890ddd
	return currentFamilyName;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
wstring TFontManager::getCurrentTypeface() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_currentLogFont.lfItalic) {
Toshihiro Shimizu 890ddd
		if (m_pimpl->m_currentLogFont.lfWeight == 700)
Toshihiro Shimizu 890ddd
			return L"Bold Italic";
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return L"Italic";
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (m_pimpl->m_currentLogFont.lfWeight == 700)
Toshihiro Shimizu 890ddd
			return L"Bold";
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return L"Regular";
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont *TFontManager::getCurrentFont()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_currentFont)
Toshihiro Shimizu 890ddd
		return m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_pimpl->m_currentFont)
Toshihiro Shimizu 890ddd
		loadFontNames();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(!m_pimpl->m_families.empty());
Toshihiro Shimizu 890ddd
	setFamily(m_pimpl->m_families.begin()->first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::getAllFamilies(vector<wstring> &families) const</wstring>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	families.clear();
Toshihiro Shimizu 890ddd
	families.reserve(m_pimpl->m_families.size());
Toshihiro Shimizu 890ddd
	WindowsFontTable::iterator it = m_pimpl->m_families.begin();
Toshihiro Shimizu 890ddd
	for (; it != m_pimpl->m_families.end(); ++it) {
Toshihiro Shimizu 890ddd
		if ((it->first)[0] != L'@')
Toshihiro Shimizu 890ddd
			families.push_back(it->first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::getAllTypefaces(vector<wstring> &typefaces) const</wstring>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	typefaces.resize(4);
Toshihiro Shimizu 890ddd
	typefaces[0] = L"Regular";
Toshihiro Shimizu 890ddd
	typefaces[1] = L"Italic";
Toshihiro Shimizu 890ddd
	typefaces[2] = L"Bold";
Toshihiro Shimizu 890ddd
	typefaces[3] = L"Bold Italic";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::setVertical(bool vertical)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pimpl->m_vertical == vertical)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_pimpl->m_vertical = vertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	wstring currentFamilyName = (m_pimpl->m_currentLogFont.lfFaceName[0] == L'@') ? wstring(m_pimpl->m_currentLogFont.lfFaceName + 1) : wstring(m_pimpl->m_currentLogFont.lfFaceName);
Toshihiro Shimizu 890ddd
	if (vertical)
Toshihiro Shimizu 890ddd
		currentFamilyName = L'@' + currentFamilyName;
Toshihiro Shimizu 890ddd
	setFamily(currentFamilyName);
Toshihiro Shimizu 890ddd
}