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