Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1994-2001 artofcode LLC.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gdevmacxf.c,v 1.6 2002/06/09 23:08:22 lpd Exp $ */
18
/* External font (xfont) implementation for Classic/Carbon MacOS. */
19
 
20
#include "gdevmac.h"
21
#include "gdevmacttf.h"
22
 
23
 
24
/* if set to 1, new carbon supported FontManager calls are used */
25
/* if set to 0, old FM calls that are "not recommended" for carbon are used */
26
/* for now, we'll set it to 0, as classic and carbon targets don't generate link errors, */
27
/* but the carbon target would be better built with this macro set to 1 */
28
/* In the case that it is set, the classic target should link in FontManager(Lib) */
29
#define USE_RECOMMENDED_CARBON_FONTMANAGER_CALLS 1
30
 
31
 
32
 
33
extern const byte gs_map_std_to_iso[256];
34
extern const byte gs_map_iso_to_std[256];
35
 
36
 
37
const byte gs_map_std_to_mac[256] =
38
{
39
/*			  x0	x1	  x2	x3	  x4	x5	  x6	x7	  x8	x9	  xA	xB	  xC	xD	  xE	xF	*/
40
/* 0x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
/* 1x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42
/* 2x */	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
43
/* 3x */	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
44
/* 4x */	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
45
/* 5x */	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
46
/* 6x */	0xD4, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
47
/* 7x */	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
48
/* 8x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49
/* 9x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50
/* Ax */	0x00, 0xC1, 0xA2, 0xA3, 0xDA, 0xB4, 0xC4, 0xA4, 0xDB, 0x27, 0xD2, 0xC7, 0xDC, 0xDD, 0xDE, 0xDF,
51
/* Bx */	0x00, 0xD0, 0xA0, 0xE0, 0xE1, 0x00, 0xA6, 0xA5, 0xE2, 0xE3, 0xD3, 0xC8, 0xC9, 0xE4, 0x00, 0xC0,
52
/* Cx */	0x00, 0x60, 0xAB, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xAC, 0x00, 0xFB, 0xFC, 0x00, 0xFD, 0xFE, 0xFF,
53
/* Dx */	0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54
/* Ex */	0x00, 0xAE, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0xCE, 0xBC, 0x00, 0x00, 0x00, 0x00,
55
/* Fx */	0x00, 0xBE, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0xBF, 0xCF, 0xA7, 0x00, 0x00, 0x00, 0x00
56
};
57
 
58
const byte gs_map_mac_to_std[256] =
59
{
60
};
61
 
62
const byte gs_map_iso_to_mac[256] =
63
{
64
/*			  x0	x1	  x2	x3	  x4	x5	  x6	x7	  x8	x9	  xA	xB	  xC	xD	  xE	xF	*/
65
/* 0x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66
/* 1x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67
/* 2x */	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
68
/* 3x */	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
69
/* 4x */	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
70
/* 5x */	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
71
/* 6x */	0xD4, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
72
/* 7x */	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
73
/* 8x */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74
/* 9x */	0xF5, 0x60, 0xAB, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xAC, 0x00, 0xFB, 0xFC, 0x00, 0xFD, 0xFE, 0xFF,
75
/* Ax */	0x00, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4, 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x2D, 0xA8, 0xF8,
76
/* Bx */	0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0,
77
/* Cx */	0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, 0xE9, 0x83, 0xE6, 0xE8, 0xEA, 0xED, 0xEB, 0xEC,
78
/* Dx */	0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00, 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7,
79
/* Ex */	0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
80
/* Fx */	0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8
81
};
82
 
83
const byte gs_map_mac_to_iso[256] =
84
{
85
};
86
 
87
 
88
 
89
 
90
 
91
/* The xfont procedure record. */
92
 
93
private const gx_xfont_procs mac_xfont_procs =
94
{
95
    mac_lookup_font,
96
    mac_char_xglyph,
97
    mac_char_metrics,
98
    mac_render_char,
99
    mac_release
100
};
101
 
102
 
103
gs_private_st_dev_ptrs1(st_mac_xfont, mac_xfont, "mac_xfont", mac_xfont_enum_ptrs,
104
						mac_xfont_reloc_ptrs, dev);
105
 
106
 
107
 
108
 
109
 
110
/* Return the xfont procedure record. */
111
 
112
const gx_xfont_procs *
113
mac_get_xfont_procs(gx_device *dev)
114
{
115
#pragma unused(dev)
116
    return &mac_xfont_procs;
117
}
118
 
119
 
120
 
121
/* lookup_font */
122
 
