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