548 #endif
549
550 return glyphInfo;
551 }
552
553
554 #pragma mark --- Glyph Striking onto Canvas ---
555
556 /*
557 * Clears the canvas, strikes the glyph with CoreGraphics, and then
558 * copies the struck pixels into the GlyphInfo image.
559 */
560 static inline void
561 CGGI_CreateImageForGlyph
562 (CGGI_GlyphCanvas *canvas, const CGGlyph glyph,
563 GlyphInfo *info, const CGGI_RenderingMode *mode)
564 {
565 // clean the canvas
566 CGGI_ClearCanvas(canvas, info);
567
568 // strike the glyph in the upper right corner
569 CGContextShowGlyphsAtPoint(canvas->context,
570 -info->topLeftX,
571 canvas->image->height + info->topLeftY,
572 &glyph, 1);
573
574 // copy the glyph from the canvas into the info
575 (*mode->glyphDescriptor->copyFxnPtr)(canvas, info);
576 }
577
578 /*
579 * CoreText path...
580 */
581 static inline GlyphInfo *
582 CGGI_CreateImageForUnicode
583 (CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
584 const CGGI_RenderingMode *mode, const UniChar uniChar)
585 {
586 // save the state of the world
587 CGContextSaveGState(canvas->context);
588
589 // get the glyph, measure it using CG
590 CGGlyph glyph;
591 CTFontRef fallback;
592 if (uniChar > 0xFFFF) {
593 UTF16Char charRef[2];
838 * and advances. Unfortunately to use CG or CT in bulk runs (which is
839 * faster than calling them per character), we have to copy into and out
840 * of these buffers. Still a net win though.
841 */
842 void
843 CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
844 const AWTStrike *strike,
845 jint rawGlyphCodes[], const CFIndex len)
846 {
847 const CGGI_RenderingMode mode = CGGI_GetRenderingMode(strike);
848
849 if (len < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) {
850 CGRect bboxes[len];
851 CGSize advances[len];
852 CGGlyph glyphs[len];
853 UniChar uniChars[len];
854
855 CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
856 rawGlyphCodes, uniChars, glyphs,
857 advances, bboxes, len);
858
859 return;
860 }
861
862 // just do one malloc, and carve it up for all the buffers
863 void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
864 sizeof(CGGlyph) * sizeof(UniChar) * len);
865 if (buffer == NULL) {
866 [[NSException exceptionWithName:NSMallocException
867 reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
868 }
869
870 CGRect *bboxes = (CGRect *)(buffer);
871 CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
872 CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
873 UniChar *uniChars = (UniChar *)(glyphs + sizeof(UniChar) * len);
874
875 CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
876 rawGlyphCodes, uniChars, glyphs,
877 advances, bboxes, len);
878
879 free(buffer);
880 }
|
548 #endif
549
550 return glyphInfo;
551 }
552
553
554 #pragma mark --- Glyph Striking onto Canvas ---
555
556 /*
557 * Clears the canvas, strikes the glyph with CoreGraphics, and then
558 * copies the struck pixels into the GlyphInfo image.
559 */
560 static inline void
561 CGGI_CreateImageForGlyph
562 (CGGI_GlyphCanvas *canvas, const CGGlyph glyph,
563 GlyphInfo *info, const CGGI_RenderingMode *mode)
564 {
565 // clean the canvas
566 CGGI_ClearCanvas(canvas, info);
567
568 if (isnan(info->topLeftX) || isnan(info->topLeftY)) {
569 return;
570 }
571 // strike the glyph in the upper right corner
572 CGContextShowGlyphsAtPoint(canvas->context,
573 -info->topLeftX,
574 canvas->image->height + info->topLeftY,
575 &glyph, 1);
576 // copy the glyph from the canvas into the info
577 (*mode->glyphDescriptor->copyFxnPtr)(canvas, info);
578 }
579
580 /*
581 * CoreText path...
582 */
583 static inline GlyphInfo *
584 CGGI_CreateImageForUnicode
585 (CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
586 const CGGI_RenderingMode *mode, const UniChar uniChar)
587 {
588 // save the state of the world
589 CGContextSaveGState(canvas->context);
590
591 // get the glyph, measure it using CG
592 CGGlyph glyph;
593 CTFontRef fallback;
594 if (uniChar > 0xFFFF) {
595 UTF16Char charRef[2];
840 * and advances. Unfortunately to use CG or CT in bulk runs (which is
841 * faster than calling them per character), we have to copy into and out
842 * of these buffers. Still a net win though.
843 */
844 void
845 CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
846 const AWTStrike *strike,
847 jint rawGlyphCodes[], const CFIndex len)
848 {
849 const CGGI_RenderingMode mode = CGGI_GetRenderingMode(strike);
850
851 if (len < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) {
852 CGRect bboxes[len];
853 CGSize advances[len];
854 CGGlyph glyphs[len];
855 UniChar uniChars[len];
856
857 CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
858 rawGlyphCodes, uniChars, glyphs,
859 advances, bboxes, len);
860 return;
861 }
862
863 // just do one malloc, and carve it up for all the buffers
864 void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
865 sizeof(CGGlyph) * sizeof(UniChar) * len);
866 if (buffer == NULL) {
867 [[NSException exceptionWithName:NSMallocException
868 reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
869 }
870
871 CGRect *bboxes = (CGRect *)(buffer);
872 CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
873 CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
874 UniChar *uniChars = (UniChar *)(glyphs + sizeof(UniChar) * len);
875
876 CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
877 rawGlyphCodes, uniChars, glyphs,
878 advances, bboxes, len);
879 free(buffer);
880 }
|