Beispiel #1
0
SkDPoint SkDQuad::top(double startT, double endT) const {
    SkDQuad sub = subDivide(startT, endT);
    SkDPoint topPt = sub[0];
    if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX)) {
        topPt = sub[2];
    }
    if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) {
        double extremeT;
        if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) {
            extremeT = startT + (endT - startT) * extremeT;
            SkDPoint test = ptAtT(extremeT);
            if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX)) {
                topPt = test;
            }
        }
    }
    return topPt;
}
Beispiel #2
0
SkDPoint SkDCubic::top(double startT, double endT) const {
    SkDCubic sub = subDivide(startT, endT);
    SkDPoint topPt = sub[0];
    if (topPt.fY > sub[3].fY || (topPt.fY == sub[3].fY && topPt.fX > sub[3].fX)) {
        topPt = sub[3];
    }
    double extremeTs[2];
    if (!sub.monotonicInY()) {
        int roots = FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, sub[3].fY, extremeTs);
        for (int index = 0; index < roots; ++index) {
            double t = startT + (endT - startT) * extremeTs[index];
            SkDPoint mid = ptAtT(t);
            if (topPt.fY > mid.fY || (topPt.fY == mid.fY && topPt.fX > mid.fX)) {
                topPt = mid;
            }
        }
    }
    return topPt;
}
Beispiel #3
0
FS_PUBLIC int32 fsc_MeasureGlyph( 
		ContourList* pclContour,        /* glyph outline */
		GlyphBitMap* pbmpBitMap,        /* to return bounds */
		WorkScan* pwsWork,              /* to return values */
		uint16 usScanKind,              /* dropout control value */
		uint16 usRoundXMin              /* for gray scale alignment */
)
{
	uint16 usCont;                      /* contour index */
	int16 sPt;                          /* point index */
	int16 sStart, sEnd;                 /* start and end point of contours */
	int16 sOrgDir;                      /* original contour direction */
	int16 sDir;                         /* current contour direction */
	int16 sFlatCount;                   /* for contours starting flat */
	int32 lVScanCount;                  /* total vertical scan lines */
	int32 lHScanCount;                  /* total horizontal scan lines */
	int32 lTotalHIx;
	int32 lTotalVIx;
	int32 lElementCount;                /* total element point estimate */
	int32 lDivide;                      /* spline element point counter */
	int32 lErrCode;    
	
	F26Dot6 fxX1, fxX2;                 /* x coord endpoints */
	F26Dot6 fxY1, fxY2;                 /* y coord endpoints */
	F26Dot6 *pfxXCoord, *pfxYCoord;     /* for fast point array access */
	F26Dot6 fxAbsDelta;                 /* for element count check */
	uint8 byF1, byF2;                   /* oncurve flag values */
	uint8 *pbyFlags;                    /* for element count check */

	PRevRoot prrRoots;                  /* reversal list roots structure */

	
	lErrCode = FindExtrema(pclContour, pbmpBitMap); /* calc bounding box */
	if (lErrCode != NO_ERR) return lErrCode;

	pbmpBitMap->rectBounds.left &= -((int32)usRoundXMin);   /* mask off low n bits */

	prrRoots = fsc_SetupRevRoots(pwsWork->pchRBuffer, pwsWork->lRMemSize);
	lElementCount = 0;                  /* smart point counter */
	
	for (usCont = 0; usCont < pclContour->usContourCount; usCont++)
	{
		sStart = pclContour->asStartPoint[usCont];
		sEnd = pclContour->asEndPoint[usCont];
		if (sStart == sEnd)
		{
			continue;                               /* for anchor points */
		}

/* check contour Y values for direction reversals */

		fxY1 = pclContour->afxYCoord[sEnd];         /* start by closing */
		pfxYCoord = &pclContour->afxYCoord[sStart];

		sPt = sStart;
		sDir = 0;                                   /* starting dir unknown */
		sFlatCount = 0;
		while ((sDir == 0) && (sPt <= sEnd))
		{
			fxY2 = *pfxYCoord++;
			if (fxY2 > fxY1)                        /* find first up or down */
			{
				sDir = 1;
			}
			else if (fxY2 < fxY1)
			{
				sDir = -1;
			}
			else
			{
				sFlatCount++;                       /* countour starts flat */
			}
			fxY1 = fxY2;
			sPt++;
		}
		sOrgDir = sDir;                             /* save original ep check */

		while (sPt <= sEnd)
		{
			fxY2 = *pfxYCoord++;
			if (sDir == 1)
			{
				if (fxY2 <= fxY1)                   /* = is for endpoint cases */
				{
					fsc_AddYReversal (prrRoots, fxY1, 1);
					sDir = -1;
				}
			}
			else    /* if sDir == -1 */
			{
				if (fxY2 >= fxY1)                   /* = is for endpoint cases */
				{
					fsc_AddYReversal (prrRoots, fxY1, -1);
					sDir = 1;
				}
			}
			fxY1 = fxY2;                            /* next segment */
			sPt++;
		}
								
		while (sFlatCount > 0)                      /* if contour started flat */
		{
			if (sDir == 0)                          /* if completely flat */
			{
				sDir = 1;                           /* then pick a direction */
				sOrgDir = 1;
			}
			fsc_AddYReversal (prrRoots, fxY1, sDir); /* add one per point */
			sDir = -sDir;
			sFlatCount--;
		}
		if (sOrgDir != sDir)                        /* if endpoint reverses */
		{
			fsc_AddYReversal (prrRoots, fxY1, sDir); /* then balance up/down */
		}

/* if doing dropout control, check contour X values for direction reversals */

		if (!(usScanKind & SK_NODROPOUT))           /* if any kind of dropout */
		{
			fxX1 = pclContour->afxXCoord[sEnd];     /* start by closing */
			pfxXCoord = &pclContour->afxXCoord[sStart];

			sPt = sStart;
			sDir = 0;                               /* starting dir unknown */
			sFlatCount = 0;
			while ((sDir == 0) && (sPt <= sEnd))
			{
				fxX2 = *pfxXCoord++;
				if (fxX2 > fxX1)                    /* find first up or down */
				{
					sDir = 1;
				}
				else if (fxX2 < fxX1)
				{
					sDir = -1;
				}
				else
				{
					sFlatCount++;                   /* countour starts flat */
				}
				fxX1 = fxX2;
				sPt++;
			}
			sOrgDir = sDir;                         /* save original ep check */

			while (sPt <= sEnd)
			{
				fxX2 = *pfxXCoord++;
				if (sDir == 1)
				{
					if (fxX2 <= fxX1)               /* = is for endpoint cases */
					{
						fsc_AddXReversal (prrRoots, fxX1, 1);
						sDir = -1;
					}
				}
				else    /* if sDir == -1 */
				{
					if (fxX2 >= fxX1)               /* = is for endpoint cases */
					{
						fsc_AddXReversal (prrRoots, fxX1, -1);
						sDir = 1;
					}
				}
				fxX1 = fxX2;                        /* next segment */
				sPt++;
			}
									
			while (sFlatCount > 0)                  /* if contour started flat */
			{
				if (sDir == 0)                      /* if completely flat */
				{
					sDir = 1;                       /* then pick a direction */
					sOrgDir = 1;
				}
				fsc_AddXReversal (prrRoots, fxX1, sDir); /* add one per point */
				sDir = -sDir;
				sFlatCount--;
			}
			if (sOrgDir != sDir)                    /* if endpoint reverses */
			{
				fsc_AddXReversal (prrRoots, fxX1, sDir); /* then balance up/down */
			}

			if (usScanKind & SK_SMART)              /* if smart dropout control */
			{                                       /* estimate the elem point count */
				fxX1 = pclContour->afxXCoord[sEnd];
				fxY1 = pclContour->afxYCoord[sEnd];
				byF1 = pclContour->abyOnCurve[sEnd];
				pfxXCoord = &pclContour->afxXCoord[sStart];
				pfxYCoord = &pclContour->afxYCoord[sStart];
				pbyFlags = &pclContour->abyOnCurve[sStart];

				lElementCount += (uint32)(sEnd - sStart) + 2L;  /* 1/pt + 1/contour */

				for (sPt = sStart; sPt <= sEnd; sPt++)
				{
					fxX2 = *pfxXCoord++;
					fxY2 = *pfxYCoord++;
					byF2 = *pbyFlags++;

					if (((byF1 & byF2) & ONCURVE) == 0) /* if this is a spline */
					{
						if (((byF1 | byF2) & ONCURVE) == 0)
						{
							lElementCount++;            /* +1 for midpoint */
						}
								
						if (FXABS(fxX2 - fxX1) > FXABS(fxY2 - fxY1))
						{
							fxAbsDelta = FXABS(fxX2 - fxX1);
						}
						else
						{
							fxAbsDelta = FXABS(fxY2 - fxY1);
						}
						lDivide = 0;
						while (fxAbsDelta > (MAXSPLINELENGTH / 2))
						{
							lDivide++;
							lDivide <<= 1;
							fxAbsDelta >>= 1;
						}
						lElementCount += lDivide;   /* for subdivision */
					}
					fxX1 = fxX2;
					fxY1 = fxY2;
					byF1 = byF2;
				}
			}
		}