123
private gx_xfont *
124
mac_lookup_font(gx_device *dev, const byte *fname, uint len,
125
				int encoding_index, const gs_uid *puid,
126
				const gs_matrix *pmat, gs_memory_t *mem)
127
{
128
#pragma unused(encoding_index,puid)
129
	mac_xfont		*macxf;
130
 
131
	CGrafPort		*currentPort;
132
	int				txFont, txSize, txMode;
133
	StyleField		txFace;
134
	Fixed			spExtra;
135
 
136
	/* are XFonts enabled? */
137
	if (((gx_device_macos*) dev)->useXFonts == false)
138
		return NULL;
139
 
140
	/* we can handle only requests from these encodings */
141
	if (encoding_index != ENCODING_INDEX_MACROMAN && encoding_index != ENCODING_INDEX_ISOLATIN1 &&
142
			encoding_index != ENCODING_INDEX_STANDARD)
143
		return NULL;
144
 
145
	/* Don't render very small fonts */
146
	if (fabs(pmat->xx * 1000.0) < 3.0)
147
		return NULL;
148
 
149
	/* Only handle simple cases for now (no transformations). */
150
	if (fabs(pmat->xy) > 0.0001 || fabs(pmat->yx) > 0.0001 || pmat->xx <= 0)
151
		return NULL;
152
 
153
	/* allocate memory for gx_xfont */
154
	macxf = gs_alloc_struct(mem, mac_xfont, &st_mac_xfont, "mac_lookup_font");
155
	if (macxf == NULL) {
156
		return NULL;
157
	}
158
 
159
	/* set default values */
160
	macxf->common.procs = &mac_xfont_procs;
161
	macxf->dev = dev;
162
 
163
	/* find the specified font */
164
	mac_find_font_family(fname, len, &(macxf->fontID), &(macxf->fontFace));
165
 
166
	/* no font found */
167
	if (macxf->fontID == 0)
168
		return NULL;
169
 
170
	FMGetFontFamilyName(macxf->fontID, macxf->fontName);
171
	macxf->fontSize = (short)(pmat->xx * 1000.0);
172
	macxf->fontEncoding = mac_get_font_encoding(macxf);
173
 
174
	/* we can handle only fonts with these encodings for now (all original Mac fonts have MacRoman encoding!) */
175
	if (macxf->fontEncoding != ENCODING_INDEX_MACROMAN && macxf->fontEncoding != ENCODING_INDEX_ISOLATIN1)
176
		return NULL;
177
 
178
	/* get font metrics */
179
 
180
	/* save current GrafPort's font information */
181
	GetPort(&((GrafPort*) currentPort));
182
	txFont  = currentPort->txFont;
183
	txSize  = currentPort->txSize;
184
	txFace  = currentPort->txFace;
185
	txMode  = currentPort->txMode;
186
	spExtra = currentPort->spExtra;
187
 
188
	/* set values for measuring */
189
	TextFont(macxf->fontID);
190
	TextSize(macxf->fontSize);
191
	TextFace(macxf->fontFace);
192
	TextMode(srcOr);
193
	SpaceExtra(0);
194
 
195
	/* measure font */
196
	FontMetrics(&(macxf->fontMetrics));
197
 
198
	/* restore current GrafPort's font information */
199
	currentPort->txFont  = txFont;
200
	currentPort->txSize  = txSize;
201
	currentPort->txFace  = txFace;
202
	currentPort->txMode  = txMode;
203
	currentPort->spExtra = spExtra;
204
 
205
	return (gx_xfont*) macxf;
206
}
207
 
208
 
209
 
210
/* char_xglyph */
211
 
212
private gx_xglyph
213
mac_char_xglyph(gx_xfont *xf, gs_char chr, int encoding_index,
214
		gs_glyph glyph, const gs_const_string *glyph_name)
215
{
216
#pragma unused(glyph_name,glyph)
217
	mac_xfont			* macxf = (mac_xfont*) xf;
218
 
219
	/* can't look up names yet */
220
	if (chr == gs_no_char)
221
		return gx_no_xglyph;
222
 
223
	if (macxf->fontEncoding == ENCODING_INDEX_MACROMAN) {
224
		switch (encoding_index) {
225
			case ENCODING_INDEX_MACROMAN:	return chr;
226
			case ENCODING_INDEX_STANDARD:	return gs_map_std_to_mac[chr];
227
			case ENCODING_INDEX_ISOLATIN1:	return gs_map_iso_to_mac[chr];
228
		}
229
	} else if (macxf->fontEncoding == ENCODING_INDEX_ISOLATIN1) {
230
		switch (encoding_index) {
231
			case ENCODING_INDEX_MACROMAN:	return gs_map_mac_to_iso[chr];
232
			case ENCODING_INDEX_STANDARD:	return gs_map_std_to_iso[chr];
233
			case ENCODING_INDEX_ISOLATIN1:	return chr;
234
		}
235
	}
236
 
237
	return gx_no_xglyph;
238
}
239
 
