src/macosx/native/sun/font/CGGlyphImages.m

Print this page


   1 /*
   2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 438 
 439     // clean the canvas
 440 #ifdef CGGI_DEBUG
 441     Pixel_8888 opaqueWhite = { 0xE0, 0xE0, 0xE0, 0xE0 };
 442 #else
 443     Pixel_8888 opaqueWhite = { 0xFF, 0xFF, 0xFF, 0xFF };
 444 #endif
 445 
 446     vImageBufferFill_ARGB8888(&canvasRectToClear, opaqueWhite, kvImageNoFlags);
 447 }
 448 
 449 
 450 #pragma mark --- GlyphInfo Creation & Copy Functions ---
 451 
 452 /*
 453  * Creates a GlyphInfo with exactly the correct size image and measurements.
 454  */
 455 #define CGGI_GLYPH_BBOX_PADDING 2.0f
 456 static inline GlyphInfo *
 457 CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,

 458                             const CGGI_RenderingMode *mode)
 459 {
 460     size_t pixelSize = mode->glyphDescriptor->pixelSize;
 461 
 462     // adjust the bounding box to be 1px bigger on each side than what
 463     // CGFont-whatever suggests - because it gives a bounding box that
 464     // is too tight
 465     bbox.size.width += CGGI_GLYPH_BBOX_PADDING * 2.0f;
 466     bbox.size.height += CGGI_GLYPH_BBOX_PADDING * 2.0f;
 467     bbox.origin.x -= CGGI_GLYPH_BBOX_PADDING;
 468     bbox.origin.y -= CGGI_GLYPH_BBOX_PADDING;
 469 
 470     vImagePixelCount width = ceilf(bbox.size.width);
 471     vImagePixelCount height = ceilf(bbox.size.height);
 472 
 473     // if the glyph is larger than 1MB, don't even try...
 474     // the GlyphVector path should have taken over by now
 475     // and zero pixels is ok
 476     if (width * height > 1024 * 1024) {
 477         width = 1;
 478         height = 1;
 479     }






 480 
 481 #ifdef USE_IMAGE_ALIGNED_MEMORY
 482     // create separate memory
 483     GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo));
 484     void *image = (void *)malloc(height * width * pixelSize);
 485 #else
 486     // create a GlyphInfo struct fused to the image it points to
 487     GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo) +
 488                                                height * width * pixelSize);
 489 #endif
 490 
 491     glyphInfo->advanceX = advance.width;
 492     glyphInfo->advanceY = advance.height;
 493     glyphInfo->topLeftX = round(bbox.origin.x);
 494     glyphInfo->topLeftY = round(bbox.origin.y);
 495     glyphInfo->width = width;
 496     glyphInfo->height = height;
 497     glyphInfo->rowBytes = width * pixelSize;
 498     glyphInfo->cellInfo = NULL;
 499 


 547     CTFontRef fallback;
 548     if (uniChar > 0xFFFF) {
 549         UTF16Char charRef[2];
 550         CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
 551         CGGlyph glyphTmp[2];
 552         fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
 553         glyph = glyphTmp[0];
 554     } else {
 555         UTF16Char charRef;
 556         charRef = (UTF16Char) uniChar; // truncate.
 557         fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
 558     }
 559 
 560     CGAffineTransform tx = strike->fTx;
 561     JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
 562 
 563     CGRect bbox;
 564     JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, style, &glyph, 1, &bbox);
 565 
 566     CGSize advance;
 567     JRSFontGetAdvancesForGlyphsAndStyle(fallback, &tx, strike->fStyle, &glyph, 1, &advance);
 568 
 569     // create the Sun2D GlyphInfo we are going to strike into
 570     GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, mode);
 571 
 572     // fix the context size, just in case the substituted character is unexpectedly large
 573     CGGI_SizeCanvas(canvas, info->width, info->height, mode->cgFontMode);
 574 
 575     // align the transform for the real CoreText strike
 576     CGContextSetTextMatrix(canvas->context, strike->fAltTx);
 577 
 578     const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
 579     CGContextSetFont(canvas->context, cgFallback);
 580     CFRelease(cgFallback);
 581 
 582     // clean the canvas - align, strike, and copy the glyph from the canvas into the info
 583     CGGI_CreateImageForGlyph(canvas, glyph, info, mode);
 584 
 585     // restore the state of the world
 586     CGContextRestoreGState(canvas->context);
 587 
 588     CFRelease(fallback);
 589 #ifdef CGGI_DEBUG
 590     DUMP_GLYPHINFO(info);


 698  * Finds the advances and bounding boxes of the characters in the run,
 699  * cycles through all the bounds and calculates the maximum canvas space
 700  * required by the largest glyph.
 701  *
 702  * Creates a GlyphInfo struct with a malloc that also encapsulates the
 703  * image the struct points to.  This is done to meet memory layout
 704  * expectations in the Sun text rasterizer memory managment code.
 705  * The image immediately follows the struct physically in memory.
 706  */
 707 static inline void
 708 CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
 709                       const CGGI_RenderingMode *mode,
 710                       const UniChar uniChars[], const CGGlyph glyphs[],
 711                       CGSize advances[], CGRect bboxes[], const CFIndex len)
 712 {
 713     AWTFont *font = strike->fAWTFont;
 714     CGAffineTransform tx = strike->fTx;
 715     JRSFontRenderingStyle bboxCGMode = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
 716 
 717     JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, bboxCGMode, glyphs, len, bboxes);
 718     JRSFontGetAdvancesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, strike->fStyle, glyphs, len, advances);
 719 
 720     size_t maxWidth = 1;
 721     size_t maxHeight = 1;
 722 
 723     CFIndex i;
 724     for (i = 0; i < len; i++)
 725     {
 726         if (uniChars[i] != 0)
 727         {
 728             glyphInfos[i] = 0L;
 729             continue; // will be handled later
 730         }
 731 
 732         CGSize advance = advances[i];
 733         CGRect bbox = bboxes[i];
 734 
 735         GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, mode);
 736 
 737         if (maxWidth < glyphInfo->width)   maxWidth = glyphInfo->width;
 738         if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height;
 739 
 740         glyphInfos[i] = ptr_to_jlong(glyphInfo);
 741     }
 742 
 743     CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
 744                              glyphs, maxWidth, maxHeight, len);
 745 }
 746 
 747 
 748 #pragma mark --- Temporary Buffer Allocations and Initialization ---
 749 
 750 /*
 751  * This stage separates the already valid glyph codes from the unicode values
 752  * that need special handling - the rawGlyphCodes array is no longer used
 753  * after this stage.
 754  */
 755 static void


   1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 438 
 439     // clean the canvas
 440 #ifdef CGGI_DEBUG
 441     Pixel_8888 opaqueWhite = { 0xE0, 0xE0, 0xE0, 0xE0 };
 442 #else
 443     Pixel_8888 opaqueWhite = { 0xFF, 0xFF, 0xFF, 0xFF };
 444 #endif
 445 
 446     vImageBufferFill_ARGB8888(&canvasRectToClear, opaqueWhite, kvImageNoFlags);
 447 }
 448 
 449 
 450 #pragma mark --- GlyphInfo Creation & Copy Functions ---
 451 
 452 /*
 453  * Creates a GlyphInfo with exactly the correct size image and measurements.
 454  */
 455 #define CGGI_GLYPH_BBOX_PADDING 2.0f
 456 static inline GlyphInfo *
 457 CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
 458                             const AWTStrike *strike,
 459                             const CGGI_RenderingMode *mode)
 460 {
 461     size_t pixelSize = mode->glyphDescriptor->pixelSize;
 462 
 463     // adjust the bounding box to be 1px bigger on each side than what
 464     // CGFont-whatever suggests - because it gives a bounding box that
 465     // is too tight
 466     bbox.size.width += CGGI_GLYPH_BBOX_PADDING * 2.0f;
 467     bbox.size.height += CGGI_GLYPH_BBOX_PADDING * 2.0f;
 468     bbox.origin.x -= CGGI_GLYPH_BBOX_PADDING;
 469     bbox.origin.y -= CGGI_GLYPH_BBOX_PADDING;
 470 
 471     vImagePixelCount width = ceilf(bbox.size.width);
 472     vImagePixelCount height = ceilf(bbox.size.height);
 473 
 474     // if the glyph is larger than 1MB, don't even try...
 475     // the GlyphVector path should have taken over by now
 476     // and zero pixels is ok
 477     if (width * height > 1024 * 1024) {
 478         width = 1;
 479         height = 1;
 480     }
 481     advance = CGSizeApplyAffineTransform(advance, strike->fFontTx);
 482     if (!JRSFontStyleUsesFractionalMetrics(strike->fStyle)) {
 483         advance.width = round(advance.width);
 484         advance.height = round(advance.height);
 485     }
 486     advance = CGSizeApplyAffineTransform(advance, strike->fDevTx);
 487 
 488 #ifdef USE_IMAGE_ALIGNED_MEMORY
 489     // create separate memory
 490     GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo));
 491     void *image = (void *)malloc(height * width * pixelSize);
 492 #else
 493     // create a GlyphInfo struct fused to the image it points to
 494     GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo) +
 495                                                height * width * pixelSize);
 496 #endif
 497 
 498     glyphInfo->advanceX = advance.width;
 499     glyphInfo->advanceY = advance.height;
 500     glyphInfo->topLeftX = round(bbox.origin.x);
 501     glyphInfo->topLeftY = round(bbox.origin.y);
 502     glyphInfo->width = width;
 503     glyphInfo->height = height;
 504     glyphInfo->rowBytes = width * pixelSize;
 505     glyphInfo->cellInfo = NULL;
 506 


 554     CTFontRef fallback;
 555     if (uniChar > 0xFFFF) {
 556         UTF16Char charRef[2];
 557         CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
 558         CGGlyph glyphTmp[2];
 559         fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
 560         glyph = glyphTmp[0];
 561     } else {
 562         UTF16Char charRef;
 563         charRef = (UTF16Char) uniChar; // truncate.
 564         fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
 565     }
 566 
 567     CGAffineTransform tx = strike->fTx;
 568     JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
 569 
 570     CGRect bbox;
 571     JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, style, &glyph, 1, &bbox);
 572 
 573     CGSize advance;
 574     CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
 575 
 576     // create the Sun2D GlyphInfo we are going to strike into
 577     GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mode);
 578 
 579     // fix the context size, just in case the substituted character is unexpectedly large
 580     CGGI_SizeCanvas(canvas, info->width, info->height, mode->cgFontMode);
 581 
 582     // align the transform for the real CoreText strike
 583     CGContextSetTextMatrix(canvas->context, strike->fAltTx);
 584 
 585     const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
 586     CGContextSetFont(canvas->context, cgFallback);
 587     CFRelease(cgFallback);
 588 
 589     // clean the canvas - align, strike, and copy the glyph from the canvas into the info
 590     CGGI_CreateImageForGlyph(canvas, glyph, info, mode);
 591 
 592     // restore the state of the world
 593     CGContextRestoreGState(canvas->context);
 594 
 595     CFRelease(fallback);
 596 #ifdef CGGI_DEBUG
 597     DUMP_GLYPHINFO(info);


 705  * Finds the advances and bounding boxes of the characters in the run,
 706  * cycles through all the bounds and calculates the maximum canvas space
 707  * required by the largest glyph.
 708  *
 709  * Creates a GlyphInfo struct with a malloc that also encapsulates the
 710  * image the struct points to.  This is done to meet memory layout
 711  * expectations in the Sun text rasterizer memory managment code.
 712  * The image immediately follows the struct physically in memory.
 713  */
 714 static inline void
 715 CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
 716                       const CGGI_RenderingMode *mode,
 717                       const UniChar uniChars[], const CGGlyph glyphs[],
 718                       CGSize advances[], CGRect bboxes[], const CFIndex len)
 719 {
 720     AWTFont *font = strike->fAWTFont;
 721     CGAffineTransform tx = strike->fTx;
 722     JRSFontRenderingStyle bboxCGMode = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
 723 
 724     JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, bboxCGMode, glyphs, len, bboxes);
 725     CTFontGetAdvancesForGlyphs((CTFontRef)font->fFont, kCTFontDefaultOrientation, glyphs, advances, len);
 726 
 727     size_t maxWidth = 1;
 728     size_t maxHeight = 1;
 729 
 730     CFIndex i;
 731     for (i = 0; i < len; i++)
 732     {
 733         if (uniChars[i] != 0)
 734         {
 735             glyphInfos[i] = 0L;
 736             continue; // will be handled later
 737         }
 738 
 739         CGSize advance = advances[i];
 740         CGRect bbox = bboxes[i];
 741 
 742         GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mode);
 743 
 744         if (maxWidth < glyphInfo->width)   maxWidth = glyphInfo->width;
 745         if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height;
 746 
 747         glyphInfos[i] = ptr_to_jlong(glyphInfo);
 748     }
 749 
 750     CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
 751                              glyphs, maxWidth, maxHeight, len);
 752 }
 753 
 754 
 755 #pragma mark --- Temporary Buffer Allocations and Initialization ---
 756 
 757 /*
 758  * This stage separates the already valid glyph codes from the unicode values
 759  * that need special handling - the rawGlyphCodes array is no longer used
 760  * after this stage.
 761  */
 762 static void