Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef __LP64__
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
#include <iostream></iostream>
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "tdebugmessage.h"
Toshihiro Shimizu 890ddd
#include "tfont.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------- structures -------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct {
Toshihiro Shimizu 890ddd
	Float32Point origin;  // The origin of the current glyph
Toshihiro Shimizu 890ddd
	Boolean first;		  // Keeps track of which segment is first in a glyph
Toshihiro Shimizu 890ddd
	Float32Point current; // The current pen position (used to filter degenerate cases)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float adv;
Toshihiro Shimizu 890ddd
	TVectorImageP m_image;
Toshihiro Shimizu 890ddd
	std::vector<tthickpoint> m_points;</tthickpoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} MyCurveCallbackData;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct {
Toshihiro Shimizu 890ddd
	ATSGlyphRef glyphID;		 // The glyphID.  This is simply an index into a table in the font.
Toshihiro Shimizu 890ddd
	Float32Point relativeOrigin; // The origin of this glyph -- relative to the origin of the line.
Toshihiro Shimizu 890ddd
} MyGlyphRecord;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------- callback---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OSStatus MyQuadraticLineProc(const Float32Point *pt1, const Float32Point *pt2, void *callBackDataPtr)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
    // Adjust the points according to the glyph origin
Toshihiro Shimizu 890ddd
    float x1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt1->x;
Toshihiro Shimizu 890ddd
    float y1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt1->y;
Toshihiro Shimizu 890ddd
    float x2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt2->x;
Toshihiro Shimizu 890ddd
    float y2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt2->y;
Toshihiro Shimizu 890ddd
    */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (data->m_points.empty())
Toshihiro Shimizu 890ddd
		data->m_points.push_back(TThickPoint(pt1->x, pt1->y, 0));
Toshihiro Shimizu 890ddd
	//else
Toshihiro Shimizu 890ddd
	//assert(isAlmostEqual(pt1 e back)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThickPoint lastPoint = TThickPoint(pt2->x, pt2->y, 0);
Toshihiro Shimizu 890ddd
	data->m_points.push_back((data->m_points.back() + lastPoint) * 0.5);
