|
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 |
}
|