4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/A#import "CGGlyphOutlines.h"
4632N/A
4632N/Astatic void
4632N/AAWTPathGetMoreSpaceIfNecessary(AWTPathRef path)
4632N/A{
4632N/A while ((path->fAllocatedSegmentTypeSpace - path->fNumberOfSegments) < 1) {
4632N/A size_t growth = sizeof(jbyte)*path->fAllocatedSegmentTypeSpace*kStorageSizeChangeOnGetMoreFactor;
4632N/A path->fSegmentType = (jbyte*) realloc(path->fSegmentType, growth);
4632N/A path->fAllocatedSegmentTypeSpace *= kStorageSizeChangeOnGetMoreFactor;
4632N/A }
4632N/A
4632N/A while ((path->fAllocatedSegmentDataSpace - path->fNumberOfDataElements) < 7) {
4632N/A size_t growth = sizeof(jfloat)*path->fAllocatedSegmentDataSpace*kStorageSizeChangeOnGetMoreFactor;
4632N/A path->fSegmentData = (jfloat*) realloc(path->fSegmentData, growth);
4632N/A path->fAllocatedSegmentDataSpace *= kStorageSizeChangeOnGetMoreFactor;
4632N/A }
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathMoveTo(void* data, CGPoint p)
4632N/A{
4632N/A CGFloat x = p.x;
4632N/A CGFloat y = p.y;
4632N/A
4632N/A AWTPathRef path = (AWTPathRef)data;
4632N/A CGFloat tx = path->fTranslate.width;
4632N/A CGFloat ty = path->fTranslate.height;
4632N/A CGFloat pathX = x+tx;
4632N/A CGFloat pathY = -y+ty;
4632N/A
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "eMoveTo \n");
4632N/A fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);
4632N/A fprintf(stderr, " x=%f, y=%f\n", x, y);
4632N/A fprintf(stderr, " pathX=%f, pathY=%f\n", pathX, pathY);
4632N/A#endif
4632N/A
4632N/A AWTPathGetMoreSpaceIfNecessary(path);
4632N/A
4632N/A path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eMoveTo;
4632N/A
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY;
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathLineTo(void* data, CGPoint p)
4632N/A{
4632N/A CGFloat x = p.x;
4632N/A CGFloat y = p.y;
4632N/A
4632N/A AWTPathRef path = (AWTPathRef)data;
4632N/A CGFloat tx = path->fTranslate.width;
4632N/A CGFloat ty = path->fTranslate.height;
4632N/A CGFloat pathX = x+tx;
4632N/A CGFloat pathY = -y+ty;
4632N/A
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "eLineTo \n");
4632N/A fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);
4632N/A fprintf(stderr, " x=%f, y=%f\n", x, y);
4632N/A fprintf(stderr, " pathX=%f, pathY=%f\n", pathX, pathY);
4632N/A#endif
4632N/A
4632N/A AWTPathGetMoreSpaceIfNecessary(path);
4632N/A
4632N/A path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eLineTo;
4632N/A
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY;
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathQuadTo(void* data, CGPoint p1, CGPoint p2)
4632N/A{
4632N/A CGFloat x1 = p1.x;
4632N/A CGFloat y1 = p1.y;
4632N/A CGFloat x2 = p2.x;
4632N/A CGFloat y2 = p2.y;
4632N/A
4632N/A AWTPathRef path = (AWTPathRef)data;
4632N/A CGFloat tx = path->fTranslate.width;
4632N/A CGFloat ty = path->fTranslate.height;
4632N/A CGFloat pathX1 = x1+tx;
4632N/A CGFloat pathY1 = -y1+ty;
4632N/A CGFloat pathX2 = x2+tx;
4632N/A CGFloat pathY2 = -y2+ty;
4632N/A
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "eQuadTo \n");
4632N/A fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);
4632N/A fprintf(stderr, " x1=%f, y1=%f\n", x1, y1);
4632N/A fprintf(stderr, " x2=%f, y2=%f\n", x2, y2);
4632N/A fprintf(stderr, " pathX1=%f, path1Y=%f\n", pathX1, pathY1);
4632N/A fprintf(stderr, " pathX2=%f, pathY2=%f\n", pathX2, pathY2);
4632N/A#endif
4632N/A
4632N/A AWTPathGetMoreSpaceIfNecessary(path);
4632N/A
4632N/A path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eQuadTo;
4632N/A
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX1;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY1;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX2;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY2;
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathCubicTo(void* data, CGPoint p1, CGPoint p2, CGPoint p3)
4632N/A{
4632N/A CGFloat x1 = p1.x;
4632N/A CGFloat y1 = p1.y;
4632N/A CGFloat x2 = p2.x;
4632N/A CGFloat y2 = p2.y;
4632N/A CGFloat x3 = p3.x;
4632N/A CGFloat y3 = p3.y;
4632N/A
4632N/A AWTPathRef path = (AWTPathRef)data;
4632N/A CGFloat tx = path->fTranslate.width;
4632N/A CGFloat ty = path->fTranslate.height;
4632N/A CGFloat pathX1 = x1+tx;
4632N/A CGFloat pathY1 = -y1+ty;
4632N/A CGFloat pathX2 = x2+tx;
4632N/A CGFloat pathY2 = -y2+ty;
4632N/A CGFloat pathX3 = x3+tx;
4632N/A CGFloat pathY3 = -y3+ty;
4632N/A
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "eCubicTo \n");
4632N/A fprintf(stderr, " tx=%f, ty=%f\n", tx, ty);
4632N/A fprintf(stderr, " x1=%f, y1=%f\n", x1, y1);
4632N/A fprintf(stderr, " x2=%f, y2=%f\n", x2, y2);
4632N/A fprintf(stderr, " x3=%f, y3=%f\n", x3, y3);
4632N/A fprintf(stderr, " pathX1=%f, path1Y=%f\n", pathX1, pathY1);
4632N/A fprintf(stderr, " pathX2=%f, pathY2=%f\n", pathX2, pathY2);
4632N/A fprintf(stderr, " pathX3=%f, pathY3=%f\n", pathX3, pathY3);
4632N/A#endif
4632N/A
4632N/A AWTPathGetMoreSpaceIfNecessary(path);
4632N/A
4632N/A path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eCubicTo;
4632N/A
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX1;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY1;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX2;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY2;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathX3;
4632N/A path->fSegmentData[path->fNumberOfDataElements++] = pathY3;
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathClose(void* data)
4632N/A{
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "GVGlyphPathCallBackClosePath \n");
4632N/A#endif
4632N/A
4632N/A AWTPathRef path = (AWTPathRef) data;
4632N/A AWTPathGetMoreSpaceIfNecessary(path);
4632N/A
4632N/A path->fSegmentType[path->fNumberOfSegments++] = (jbyte)eClosePath;
4632N/A}
4632N/A
4632N/AAWTPathRef
4632N/AAWTPathCreate(CGSize translate)
4632N/A{
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "AWTPathCreate \n");
4632N/A fprintf(stderr, " translate.width=%f \n", translate.width);
4632N/A fprintf(stderr, " translate.height=%f \n", translate.height);
4632N/A#endif
4632N/A
4632N/A AWTPathRef path = (AWTPathRef) malloc(sizeof(AWTPath));
4632N/A path->fTranslate = translate;
4632N/A path->fSegmentData = (jfloat*)malloc(sizeof(jfloat) * kInitialAllocatedPathSegments);
4632N/A path->fSegmentType = (jbyte*)malloc(sizeof(jbyte) * kInitialAllocatedPathSegments);
4632N/A path->fNumberOfDataElements = 0;
4632N/A path->fNumberOfSegments = 0;
4632N/A path->fAllocatedSegmentTypeSpace = kInitialAllocatedPathSegments;
4632N/A path->fAllocatedSegmentDataSpace = kInitialAllocatedPathSegments;
4632N/A
4632N/A return path;
4632N/A}
4632N/A
4632N/Avoid
4632N/AAWTPathFree(AWTPathRef pathRef)
4632N/A{
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "--B--AWTPathFree\n");
4632N/A fprintf(stderr, "pathRef->fSegmentData (%p)\n",pathRef->fSegmentData);
4632N/A#endif
4632N/A
4632N/A free(pathRef->fSegmentData);
4632N/A //fprintf(stderr, "pathRef->fSegmentType (%d)\n",pathRef->fSegmentType);
4632N/A free(pathRef->fSegmentType);
4632N/A //fprintf(stderr, "pathRef (%d)\n", pathRef);
4632N/A free(pathRef);
4632N/A //fprintf(stderr, "--E--AWTPathFree\n");
4632N/A}
4632N/A
4632N/Astatic void
4632N/AAWTPathApplierCallback(void *info, const CGPathElement *element)
4632N/A{
4632N/A switch (element->type) {
4632N/A case kCGPathElementMoveToPoint:
4632N/A AWTPathMoveTo(info, element->points[0]);
4632N/A break;
4632N/A case kCGPathElementAddLineToPoint:
4632N/A AWTPathLineTo(info, element->points[0]);
4632N/A break;
4632N/A case kCGPathElementAddQuadCurveToPoint:
4632N/A AWTPathQuadTo(info, element->points[0], element->points[1]);
4632N/A break;
4632N/A case kCGPathElementAddCurveToPoint:
4632N/A AWTPathCubicTo(info, element->points[0],
4632N/A element->points[1], element->points[2]);
4632N/A break;
4632N/A case kCGPathElementCloseSubpath:
4632N/A AWTPathClose(info);
4632N/A break;
4632N/A }
4632N/A}
4632N/A
4632N/AOSStatus
4632N/AAWTGetGlyphOutline(CGGlyph *glyphs, NSFont *font,
4632N/A CGSize *advanceArray, CGAffineTransform *tx,
4632N/A UInt32 inStartIndex, size_t length,
4632N/A AWTPathRef* outPath)
4632N/A{
4632N/A#ifdef AWT_GV_DEBUG
4632N/A fprintf(stderr, "AWTGetGlyphOutline\n");
4632N/A fprintf(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);
4632N/A#endif
4632N/A
4632N/A OSStatus status = noErr;
4632N/A
4632N/A glyphs = glyphs + inStartIndex;
4632N/A// advanceArray = advanceArray + inStartIndex; // TODO(cpc): use advance
4632N/A
4632N/A CGPathRef cgPath = CTFontCreatePathForGlyph((CTFontRef)font, glyphs[0], tx);
4632N/A CGPathApply(cgPath, *outPath, AWTPathApplierCallback);
4632N/A CGPathRelease(cgPath);
4632N/A
4632N/A return status;
4632N/A}