240
 
241
 
242
/* char_metrics */
243
 
244
private int
245
mac_char_metrics(gx_xfont *xf, gx_xglyph xg, int wmode,
246
				 gs_point *pwidth, gs_int_rect *pbbox)
247
{
248
#pragma unused(xg)
249
	mac_xfont			* macxf = (mac_xfont*) xf;
250
 
251
	if (wmode != 0)
252
		return gs_error_undefined;
253
 
254
	pbbox->p.x = 0;
255
	pbbox->q.x = Fix2Long(macxf->fontMetrics.widMax);
256
	pbbox->p.y = -Fix2Long(macxf->fontMetrics.ascent);
257
	pbbox->q.y = Fix2Long(macxf->fontMetrics.descent);
258
	pwidth->x = pbbox->q.x;
259
	pwidth->y = 0.0;
260
 
261
	return 0;
262
}
263
 
264
 
265
 
266
/* render_char */
267
 
268
private int
269
mac_render_char(gx_xfont *xf, gx_xglyph xg, gx_device *dev,
270
				int xo, int yo, gx_color_index color, int required)
271
{
272
#pragma unused(dev,required)
273
	mac_xfont			* macxf = (mac_xfont*) xf;
274
	gx_device_macos		* mdev = (gx_device_macos*) macxf->dev;
275
 
276
	Str255				character;
277
	int					i, found;
278
 
279
	CheckMem(10*1024, 100*1024);
280
	ResetPage();
281
 
282
	character[0] = 1;
283
	character[1] = xg;
284
 
285
	GSSetFgCol(macxf->dev, mdev->currPicPos, color);
286
 
287
	found = 0;
288
	for (i=0; i<mdev->numUsedFonts; i++)
289
		if (mdev->usedFontIDs[i] == macxf->fontID)	found = 1;
290
 
291
	if (!found) {
292
		mdev->usedFontIDs[mdev->numUsedFonts++] = macxf->fontID;
293
		PICT_fontName(mdev->currPicPos, macxf->fontID, macxf->fontName);
294
	}
295
	if (mdev->lastFontID != macxf->fontID) {
296
		PICT_TxFont(mdev->currPicPos, macxf->fontID);
297
		mdev->lastFontID = macxf->fontID;
298
	}
299
	if (mdev->lastFontSize != macxf->fontSize) {
300
		PICT_TxSize(mdev->currPicPos, macxf->fontSize);
301
		mdev->lastFontSize = macxf->fontSize;
302
	}
303
	if (mdev->lastFontFace != macxf->fontFace) {
304
		PICT_TxFace(mdev->currPicPos, macxf->fontFace);
305
		mdev->lastFontFace = macxf->fontFace;
306
	}
307
	PICT_LongText(mdev->currPicPos, xo, yo, character);
308
	PICT_OpEndPicGoOn(mdev->currPicPos);
309
 
310
	return 0;
311
}
312
 
313
 
314
 
315
/* release */
316
 
317
private int
318
mac_release(gx_xfont *xf, gs_memory_t *mem)
319
{
320
	if (mem != NULL)
321
		gs_free_object(mem, xf, "mac_release");
322
 
323
	return 0;
324
}
325
 
326
 
327
 
328
/* try to extract font family and style from name and find a suitable font */
329
 
