in modules/awt/src/main/native/fontlib/shared/ParsingTables.cpp [856:1127]
fint parseGlyphData(FILE* tt_file, const GlyphOffsets gO, ufshort numGlyphs, ufshort glyphIndex, TTCurve *curve, fshort* bRect, ffloat transform)
{
uflong offset;
Glyph_header glyphHeader;
fshort numOfContours;
ufshort *endPtsOfContours = NULL;
ufshort instructionLength;//instruction length in bytes
ufchar* instructions = NULL;
ufchar* flags = NULL;
ufchar* xCoord = NULL; //pointer to array of X coordinates
ufchar* yCoord = NULL; //pointer to array of Y coordinates
ufchar* tmp = NULL;
fint numPoints; // number of Points
fint size, i, j, curLen;
fint flagIndex = 0;
fint xCoordIndex = 0;
fint yCoordIndex = 0;
fint rep = 0;
fshort xLength = 0; //length of array of X coordinates
fshort yLength = 0; //length of array of Y coordinates
ufchar curFlag = 0;
if (glyphIndex >= numGlyphs)
{
// printf("debug info: glyphIndex out of range");
glyphIndex = 0;
}
offset = gO.offsets[glyphIndex];
if (offset == gO.offsets[glyphIndex+1])
{
curve->add(0,0, 1);
return 0;
}
size = fseek(tt_file, offset, SEEK_SET);
if (size != 0){
// printf("Error executing fseek() for someone glyph.");
return -1;
}
/* read 'Glyph_header' table */
size = (fint)fread(&glyphHeader, sizeof(Glyph_header), 1, tt_file);
if (size != 1){
// printf("Error reading 'Glyph_header' table from file.");
return -1;
}
glyphHeader.number_of_contours = wReverse(glyphHeader.number_of_contours);
numOfContours = glyphHeader.number_of_contours;
bRect[0] = (short)(wReverse(glyphHeader.xMin)*transform);
bRect[1] = (short)(wReverse(glyphHeader.yMin)*transform);
bRect[2] = (short)(wReverse(glyphHeader.xMax)*transform);
bRect[3] = (short)(wReverse(glyphHeader.yMax)*transform);
if (numOfContours > 0)
{
endPtsOfContours = new ufshort[numOfContours];
size = (fint)fread(endPtsOfContours, sizeof(fshort),numOfContours,tt_file);
if (size != numOfContours)
{
// printf("Error reading endPtsOfContours for someone glyph.");
delete[] endPtsOfContours;
return -1;
}
for (i=0; i<numOfContours; i++)
{
endPtsOfContours[i] = wReverse(endPtsOfContours[i]);
}
numPoints = endPtsOfContours[i-1] + 1;
size = (fint)fread(&instructionLength,sizeof(fshort),1,tt_file);
if (size != 1)
{
// printf("Error reading length of instructions./n");
delete[] endPtsOfContours;
return -1;
}
instructionLength = wReverse(instructionLength);
instructions = new ufchar[instructionLength];
size = (fint)fread(instructions,sizeof(ufchar),instructionLength,tt_file);
if (size != instructionLength)
{
// printf("Error reading instructions./n");
delete[] instructions;
delete[] endPtsOfContours;
return -1;
}
curLen=0;
flags = NULL;
for (i=0; i<numPoints; i++)
{
fint x_repeat = 0;
fint y_repeat = 0;
tmp = flags;
curLen++;
flags = new ufchar[curLen];
memcpy(flags,tmp,curLen-1);
delete[] tmp;
size = (fint)fread(&(flags[curLen-1]),sizeof(ufchar),1,tt_file);
if (size != 1)
{
// printf("Error reading array of flags from font file.\n");
delete[] flags;
delete[] instructions;
delete[] endPtsOfContours;
return -1;
}
if ((flags[curLen-1] & X_POSITIVE) == X_POSITIVE ||
(flags[curLen-1] & X_POSITIVE) == X_NEGATIVE)
x_repeat = 1;
else if ((flags[curLen-1] & X_POSITIVE) == X_DWORD)
x_repeat = 2;
if ((flags[curLen-1] & Y_POSITIVE) == Y_POSITIVE ||
(flags[curLen-1] & Y_POSITIVE) == Y_NEGATIVE)
y_repeat = 1;
else if ((flags[curLen-1] & Y_POSITIVE) == Y_DWORD)
y_repeat = 2;
if(flags[curLen-1] & REPEAT)
{
tmp = flags;
curLen++;
flags = new ufchar[curLen];
memcpy(flags,tmp,curLen-1);
delete[] tmp;
size=(fint)fread(&(flags[curLen-1]),sizeof(ufchar),1,tt_file);
if (size != 1)
{
// printf("Error reading array of flags from font file.\n");
delete[] flags;
delete[] instructions;
delete[] endPtsOfContours;
return -1;
}
xLength += x_repeat*(flags[curLen-1] + 1);
yLength += y_repeat*(flags[curLen-1] + 1);
i += flags[curLen-1];
} else
xLength += x_repeat;
yLength += y_repeat;
}
xCoord = new ufchar[xLength];
yCoord = new ufchar[yLength];
size = (fint)fread(xCoord,sizeof(ufchar),xLength,tt_file);
if (size != xLength)
{
// printf("Error reading x-coordinate of glyph's point.\n");
delete[] flags;
delete[] instructions;
delete[] endPtsOfContours;
delete[] xCoord;
delete[] yCoord;
return -1;
}
size = (fint)fread(yCoord,sizeof(ufchar),yLength,tt_file);
if (size != yLength)
{
// printf("Error reading coordinates of glyph points.\n");
delete[] flags;
delete[] instructions;
delete[] endPtsOfContours;
delete[] xCoord;
delete[] yCoord;
return -1;
}
i=0;
rep=0;
fint x=0, y=0;
ffloat xFirstInContour,yFirstInContour;
bool contBegin;
for (j=0; j<numOfContours;j++)
{
fint repLim = endPtsOfContours[j];
contBegin = 1;
while(i<=repLim)
{
if (rep==0)
{
curFlag = flags[flagIndex];
flagIndex++;
rep = 1;
if (curFlag & REPEAT)
{
rep += flags[flagIndex];
flagIndex++;
}
}
fint xChange = 0, yChange = 0;
if ((curFlag & X_POSITIVE) == X_POSITIVE)
{
xChange = xCoord[xCoordIndex];
xCoordIndex++;
}else if ((curFlag & X_POSITIVE) == X_NEGATIVE)
{
xChange = -xCoord[xCoordIndex];
xCoordIndex++;
}else if ((curFlag & X_POSITIVE) == X_DWORD)
{
xChange = (fshort)((xCoord[xCoordIndex]<<8)+xCoord[xCoordIndex+1]);
xCoordIndex+=2;
}
if ((curFlag & Y_POSITIVE) == Y_POSITIVE)
{
yChange = yCoord[yCoordIndex];
yCoordIndex++;
}else if ((curFlag & Y_POSITIVE) == Y_NEGATIVE)
{
yChange = -yCoord[yCoordIndex];
yCoordIndex++;
}else if ((curFlag & Y_POSITIVE) == Y_DWORD)
{
yChange = (fshort)((yCoord[yCoordIndex]<<8)+yCoord[yCoordIndex+1]);
yCoordIndex+=2;
}
if((flagIndex >1) && !(curFlag & ON_CURVE ) &&
((rep == 1) ? (!(flags[flagIndex-2] & ON_CURVE)) : (!(flags[flagIndex-3] & ON_CURVE))))
curve->add((x+xChange/2)*transform,(y+yChange/2)*transform,FLAG_ONCURVE);
x+=xChange;
y+=yChange;
if (contBegin)
{
curve->add(x*transform,y*transform, 1);
xFirstInContour = x*transform;
yFirstInContour = y*transform;
contBegin = 0;
} else
curve->add(x*transform,y*transform, curFlag & ON_CURVE ? FLAG_ONCURVE : 0);
rep--;
i++;
}
curve->add(xFirstInContour,yFirstInContour,FLAG_ONCURVE);
}
}
delete[] xCoord;
delete[] yCoord;
delete[] flags;
delete[] endPtsOfContours;
delete[] instructions;
return 0;
}