5 #define Cursor OSXCursor
6 #include <Carbon/Carbon.h>
19 extern void CGFontGetGlyphsForUnichars(CGFontRef, const UniChar[], const CGGlyph[], size_t);
27 n = CFStringGetLength(s)*8;
29 CFStringGetCString(s, p, n, kCFStringEncodingUTF8);
36 return CFStringCreateWithBytes(nil, (uchar*)p, strlen(p), kCFStringEncodingUTF8, false);
40 mac2r(CGRect r, int size, int unit)
44 rr.min.x = r.origin.x*size/unit;
45 rr.min.y = r.origin.y*size/unit;
46 rr.max.x = (r.origin.x+r.size.width)*size/unit + 0.99999999;
47 rr.max.y = (r.origin.x+r.size.width)*size/unit + 0.99999999;
55 CTFontCollectionRef allc;
58 CTFontDescriptorRef f;
60 allc = CTFontCollectionCreateFromAvailableFonts(0);
61 array = CTFontCollectionCreateMatchingFontDescriptors(allc);
62 n = CFArrayGetCount(array);
63 xfont = emalloc9p(n*sizeof xfont[0]);
65 f = (void*)CFArrayGetValueAtIndex(array, i);
68 s = CTFontDescriptorCopyAttribute(f, kCTFontNameAttribute);
69 xfont[nxfont].name = mac2c(s);
76 subfontbbox(CGFontRef font, int lo, int hi)
87 for(i=lo; i<=hi; i++) {
93 CGFontGetGlyphsForUnichars(font, &u, &g, 1);
94 if(g == 0 || !CGFontGetGlyphBBoxes(font, &g, 1, &r))
97 r.size.width += r.origin.x;
98 r.size.height += r.origin.y;
104 if(bbox.origin.x > r.origin.x)
105 bbox.origin.x = r.origin.x;
106 if(bbox.origin.y > r.origin.y)
107 bbox.origin.y = r.origin.y;
108 if(bbox.size.width < r.size.width)
109 bbox.size.width = r.size.width;
110 if(bbox.size.height < r.size.height)
111 bbox.size.height = r.size.height;
114 bbox.size.width -= bbox.origin.x;
115 bbox.size.height -= bbox.origin.y;
133 font = CGFontCreateWithFontName(s);
138 // assume bbox gives latin1 is height/ascent for all
139 bbox = subfontbbox(font, 0x00, 0xff);
140 f->unit = CGFontGetUnitsPerEm(font);
141 f->height = bbox.size.height;
142 f->originy = bbox.origin.y;
144 // figure out where the letters are
145 for(i=0; i<0xffff; i+=0x100) {
146 for(j=0; j<0x100; j++) {
150 CGFontGetGlyphsForUnichars(font, u, g, 256);
151 for(j=0; j<0x100; j++) {
163 mksubfont(char *name, int lo, int hi, int size, int antialias)
166 CGColorSpaceRef color;
170 Memimage *m, *mc, *m1;
177 font = CGFontCreateWithFontName(s);
181 bbox = subfontbbox(font, lo, hi);
182 unit = CGFontGetUnitsPerEm(font);
183 x = (int)(bbox.size.width * size / unit + 0.99999999);
184 y = bbox.size.height * size/unit + 0.99999999;
185 y0 = (int)(-bbox.origin.y * size/unit + 0.99999999);
186 m = allocmemimage(Rect(0, 0, x*(hi+1-lo), y), GREY8);
189 mc = allocmemimage(Rect(0, 0, x, y), GREY8);
192 memfillcolor(m, DBlack);
193 memfillcolor(mc, DBlack);
194 fc = malloc((hi+2 - lo) * sizeof fc[0]);
195 sf = malloc(sizeof *sf);
196 if(fc == nil || sf == nil) {
205 color = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
206 ctxt = CGBitmapContextCreate(byteaddr(mc, mc->r.min), Dx(mc->r), Dy(mc->r), 8,
207 mc->width*sizeof(u32int), color, kCGImageAlphaNone);
208 CGColorSpaceRelease(color);
217 CGContextSetFont(ctxt, font);
218 CGContextSetFontSize(ctxt, size);
219 CGContextSetAllowsAntialiasing(ctxt, antialias);
220 CGContextSetRGBFillColor(ctxt, 1, 1, 1, 1);
221 CGContextSetTextPosition(ctxt, 0, 0); // XXX
224 for(i=lo; i<=hi; i++, fc++) {
233 fc->bottom = Dy(m->r);
240 CGFontGetGlyphsForUnichars(font, u, g, n);
241 if(g[0] == 0 || !CGFontGetGlyphBBoxes(font, g, n, r)) {
248 // memimagestring(m, p, memwhite, ZP, defont, peterface);
249 i = defont->info + 0;
250 memdraw(m, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom),
251 memwhite, ZP, defont->bits, Pt(i->x, i->top), S);
254 fc->width = i->width;
259 memfillcolor(mc, DBlack);
260 CGContextSetTextPosition(ctxt, 0, y0);
261 CGContextShowGlyphs(ctxt, g, n);
262 p1 = CGContextGetTextPosition(ctxt);
265 memimagedraw(m, Rect(x, 0, x + p1.x, y), mc, ZP, memopaque, ZP, S);
272 // round up to 32-bit boundary
273 // so that in-memory data is same
274 // layout as in-file data.
279 m1 = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1);
280 memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S);
285 sf->height = Dy(m1->r);
286 sf->ascent = Dy(m1->r) - y0;