330
private void
331
mac_find_font_family(ConstStringPtr fname, int len, FMFontFamily *fontID, FMFontStyle *fontFace)
332
{
333
	char			fontNameStr[512];
334
	char			*fontFamilyName;
335
	char			*fontStyleName;
336
	int				i;
337
 
338
	*fontID   = 0;
339
	*fontFace = 0;
340
 
341
	/* first try the full fontname */
342
	fontNameStr[0] = len;
343
	memcpy(fontNameStr+1, fname, len);
344
	*fontID = FMGetFontFamilyFromName((StringPtr) fontNameStr);
345
	if (*fontID > 0)	return;
346
 
347
	/* try to find the font without the dashes */
348
	fontNameStr[0] = len;
349
	memcpy(fontNameStr+1, fname, len);
350
	for (i=1; i<=len; i++)
351
		if (fontNameStr[i] == '-')	fontNameStr[i] = ' ';
352
	*fontID = FMGetFontFamilyFromName((StringPtr) fontNameStr);
353
	if (*fontID > 0)	return;
354
 
355
	/* we should read some default fontname mappings from a file here */
356
	if (*fontID > 0)	return;
357
 
358
	/* try to extract font basename and style names */
359
	memcpy(fontNameStr, fname, len);
360
	fontNameStr[len] = 0;
361
 
362
	fontFamilyName = strtok(fontNameStr, "- ");
363
	while ((fontStyleName = strtok(NULL, "- ")) != NULL) {
364
		if (!strcmp(fontStyleName, "Italic") || !strcmp(fontStyleName, "Oblique") || !strcmp(fontStyleName, "It"))
365
			*fontFace |= italic;
366
		if (!strcmp(fontStyleName, "Bold") || !strcmp(fontStyleName, "Bd"))
367
			*fontFace |= bold;
368
		if (!strcmp(fontStyleName, "Narrow") || !strcmp(fontStyleName, "Condensed"))
369
			*fontFace |= condense;
370
	}
371
 
372
	if (fontFamilyName == NULL) {
373
		return;
374
	} else {
375
		Str255	fontName;
376
 
377
		fontName[0] = strlen(fontFamilyName);
378
		strcpy((char*)(fontName+1), fontFamilyName);
379
		*fontID = FMGetFontFamilyFromName((StringPtr) fontNameStr);
380
		if (*fontID > 0) return;
381
	}
382
}
383
 
384
 
385
 
386
/* extract a font's platform id (encoding) */
387
 
388
private int
389
mac_get_font_encoding(mac_xfont *macxf)
390
{
391
	int			encoding = ENCODING_INDEX_UNKNOWN;
392
	ResType		resType;
393
	short		resID;
394
 
395
	mac_get_font_resource(macxf, &resType, &resID);
396
 
397
	if (resType == 'sfnt') {
398
		Handle				fontHandle;
399
		TTFontDir			*fontDir;
400
		TTFontNamingTable	*fontNamingTable;
401
		int					i;
402
 
403
		/* load resource */
404
		if ((fontHandle = GetResource(resType, resID)) == NULL)
405
			return encoding;
406
		HLock(fontHandle);
407
 
408
		/* walk through the font directory and find the font naming table */
409
		fontDir = (TTFontDir*) *fontHandle;
410
		if (fontDir != NULL && fontDir->version == 'true') {
411
			for (i=0; i<fontDir->numTables; i++) {
412
				if (fontDir->components[i].tagName == TTF_FONT_NAMING_TABLE) {
413
					fontNamingTable = (TTFontNamingTable*) ((long)(fontDir->components[i].offset) + (long)fontDir);
414
					switch (fontNamingTable->platformID) {
415
						//case 0:		encoding = ENCODING_INDEX_STANDARD;		break;	/* Unicode */
416
						case 1:		encoding = ENCODING_INDEX_MACROMAN;		break;
417
						case 2:		encoding = ENCODING_INDEX_ISOLATIN1;	break;
418
						//case 3:		encoding = ENCODING_INDEX_WINANSI;		break;
419
					}
420
					break;
421
				}
422
			}
423
		}
424
 
425
		HUnlock(fontHandle);
426
		ReleaseResource(fontHandle);
427
	}
428
 
429
	return encoding;
430
}
431
 
432
 
433
 
434
/* get a handle to a font resource */
435
 
436
private void
437
mac_get_font_resource(mac_xfont *macxf, ResType *resType, short *resID)
438
{
439
	FMInput		fontInput = {0, 0, 0, true, 0, {1,1}, {1,1}};
440
	FMOutputPtr	fontOutput;
441
 
442
	Str255		resName;
443
 
444
	fontInput.family	= macxf->fontID;
445
	fontInput.size		= macxf->fontSize;
446
	fontInput.face		= macxf->fontFace;
447
 
448
	fontOutput = FMSwapFont(&fontInput);
449
 
450
	if (fontOutput == NULL || fontOutput->fontHandle == NULL)
451
		return;
452
 
453
	GetResInfo(fontOutput->fontHandle, resID, resType, resName);
454
}
455
 
456
 
457
 
458
#if !USE_RECOMMENDED_CARBON_FONTMANAGER_CALLS
459
/* wrap the old Classic MacOS font manager calls to fake support for the
460
   new FontManager API on older systems */
461
 
462
OSStatus
463
FMGetFontFamilyName(FMFontFamily fontFamilyID, Str255 fontNameStr)
464
{
465
	GetFontName(fontFamilyID, fontNameStr);
466
	return noErr;
467
}
468
 
469
FMFontFamily
470
FMGetFontFamilyFromName(ConstStr255Param fontNameStr)
471
{
472
    int	fontID;
473
    GetFNum(fontNameStr, &fontID);
474
 
475
    return (FMFontFamily)fontID;
476
}
477
#endif