Toshihiro Shimizu 890ddd
	data->m_points.push_back(lastPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OSStatus MyQuadraticCurveProc(const Float32Point *pt1, const Float32Point *controlPt, const Float32Point *pt2, void *callBackDataPtr)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
    // Adjust the points according to the glyph origin    
Toshihiro Shimizu 890ddd
    float x1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt1->x;
Toshihiro Shimizu 890ddd
    float y1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt1->y;
Toshihiro Shimizu 890ddd
    float x2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt2->x;
Toshihiro Shimizu 890ddd
    float y2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt2->y;
Toshihiro Shimizu 890ddd
    float cpx = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + controlPt->x;
Toshihiro Shimizu 890ddd
    float cpy = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + controlPt->y;    
Toshihiro Shimizu 890ddd
    */
Toshihiro Shimizu 890ddd
	MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (data->m_points.empty())
Toshihiro Shimizu 890ddd
		data->m_points.push_back(TThickPoint(pt1->x, pt1->y, 0));
Toshihiro Shimizu 890ddd
	//else
Toshihiro Shimizu 890ddd
	//assert(isAlmostEqual(pt1 e back)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	data->m_points.push_back(TThickPoint(controlPt->x, controlPt->y, 0));
Toshihiro Shimizu 890ddd
	data->m_points.push_back(TThickPoint(pt2->x, pt2->y, 0));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OSStatus MyQuadraticNewPathProc(void *callBackDataPtr)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(((MyCurveCallbackData *)callBackDataPtr)->m_points.empty());
Toshihiro Shimizu 890ddd
	return noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OSStatus MyQuadraticClosePathProc(void *callBackDataPtr)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(data->m_points.size() >= 3 && data->m_points.size() & 1); //il numero di punti di controllo devono essere dispari e >= 3
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = new TStroke(data->m_points);
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	data->m_points.clear();
Toshihiro Shimizu 890ddd
	data->m_image->addStroke(stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return noErr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void GetGlyphIDsAndPositions(ATSUTextLayout iLayout, UniCharArrayOffset iStart, UniCharCount iLength, MyGlyphRecord **oGlyphRecordArray, ItemCount *oNumGlyphs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// This block of code uses the new Direct Access APIs, which are only available on Mac OS X 10.2 and later systems
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSLayoutRecord *layoutRecords;
Toshihiro Shimizu 890ddd
	ItemCount numRecords;
Toshihiro Shimizu 890ddd
	Fixed *deltaYs;
Toshihiro Shimizu 890ddd
	ItemCount numDeltaYs;
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
	OSStatus status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Get the arrays of glyph information
Toshihiro Shimizu 890ddd
	status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(
Toshihiro Shimizu 890ddd
		iLayout, iStart,
Toshihiro Shimizu 890ddd
		kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
Toshihiro Shimizu 890ddd
		(void **)&layoutRecords, &numRecords);
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(
Toshihiro Shimizu 890ddd
		iLayout, iStart,
Toshihiro Shimizu 890ddd
		kATSUDirectDataBaselineDeltaFixedArray,
Toshihiro Shimizu 890ddd
		(void **)&deltaYs, &numDeltaYs);
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Build the array of MyGlyphRecords
Toshihiro Shimizu 890ddd
	*oGlyphRecordArray = (MyGlyphRecord *)malloc(numRecords * sizeof(MyGlyphRecord));
Toshihiro Shimizu 890ddd
	*oNumGlyphs = numRecords;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < *oNumGlyphs; i++) {
Toshihiro Shimizu 890ddd
		// Fill in the glyphID
Toshihiro Shimizu 890ddd
		(*oGlyphRecordArray)[i].glyphID = layoutRecords[i].glyphID;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Set up the relative origin of the glyph
Toshihiro Shimizu 890ddd
		//
Toshihiro Shimizu 890ddd
		// The real position is the x coordinate of the glyph, relative to the beginning of the line
Toshihiro Shimizu 890ddd
		// The baseline delta (deltaY), if any, is the y coordinate of the glyph, relative to the baseline
Toshihiro Shimizu 890ddd
		//
Toshihiro Shimizu 890ddd
		(*oGlyphRecordArray)[i].relativeOrigin.x = Fix2X(layoutRecords[i].realPos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (deltaYs == NULL) {
Toshihiro Shimizu 890ddd
			(*oGlyphRecordArray)[i].relativeOrigin.y = 0.0;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			(*oGlyphRecordArray)[i].relativeOrigin.y = 0.0 - Fix2X(deltaYs[i]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Free the arrays of glyph information
Toshihiro Shimizu 890ddd
	if (deltaYs != NULL) {
Toshihiro Shimizu 890ddd
		status = ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataBaselineDeltaFixedArray, (void **)&deltaYs);
Toshihiro Shimizu 890ddd
		assert(status == noErr);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	status = ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords);
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void drawQuadratics(ATSUTextLayout iLayout, ATSUStyle iStyle, UniCharArrayOffset start, UniCharCount length, MyCurveCallbackData &data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//boh ----------------
Toshihiro Shimizu 890ddd
	Fixed penX = 0;
Toshihiro Shimizu 890ddd
	Fixed penY = 0;
Toshihiro Shimizu 890ddd
	// -------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MyGlyphRecord *glyphRecordArray;
Toshihiro Shimizu 890ddd
	ItemCount numGlyphs;
Toshihiro Shimizu 890ddd
	ATSQuadraticNewPathUPP newPathProc;
Toshihiro Shimizu 890ddd
	ATSQuadraticLineUPP lineProc;
Toshihiro Shimizu 890ddd
	ATSQuadraticCurveUPP curveProc;
Toshihiro Shimizu 890ddd
	ATSQuadraticClosePathUPP closePathProc;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OSStatus status;
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Create the Quadratic callbacks
Toshihiro Shimizu 890ddd
	newPathProc = NewATSQuadraticNewPathUPP(MyQuadraticNewPathProc);
Toshihiro Shimizu 890ddd
	lineProc = NewATSQuadraticLineUPP(MyQuadraticLineProc);
Toshihiro Shimizu 890ddd
	curveProc = NewATSQuadraticCurveUPP(MyQuadraticCurveProc);
Toshihiro Shimizu 890ddd
	closePathProc = NewATSQuadraticClosePathUPP(MyQuadraticClosePathProc);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Get the array of glyph information
Toshihiro Shimizu 890ddd
	GetGlyphIDsAndPositions(iLayout, start, length, &glyphRecordArray, &numGlyphs);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Loop over all the glyphs
Toshihiro Shimizu 890ddd
	for (i = 0; i < numGlyphs; i++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Set up the absolute origin of the glyph
Toshihiro Shimizu 890ddd
		data.origin.x = Fix2X(penX) + glyphRecordArray[i].relativeOrigin.x;
Toshihiro Shimizu 890ddd
		data.origin.y = Fix2X(penY) + glyphRecordArray[i].relativeOrigin.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Reset state for quadratic drawing (the callbacks only do a MoveTo on the very first segment)
Toshihiro Shimizu 890ddd
		data.first = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// If this is a deleted glyph (-1), don't draw it.  Otherwise, go ahead.
Toshihiro Shimizu 890ddd
		if (glyphRecordArray[i].glyphID != kATSDeletedGlyphcode) {
Toshihiro Shimizu 890ddd
			status = ATSUGlyphGetQuadraticPaths(iStyle, glyphRecordArray[i].glyphID, newPathProc, lineProc, curveProc, closePathProc, &data, &status);
Toshihiro Shimizu 890ddd
			assert(status == noErr);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	// Free the array of glyph information
Toshihiro Shimizu 890ddd
	free(glyphRecordArray);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Dispose of the Quadratic callbacks
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	DisposeATSQuadraticNewPathUPP(newPathProc);
Toshihiro Shimizu 890ddd
	DisposeATSQuadraticLineUPP(lineProc);
Toshihiro Shimizu 890ddd
	DisposeATSQuadraticCurveUPP(curveProc);
Toshihiro Shimizu 890ddd
	DisposeATSQuadraticClosePathUPP(closePathProc);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TFont::Impl {
Toshihiro Shimizu 890ddd
	bool m_hasKerning;
Toshihiro Shimizu 890ddd
	int m_hasVertical;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//  KerningPairs m_kerningPairs;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSUStyle m_style;
Toshihiro Shimizu 890ddd
	ATSUFontID m_fontId;
Toshihiro Shimizu 890ddd
	ATSUTextLayout m_layout;
Toshihiro Shimizu 890ddd
	Fixed m_size;
Toshihiro Shimizu 890ddd
	int m_ascender;
Toshihiro Shimizu 890ddd
	int m_descender;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Impl(ATSUFontID fontId, int size);
Toshihiro Shimizu 890ddd
	~Impl();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//void getChar();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFont::TFont(ATSUFontID fontId, int size)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pimpl = new Impl(fontId, size);
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(ATSUFontID fontId, int size)
Toshihiro Shimizu 890ddd
	: m_fontId(fontId), m_size(Long2Fix(size))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	OSStatus status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	long response;
Toshihiro Shimizu 890ddd
	status = Gestalt(gestaltATSUFeatures, &response);
Toshihiro Shimizu 890ddd
	assert(response & gestaltATSUDirectAccess);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUCreateStyle(&m_style);
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSUAttributeTag tags[2];
Toshihiro Shimizu 890ddd
	ByteCount sizes[2];
Toshihiro Shimizu 890ddd
	ATSUAttributeValuePtr values[2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tags[0] = kATSUFontTag;
Toshihiro Shimizu 890ddd
	sizes[0] = sizeof(ATSUFontID);
Toshihiro Shimizu 890ddd
	values[0] = &fontId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tags[1] = kATSUSizeTag;
Toshihiro Shimizu 890ddd
	sizes[1] = sizeof(Fixed);
Toshihiro Shimizu 890ddd
	values[1] = &m_size;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUSetAttributes(m_style, 2, tags, sizes, values);
Toshihiro Shimizu 890ddd
	//assert(status==noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UniChar dummyStr[] = {'H', 'e', 'l', 'l', 'o'};
Toshihiro Shimizu 890ddd
	UniCharCount length = sizeof(dummyStr) / sizeof(UniChar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUCreateTextLayoutWithTextPtr(
Toshihiro Shimizu 890ddd
		dummyStr, kATSUFromTextBeginning, kATSUToTextEnd, length, 1,
Toshihiro Shimizu 890ddd
		&length, &m_style, &m_layout);
Toshihiro Shimizu 890ddd
	//assert(status==noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSTrapezoid glyphBounds;
Toshihiro Shimizu 890ddd
	status = ATSUGetGlyphBounds(m_layout, 0, 0,
Toshihiro Shimizu 890ddd
								kATSUFromTextBeginning, kATSUToTextEnd, kATSUseFractionalOrigins,
Toshihiro Shimizu 890ddd
								1, &glyphBounds, NULL);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_ascender = -FixedToInt(glyphBounds.upperLeft.y);
Toshihiro Shimizu 890ddd
	assert(m_ascender > 0);
Toshihiro Shimizu 890ddd
	m_descender = -FixedToInt(glyphBounds.lowerLeft.y);
Toshihiro Shimizu 890ddd
	assert(m_descender < 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
}
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
	OSStatus status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UniChar subString[2];
Toshihiro Shimizu 890ddd
	subString[0] = charcode;
Toshihiro Shimizu 890ddd
	subString[1] = 0 /*nextCharCode*/;
Toshihiro Shimizu 890ddd
	UniCharCount length = sizeof(subString) / sizeof(UniChar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUCreateTextLayoutWithTextPtr(subString, kATSUFromTextBeginning, kATSUToTextEnd,
Toshihiro Shimizu 890ddd
											 length, 1,
Toshihiro Shimizu 890ddd
											 &length, &(m_pimpl->m_style), &(m_pimpl->m_layout));
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MyCurveCallbackData data;
Toshihiro Shimizu 890ddd
	data.m_image = image;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	drawQuadratics(m_pimpl->m_layout, m_pimpl->m_style, kATSUFromTextBeginning, kATSUToTextEnd, data);
Toshihiro Shimizu 890ddd
	image->transform(TScale(1, -1));
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
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void appDrawChar(TRasterGR8P &outImage, TFont::Impl *pimpl, wchar_t charcode)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	OSStatus status;
Toshihiro Shimizu 890ddd
	UniChar subString[2];
Toshihiro Shimizu 890ddd
	subString[0] = charcode;
Toshihiro Shimizu 890ddd
	subString[1] = 0;
Toshihiro Shimizu 890ddd
	UniCharCount length = sizeof(subString) / sizeof(UniChar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUCreateTextLayoutWithTextPtr(subString, kATSUFromTextBeginning, kATSUToTextEnd,
Toshihiro Shimizu 890ddd
											 length, 1,
Toshihiro Shimizu 890ddd
											 &length, &(pimpl->m_style), &(pimpl->m_layout));
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSTrapezoid glyphBounds;
Toshihiro Shimizu 890ddd
	status = ATSUGetGlyphBounds(pimpl->m_layout, 0, 0,
Toshihiro Shimizu 890ddd
								kATSUFromTextBeginning, kATSUToTextEnd, kATSUseFractionalOrigins,
Toshihiro Shimizu 890ddd
								1, &glyphBounds, NULL);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int height = FixedToInt(glyphBounds.lowerLeft.y) - FixedToInt(glyphBounds.upperLeft.y);
Toshihiro Shimizu 890ddd
	int width = tmax(FixedToInt(glyphBounds.lowerRight.x), FixedToInt(glyphBounds.upperRight.x)) -
Toshihiro Shimizu 890ddd
				tmin(FixedToInt(glyphBounds.lowerLeft.x), FixedToInt(glyphBounds.upperLeft.x));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	outImage = TRasterGR8P(width, height);
Toshihiro Shimizu 890ddd
	TPixelGR8 bgp;
Toshihiro Shimizu 890ddd
	bgp.value = 255;
Toshihiro Shimizu 890ddd
	outImage->fill(bgp);
Toshihiro Shimizu 890ddd
	void *data = outImage->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CGColorSpaceRef grayColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
Toshihiro Shimizu 890ddd
	CGContextRef gContext = CGBitmapContextCreate(data, width, height, 8, width, grayColorSpace, kCGImageAlphaNone);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(DEBUG) || defined(_DEBUG)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int bpc = CGBitmapContextGetBitsPerComponent(gContext);
Toshihiro Shimizu 890ddd
	if (bpc != 8)
Toshihiro Shimizu 890ddd
		std::cout << "BitsPerComponent: " << bpc << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int bpp = CGBitmapContextGetBitsPerPixel(gContext);
Toshihiro Shimizu 890ddd
	if (bpp != 8)
Toshihiro Shimizu 890ddd
		std::cout << "BitsPerPixel: " << bpp << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int bytesPerRow = CGBitmapContextGetBytesPerRow(gContext);
Toshihiro Shimizu 890ddd
	int newWidth = CGBitmapContextGetWidth(gContext);
Toshihiro Shimizu 890ddd
	if (bytesPerRow != width || newWidth != width)
Toshihiro Shimizu 890ddd
		std::cout << "BytesPerRow: " << bytesPerRow
Toshihiro Shimizu 890ddd
				  << " Old width= " << width
Toshihiro Shimizu 890ddd
				  << " New width= " << newWidth << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int newHeight = CGBitmapContextGetHeight(gContext);
Toshihiro Shimizu 890ddd
	if (newHeight != height)
Toshihiro Shimizu 890ddd
		std::cout << " Old height= " << height << " New height= " << newHeight << std::endl;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(CGBitmapContextGetColorSpace(gContext) == grayColorSpace);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSUAttributeTag tags[1];
Toshihiro Shimizu 890ddd
	ByteCount sizes[1];
Toshihiro Shimizu 890ddd
	ATSUAttributeValuePtr values[1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tags[0] = kATSUCGContextTag;
Toshihiro Shimizu 890ddd
	sizes[0] = sizeof(CGContextRef);
Toshihiro Shimizu 890ddd
	values[0] = &gContext;
Toshihiro Shimizu 890ddd
	status = ATSUSetLayoutControls(pimpl->m_layout, 1, tags, sizes, values);
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ATSUDrawText(pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, glyphBounds.lowerLeft.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPoint TFont::drawChar(TRasterGR8P &outImage, TPoint &unused, wchar_t charcode, wchar_t nextCharCode) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	appDrawChar(outImage, m_pimpl, charcode);
Toshihiro Shimizu 890ddd
	outImage->yMirror();
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 &unused, int inkId, wchar_t charcode, wchar_t nextCharCode) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterGR8P grayAppImage;
Toshihiro Shimizu 890ddd
	appDrawChar(grayAppImage, m_pimpl, charcode);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int lx = grayAppImage->getLx();
Toshihiro Shimizu 890ddd
	int ly = grayAppImage->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	outImage = TRasterCM32P(lx, ly);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(TPixelCM32::getMaxTone() == 255);
Toshihiro Shimizu 890ddd
	TPixelCM32 bgColor(0, 0, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
	grayAppImage->lock();
Toshihiro Shimizu 890ddd
	outImage->lock();
Toshihiro Shimizu 890ddd
	int ty = 0;
Toshihiro Shimizu 890ddd
	for (int gy = ly - 1; gy >= 0; --gy, ++ty) {
Toshihiro Shimizu 890ddd
		TPixelGR8 *srcPix = grayAppImage->pixels(gy);
Toshihiro Shimizu 890ddd
		TPixelCM32 *tarPix = outImage->pixels(ty);
Toshihiro Shimizu 890ddd
		for (int x = 0; x < lx; ++x) {
Toshihiro Shimizu 890ddd
			int tone = srcPix->value;
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);
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
	OSStatus status;
Toshihiro Shimizu 890ddd
	UniChar subString[2];
Toshihiro Shimizu 890ddd
	subString[0] = firstChar;
Toshihiro Shimizu 890ddd
	subString[1] = secondChar;
Toshihiro Shimizu 890ddd
	UniCharCount length = sizeof(subString) / sizeof(UniChar);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	status = ATSUCreateTextLayoutWithTextPtr(subString, kATSUFromTextBeginning, kATSUToTextEnd,
Toshihiro Shimizu 890ddd
											 length, 1,
Toshihiro Shimizu 890ddd
											 &length, &(m_pimpl->m_style), &(m_pimpl->m_layout));
Toshihiro Shimizu 890ddd
	assert(status == noErr);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MyGlyphRecord *glyphRecordArray;
Toshihiro Shimizu 890ddd
	ItemCount numGlyphs;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Get the array of glyph information
Toshihiro Shimizu 890ddd
	GetGlyphIDsAndPositions(m_pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, &glyphRecordArray, &numGlyphs);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(numGlyphs >= 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(glyphRecordArray[0].relativeOrigin.x == 0);
Toshihiro Shimizu 890ddd
	int advance = (int)(glyphRecordArray[1].relativeOrigin.x - glyphRecordArray[0].relativeOrigin.x);
Toshihiro Shimizu 890ddd
	if (advance == 0) {
Toshihiro Shimizu 890ddd
		subString[1] = 0;
Toshihiro Shimizu 890ddd
		status = ATSUCreateTextLayoutWithTextPtr(subString, kATSUFromTextBeginning, kATSUToTextEnd,
Toshihiro Shimizu 890ddd
												 length, 1,
Toshihiro Shimizu 890ddd
												 &length, &(m_pimpl->m_style), &(m_pimpl->m_layout));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		GetGlyphIDsAndPositions(m_pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, &glyphRecordArray, &numGlyphs);
Toshihiro Shimizu 890ddd
		advance = (int)(glyphRecordArray[1].relativeOrigin.x - glyphRecordArray[0].relativeOrigin.x);
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_ascender - m_pimpl->m_descender;
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
	assert(!"not implemented yet");
Toshihiro Shimizu 890ddd
	return 100;
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_ascender;
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_descender;
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 true;
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 false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include <map></map>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::map<std::string, atsufontid=""> FontFamily;</std::string,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::map<std::string, fontfamily=""> FamilyMap;</std::string,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TFontManager::Impl {
Toshihiro Shimizu 890ddd
	FamilyMap m_families;
Toshihiro Shimizu 890ddd
	bool m_loaded;
Toshihiro Shimizu 890ddd
	ATSUFontID m_currentAtsuFontId;
Toshihiro Shimizu 890ddd
	TFont *m_currentFont;
Toshihiro Shimizu 890ddd
	wstring m_currentFamily;
Toshihiro Shimizu 890ddd
	wstring m_currentTypeface;
Toshihiro Shimizu 890ddd
	int m_size;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Impl()
Toshihiro Shimizu 890ddd
		: m_currentAtsuFontId(0), m_currentFont(0), m_loaded(false), m_size(70)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool setFontName(ATSUFontID fontId, int platform, int script, int lang);
Toshihiro Shimizu 890ddd
	bool addFont(ATSUFontID);
Toshihiro Shimizu 890ddd
	void loadFontNames();
Toshihiro Shimizu 890ddd
	bool setFont(std::wstring family, std::wstring style);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TFontManager::Impl::setFontName(ATSUFontID fontId, int platform, int script, int lang)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ByteCount oActualNameLength;
Toshihiro Shimizu 890ddd
	ItemCount oFontCount;
Toshihiro Shimizu 890ddd
	OSStatus status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char *buffer = 0;
Toshihiro Shimizu 890ddd
	char *buffer2 = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// chiedo la lunhezza del Full Family Name per allocare il buffer
Toshihiro Shimizu 890ddd
	status = ATSUFindFontName(fontId,
Toshihiro Shimizu 890ddd
							  kFontFullName,
Toshihiro Shimizu 890ddd
							  platform,
Toshihiro Shimizu 890ddd
							  script,
Toshihiro Shimizu 890ddd
							  lang,
Toshihiro Shimizu 890ddd
							  0, 0,
Toshihiro Shimizu 890ddd
							  &oActualNameLength,
Toshihiro Shimizu 890ddd
							  0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (status != noErr || oActualNameLength <= 1)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer = new char[oActualNameLength + 1];
Toshihiro Shimizu 890ddd
	// chiedo il Full Family Name
Toshihiro Shimizu 890ddd
	status = ATSUFindFontName(fontId,
Toshihiro Shimizu 890ddd
							  kFontFullName,
Toshihiro Shimizu 890ddd
							  platform,
Toshihiro Shimizu 890ddd
							  script,
Toshihiro Shimizu 890ddd
							  lang,
Toshihiro Shimizu 890ddd
							  oActualNameLength, buffer,
Toshihiro Shimizu 890ddd
							  &oActualNameLength,
Toshihiro Shimizu 890ddd
							  &oFontCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (status != noErr || oActualNameLength <= 1 || buffer[0] == '\0') {
Toshihiro Shimizu 890ddd
		delete[] buffer;
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	buffer[oActualNameLength] = '\0';
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// chiedo la lunhezza del Typeface Name per allocare il buffer
Toshihiro Shimizu 890ddd
	status = ATSUFindFontName(fontId,
Toshihiro Shimizu 890ddd
							  kFontStyleName,
Toshihiro Shimizu 890ddd
							  platform,
Toshihiro Shimizu 890ddd
							  script,
Toshihiro Shimizu 890ddd
							  lang,
Toshihiro Shimizu 890ddd
							  0, 0,
Toshihiro Shimizu 890ddd
							  &oActualNameLength,
Toshihiro Shimizu 890ddd
							  0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (status != noErr || oActualNameLength <= 1) {
Toshihiro Shimizu 890ddd
		delete[] buffer;
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	buffer2 = new char[oActualNameLength + 1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// chiedo il Typeface Name
Toshihiro Shimizu 890ddd
	status = ATSUFindFontName(fontId,
Toshihiro Shimizu 890ddd
							  kFontStyleName,
Toshihiro Shimizu 890ddd
							  platform,
Toshihiro Shimizu 890ddd
							  script,
Toshihiro Shimizu 890ddd
							  lang,
Toshihiro Shimizu 890ddd
							  oActualNameLength, buffer2,
Toshihiro Shimizu 890ddd
							  &oActualNameLength,
Toshihiro Shimizu 890ddd
							  &oFontCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (status != noErr || oActualNameLength <= 1 || buffer2[0] == '\0') {
Toshihiro Shimizu 890ddd
		delete[] buffer;
Toshihiro Shimizu 890ddd
		delete[] buffer2;
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		buffer2[oActualNameLength] = '\0';
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string s_family(buffer);
Toshihiro Shimizu 890ddd
	FontFamily &family = m_families[s_family];
Toshihiro Shimizu 890ddd
	family[string(buffer2)] = fontId;
Toshihiro Shimizu 890ddd
	delete[] buffer;
Toshihiro Shimizu 890ddd
	delete[] buffer2;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TFontManager::Impl::addFont(ATSUFontID fontId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int platform, script, lang;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// per ottimizzare, ciclo solo sui valori
Toshihiro Shimizu 890ddd
	// piu' comuni
Toshihiro Shimizu 890ddd
	for (lang = -1; lang <= 0; lang++)
Toshihiro Shimizu 890ddd
		for (platform = -1; platform <= 1; platform++)
Toshihiro Shimizu 890ddd
			for (script = -1; script <= 0; script++)
Toshihiro Shimizu 890ddd
				if (setFontName(fontId, platform, script, lang))
Toshihiro Shimizu 890ddd
					return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//poi li provo tutti
Toshihiro Shimizu 890ddd
	for (lang = -1; lang <= 139; lang++)
Toshihiro Shimizu 890ddd
		for (script = -1; script <= 32; script++)
Toshihiro Shimizu 890ddd
			for (platform = -1; platform <= 4; platform++) {
Toshihiro Shimizu 890ddd
				// escludo quelli nel tri-ciclo for precedente.
Toshihiro Shimizu 890ddd
				// Purtoppo si deve fare cosi:
Toshihiro Shimizu 890ddd
				// non si puo' fare partendo con indici piu' alti nei cicli for!
Toshihiro Shimizu 890ddd
				if (-1 <= lang && lang <= 0 &&
Toshihiro Shimizu 890ddd
					-1 <= script && script <= 0 &&
Toshihiro Shimizu 890ddd
					-1 <= platform && platform <= 1)
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (setFontName(fontId, platform, script, lang))
Toshihiro Shimizu 890ddd
					return true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TFontManager::Impl::loadFontNames()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_loaded)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ItemCount oFontCount, fontCount;
Toshihiro Shimizu 890ddd
	ATSUFontCount(&oFontCount);
Toshihiro Shimizu 890ddd
	fontCount = oFontCount;
Toshihiro Shimizu 890ddd
	ATSUFontID *oFontIDs = new ATSUFontID[fontCount];
Toshihiro Shimizu 890ddd
	ATSUGetFontIDs(oFontIDs, fontCount, &oFontCount);
Toshihiro Shimizu 890ddd
	assert(fontCount == oFontCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < fontCount; i++)
Toshihiro Shimizu 890ddd
		addFont(oFontIDs[i]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete[] oFontIDs;
Toshihiro Shimizu 890ddd
	m_loaded = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TFontManager::Impl::setFont(std::wstring family, std::wstring typeface)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (family == m_currentFamily && (typeface == m_currentTypeface || typeface == L""))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FamilyMap::iterator family_it = m_families.find(toString(family));
Toshihiro Shimizu 890ddd
	if (family_it == m_families.end())
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_currentFamily = family;
Toshihiro Shimizu 890ddd
	FontFamily::iterator style_it;
Toshihiro Shimizu 890ddd
	if (typeface == L"") {
Toshihiro Shimizu 890ddd
		style_it = ((*family_it).second).find(toString(m_currentTypeface));
Toshihiro Shimizu 890ddd
		if (style_it == (*family_it).second.end())
Toshihiro Shimizu 890ddd
			style_it = ((*family_it).second).begin();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		typeface = toWideString(style_it->first);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		style_it = ((*family_it).second).find(toString(typeface));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (style_it == (*family_it).second.end())
Toshihiro Shimizu 890ddd
		throw TFontCreationError();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_currentTypeface = typeface;
Toshihiro Shimizu 890ddd
	m_currentAtsuFontId = (*style_it).second;
Toshihiro Shimizu 890ddd
	return true;
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
void TFontManager::loadFontNames()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pimpl->loadFontNames();
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
	bool changed = m_pimpl->setFont(family, L"");
Toshihiro Shimizu 890ddd
	if (changed) {
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size);
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
	bool changed = m_pimpl->setFont(m_pimpl->m_currentFamily, typeface);
Toshihiro Shimizu 890ddd
	if (changed) {
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size);
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
	if (m_pimpl->m_size != size) {
Toshihiro Shimizu 890ddd
		m_pimpl->m_size = size;
Toshihiro Shimizu 890ddd
		delete m_pimpl->m_currentFont;
Toshihiro Shimizu 890ddd
		m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size);
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
	return m_pimpl->m_currentFamily;
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
	return m_pimpl->m_currentTypeface;
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(toWideString(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
Toshihiro Shimizu 890ddd
	FamilyMap::iterator it = m_pimpl->m_families.begin();
Toshihiro Shimizu 890ddd
	for (; it != m_pimpl->m_families.end(); ++it) {
Toshihiro Shimizu 890ddd
		families.push_back(toWideString(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.clear();
Toshihiro Shimizu 890ddd
	FamilyMap::iterator it_family = m_pimpl->m_families.find(toString(m_pimpl->m_currentFamily));
Toshihiro Shimizu 890ddd
	if (it_family == m_pimpl->m_families.end())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	FontFamily &typefaceSet = it_family->second;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typefaces.reserve(typefaceSet.size());
Toshihiro Shimizu 890ddd
	FontFamily::iterator it_typeface = typefaceSet.begin();
Toshihiro Shimizu 890ddd
	for (; it_typeface != typefaceSet.end(); ++it_typeface) {
Toshihiro Shimizu 890ddd
		typefaces.push_back(toWideString(it_typeface->first));
Toshihiro Shimizu 890ddd
	}
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
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif