Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/font/CGGlyphOutlines.m
41152 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#import "CGGlyphOutlines.h"2627static void28AWTPathGetMoreSpaceIfNecessary(AWTPathRef path)29{30while ((path->fAllocatedSegmentTypeSpace - path->fNumberOfSegments) < 1) {31size_t growth = sizeof(jbyte)*path->fAllocatedSegmentTypeSpace*kStorageSizeChangeOnGetMoreFactor;32path->fSegmentType = (jbyte*) realloc(path->fSegmentType, growth);33path->fAllocatedSegmentTypeSpace *= kStorageSizeChangeOnGetMoreFactor;34}3536while ((path->fAllocatedSegmentDataSpace - path->fNumberOfDataElements) < 7) {37size_t growth = sizeof(jfloat)*path->fAllocatedSegmentDataSpace*kStorageSizeChangeOnGetMoreFactor;38path->fSegmentData = (jfloat*) realloc(path->fSegmentData, growth);39path->fAllocatedSegmentDataSpace *= kStorageSizeChangeOnGetMoreFactor;40}41}4243static void44AWTPathMoveTo(void* data, CGPoint p)45{46CGFloat x = p.x;47CGFloat y = p.y;4849AWTPathRef path = (AWTPathRef)data;50CGFloat tx = path->fTranslate.width;51CGFloat ty = path->fTranslate.height;52CGFloat pathX = x+tx;53CGFloat pathY = -y+ty;5455#ifdef AWT_GV_DEBUG56fprintf(stderr, "eMoveTo \n");57fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);58fprintf(stderr, " x=%f, y=%f\n", x, y);59fprintf(stderr, " pathX=%f, pathY=%f\n", pathX, pathY);60#endif6162AWTPathGetMoreSpaceIfNecessary(path);6364path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eMoveTo;6566path->fSegmentData[path->fNumberOfDataElements++] = pathX;67path->fSegmentData[path->fNumberOfDataElements++] = pathY;68}6970static void71AWTPathLineTo(void* data, CGPoint p)72{73CGFloat x = p.x;74CGFloat y = p.y;7576AWTPathRef path = (AWTPathRef)data;77CGFloat tx = path->fTranslate.width;78CGFloat ty = path->fTranslate.height;79CGFloat pathX = x+tx;80CGFloat pathY = -y+ty;8182#ifdef AWT_GV_DEBUG83fprintf(stderr, "eLineTo \n");84fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);85fprintf(stderr, " x=%f, y=%f\n", x, y);86fprintf(stderr, " pathX=%f, pathY=%f\n", pathX, pathY);87#endif8889AWTPathGetMoreSpaceIfNecessary(path);9091path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eLineTo;9293path->fSegmentData[path->fNumberOfDataElements++] = pathX;94path->fSegmentData[path->fNumberOfDataElements++] = pathY;95}9697static void98AWTPathQuadTo(void* data, CGPoint p1, CGPoint p2)99{100CGFloat x1 = p1.x;101CGFloat y1 = p1.y;102CGFloat x2 = p2.x;103CGFloat y2 = p2.y;104105AWTPathRef path = (AWTPathRef)data;106CGFloat tx = path->fTranslate.width;107CGFloat ty = path->fTranslate.height;108CGFloat pathX1 = x1+tx;109CGFloat pathY1 = -y1+ty;110CGFloat pathX2 = x2+tx;111CGFloat pathY2 = -y2+ty;112113#ifdef AWT_GV_DEBUG114fprintf(stderr, "eQuadTo \n");115fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);116fprintf(stderr, " x1=%f, y1=%f\n", x1, y1);117fprintf(stderr, " x2=%f, y2=%f\n", x2, y2);118fprintf(stderr, " pathX1=%f, path1Y=%f\n", pathX1, pathY1);119fprintf(stderr, " pathX2=%f, pathY2=%f\n", pathX2, pathY2);120#endif121122AWTPathGetMoreSpaceIfNecessary(path);123124path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eQuadTo;125126path->fSegmentData[path->fNumberOfDataElements++] = pathX1;127path->fSegmentData[path->fNumberOfDataElements++] = pathY1;128path->fSegmentData[path->fNumberOfDataElements++] = pathX2;129path->fSegmentData[path->fNumberOfDataElements++] = pathY2;130}131132static void133AWTPathCubicTo(void* data, CGPoint p1, CGPoint p2, CGPoint p3)134{135CGFloat x1 = p1.x;136CGFloat y1 = p1.y;137CGFloat x2 = p2.x;138CGFloat y2 = p2.y;139CGFloat x3 = p3.x;140CGFloat y3 = p3.y;141142AWTPathRef path = (AWTPathRef)data;143CGFloat tx = path->fTranslate.width;144CGFloat ty = path->fTranslate.height;145CGFloat pathX1 = x1+tx;146CGFloat pathY1 = -y1+ty;147CGFloat pathX2 = x2+tx;148CGFloat pathY2 = -y2+ty;149CGFloat pathX3 = x3+tx;150CGFloat pathY3 = -y3+ty;151152#ifdef AWT_GV_DEBUG153fprintf(stderr, "eCubicTo \n");154fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);155fprintf(stderr, " x1=%f, y1=%f\n", x1, y1);156fprintf(stderr, " x2=%f, y2=%f\n", x2, y2);157fprintf(stderr, " x3=%f, y3=%f\n", x3, y3);158fprintf(stderr, " pathX1=%f, path1Y=%f\n", pathX1, pathY1);159fprintf(stderr, " pathX2=%f, pathY2=%f\n", pathX2, pathY2);160fprintf(stderr, " pathX3=%f, pathY3=%f\n", pathX3, pathY3);161#endif162163AWTPathGetMoreSpaceIfNecessary(path);164165path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eCubicTo;166167path->fSegmentData[path->fNumberOfDataElements++] = pathX1;168path->fSegmentData[path->fNumberOfDataElements++] = pathY1;169path->fSegmentData[path->fNumberOfDataElements++] = pathX2;170path->fSegmentData[path->fNumberOfDataElements++] = pathY2;171path->fSegmentData[path->fNumberOfDataElements++] = pathX3;172path->fSegmentData[path->fNumberOfDataElements++] = pathY3;173}174175static void176AWTPathClose(void* data)177{178#ifdef AWT_GV_DEBUG179fprintf(stderr, "GVGlyphPathCallBackClosePath \n");180#endif181182AWTPathRef path = (AWTPathRef) data;183AWTPathGetMoreSpaceIfNecessary(path);184185path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eClosePath;186}187188AWTPathRef189AWTPathCreate(CGSize translate)190{191#ifdef AWT_GV_DEBUG192fprintf(stderr, "AWTPathCreate \n");193fprintf(stderr, " translate.width=%f \n", translate.width);194fprintf(stderr, " translate.height=%f \n", translate.height);195#endif196197AWTPathRef path = (AWTPathRef) malloc(sizeof(AWTPath));198path->fTranslate = translate;199path->fSegmentData = (jfloat*)malloc(sizeof(jfloat) * kInitialAllocatedPathSegments);200path->fSegmentType = (jbyte*)malloc(sizeof(jbyte) * kInitialAllocatedPathSegments);201path->fNumberOfDataElements = 0;202path->fNumberOfSegments = 0;203path->fAllocatedSegmentTypeSpace = kInitialAllocatedPathSegments;204path->fAllocatedSegmentDataSpace = kInitialAllocatedPathSegments;205206return path;207}208209void210AWTPathFree(AWTPathRef pathRef)211{212#ifdef AWT_GV_DEBUG213fprintf(stderr, "--B--AWTPathFree\n");214fprintf(stderr, "pathRef->fSegmentData (%p)\n",pathRef->fSegmentData);215#endif216217free(pathRef->fSegmentData);218//fprintf(stderr, "pathRef->fSegmentType (%d)\n",pathRef->fSegmentType);219free(pathRef->fSegmentType);220//fprintf(stderr, "pathRef (%d)\n", pathRef);221free(pathRef);222//fprintf(stderr, "--E--AWTPathFree\n");223}224225static void226AWTPathApplierCallback(void *info, const CGPathElement *element)227{228switch (element->type) {229case kCGPathElementMoveToPoint:230AWTPathMoveTo(info, element->points[0]);231break;232case kCGPathElementAddLineToPoint:233AWTPathLineTo(info, element->points[0]);234break;235case kCGPathElementAddQuadCurveToPoint:236AWTPathQuadTo(info, element->points[0], element->points[1]);237break;238case kCGPathElementAddCurveToPoint:239AWTPathCubicTo(info, element->points[0],240element->points[1], element->points[2]);241break;242case kCGPathElementCloseSubpath:243AWTPathClose(info);244break;245}246}247248OSStatus249AWTGetGlyphOutline(CGGlyph *glyphs, NSFont *font,250CGSize *advanceArray, CGAffineTransform *tx,251UInt32 inStartIndex, size_t length,252AWTPathRef* outPath)253{254#ifdef AWT_GV_DEBUG255fprintf(stderr, "AWTGetGlyphOutline\n");256fprintf(stderr, " inAffineTransform a=%f, b=%f, c=%f, d=%f, tx=%f, ty=%f \n", tx->a, tx->b, tx->c, tx->d, tx->tx, tx->ty);257#endif258259OSStatus status = noErr;260261if ( isnan(tx->a) || isnan(tx->b) || isnan(tx->c) ||262isnan(tx->d) || isnan(tx->tx) || isnan(tx->ty)) {263return status;264}265glyphs = glyphs + inStartIndex;266// advanceArray = advanceArray + inStartIndex; // TODO(cpc): use advance267268CGPathRef cgPath = CTFontCreatePathForGlyph((CTFontRef)font, glyphs[0], tx);269CGPathApply(cgPath, *outPath, AWTPathApplierCallback);270CGPathRelease(cgPath);271272return status;273}274275276