Ejemplo n.º 1
0
/*****************************************************************************
 * Function: GetSelectedText
 *
 *****************************************************************************/
static int
GetSelectedText(
    _DtCanvasStruct	*canvas,
    _DtCvSelectData next,
    _DtCvSelectData end,
    unsigned int         mask,
    _DtCvPointer	*ret_data)
{
    _DtCvUnit   maxY;
    _DtCvUnit   botY;
    int    i;
    int    lineCnt  = 0;
    int    junk;
    int    result   = 0;
    int    cpyCnt   = 0;
    int    txtCnt   = canvas->txt_cnt;
    _DtCvFlags endFlag;
    _DtCvValue  processing = True;
    _DtCvDspLine   *lines = canvas->txt_lst;

    for (i = 0; i < txtCnt; i++)
	_DtCvClearProcessed(lines[i]);

    MarkLinesOutsideBoundary(canvas, next.y, next.x, end.y, end.x);

    maxY = next.y;
    if (next.line_idx == -1)
      {
	/*
	 * find the first selected line
	 */
	if (FindNextMinY(lines, txtCnt, -1, &next.y) == False)
	    return 0;

	next.x  = 0;
	lineCnt = FindMinX(lines, txtCnt, next.y, &next.line_idx);
	next.char_idx = 0;
      }
    else
	lineCnt = FindMinX(lines, txtCnt, next.y, &junk);

    while (processing == True && result == 0)
      {
	/*
	 * process the next line of text.
	 */
	do
	  {
	    endFlag = 0;
	    cpyCnt  = lines[next.line_idx].length - next.char_idx;
	    if (next.line_idx == end.line_idx)
		cpyCnt = cpyCnt - lines[next.line_idx].length + end.char_idx;
	    else if (lineCnt == 1)
		endFlag = _DtCvEND_OF_LINE;

	    result  = BuildLine(canvas, mask, maxY, next.x,
					next.line_idx, next.char_idx,
					cpyCnt, endFlag,
					&next.x, &botY, ret_data);

	    if (botY > maxY)
		maxY = botY;

	    next.char_idx = 0;
	    lineCnt       = FindMinX(lines, txtCnt, next.y, &next.line_idx);

	  } while (result == 0 && lineCnt > 0);

	if (result == 0)
	  {
	    next.x = 0;
	    processing = FindNextMinY(lines, txtCnt, -1, &next.y);
	    if (processing == True)
		lineCnt = FindMinX(lines, txtCnt, next.y, &next.line_idx);
	  }
      }

    return result;

} /* End GetSelectedText */
Ejemplo n.º 2
0
/*****************************************************************************
 * Function:	GetSegsInArea()
 *
 * Purpose:	Retrieve the segments making up the selection.
 *
 *****************************************************************************/
static _DtCvStatus
GetSegsInArea (
    _DtCanvasStruct	*canvas,
    _DtCvSelectData	  *beg,
    _DtCvSelectData	  *end,
    _DtCvSegPts		***ret_segs,
    _DtCvUnit		  *ret_y1,
    _DtCvUnit		  *ret_y2)
{
    int			 cnt;
    int			 count;
    int			 start;
    int			 length;
    int			 lineCnt;
    int			 result = 0;
    _DtCvValue		 processing = True;
    _DtCvUnit		 minY;
    _DtCvUnit		 maxY;
    _DtCvUnit		 botY;
    _DtCvSelectData	 next;
    _DtCvSegPts		*newPt;
    _DtCvSegmentI	*pSeg;
    _DtCvDspLine	*lines = canvas->txt_lst;

    *ret_segs = NULL;

    if (beg->x == -1)
	return _DtCvSTATUS_NONE;

    /*
     * make sure the selection points are in the correct order.
     */
    CheckAndSwitchPoints(beg, end);

    /*
     * clear the processed bit
     */
    for (cnt = 0; cnt < canvas->txt_cnt; cnt++)
	_DtCvClearProcessed(lines[cnt]);

    /*
     * initialize the working structure
     * mark all the lines outside the selection regiion as invalid
     */
    next = *beg;
    MarkLinesOutsideBoundary(canvas, next.y, next.x, end->y, end->x);

    /*
     * start the minimum and maximum Y at this location.
     */
    minY = next.y;
    maxY = end->y;

    /*
     * is there a line at this location?
     */
    if (next.line_idx == -1)
      {
	/*
	 * find the first selected line within the region.
	 */
	if (FindNextMinY(lines, canvas->txt_cnt, -1, &next.y) == False)
	    processing = False;		/* empty of any text */
	else
	  {
	    /*
	     * now find the first line that is on this 'line' and
	     * the number of lines.
	     */
	    next.x  = 0;
	    lineCnt = FindMinX(lines, canvas->txt_cnt, next.y, &next.line_idx);
	    next.char_idx = 0;
          }
      }
    else /* find the number of lines on this 'line' */
	lineCnt = FindMinX(lines, canvas->txt_cnt, next.y, &cnt);

    /*
     * loop will there are segments to process
     */
    while (processing == True && result == 0)
      {
	/*
	 * process the next line of text.
	 */
	while (result == 0 && lineCnt > 0)
	  {
	    /*
	     * for each segment in this line (that is selected)
	     * create a segment point for it.
	     */
	    length = lines[next.line_idx].length;
	    start  = lines[next.line_idx].byte_index;

	    /*
	     * if this is the last line, shorten the length
	     * by the ending index.
	     */
	    if (next.line_idx == end->line_idx)
		length = end->char_idx;

	    /*
	     * move through the line's segments until we
	     * hit the segment starting the selection
	     */
	    pSeg = lines[next.line_idx].seg_ptr;
	    count = next.char_idx;
	    while (NULL != pSeg && 0 < count)
	      {
		/*
		 * get the byte count of this segment
		 */
		_DtCvGetWidthOfSegment(canvas, pSeg, start, length,
					&cnt, NULL, NULL);

		/*
		 * is the byte count of this segment larger than
		 * the starting index of the selection? If not,
		 * the selection is after this segment.
		 */
		if (count >= cnt)
		  {
		    start          = 0;
		    length        -= cnt;
		    pSeg           = pSeg->next_disp;
		  }
		else
		  {
		    length        -= count;
		    start          = start + count;
		  }
		count -= cnt;
	      }

	    while (0 == result && NULL != pSeg && 0 < length)
	      {
	        /*
		 * start with error condition. If the malloc works
	         * the error result gets reset to valid.
		 */
	        result = -1;
	        newPt = (_DtCvSegPts *) malloc (sizeof(_DtCvSegPts));
	        if (NULL != newPt)
		  {
		    /*
		     * indicate everything is okay.
		     */
		    result = 0;

		    /*
		     * get the width of this segment
		     */
		    _DtCvGetWidthOfSegment(canvas, pSeg, start, length,
							&cnt, NULL, NULL);

		    /*
		     * now set the segment point information and add it to the
		     * array of segment points.
		     */
	            newPt->offset  = start;
	            newPt->len     = cnt;
		    newPt->segment = pSeg;

		    *ret_segs = (_DtCvSegPts **) _DtCvAddPtrToArray(
							(void **) *ret_segs,
							(void  *)  newPt);
		    if (NULL == *ret_segs)
		        result = -1;

		    pSeg    = pSeg->next_disp;
		    length -= cnt;
		    start   = 0;
		  }
	      }

	    /*
	     * does this line extend below the selection y?
	     * if so, report it as the maximum y.
	     */
	    botY = lines[next.line_idx].baseline + lines[next.line_idx].descent;
	    if (botY > maxY)
		maxY = botY;

	    /*
	     * indicate this line has been processed.
	     */
	    _DtCvSetProcessed(lines[next.line_idx]);

	    /*
	     * get the next line
	     */
	    next.char_idx = 0;
	    lineCnt       = FindMinX(lines, canvas->txt_cnt, next.y,
							&next.line_idx);
	  }

	if (result == 0)
	  {
	    next.x = 0;
	    processing = FindNextMinY(lines,canvas->txt_cnt, -1, &next.y);
	    if (processing == True)
		lineCnt = FindMinX(lines,canvas->txt_cnt,next.y,&next.line_idx);
	  }
      }

    /*
     * if no errors, add a null to the array
     */
    if (0 != result)
      {
        *ret_segs = (_DtCvSegPts **) _DtCvAddPtrToArray((void **) *ret_segs,
							(void  *) NULL);
	if (NULL == *ret_segs)
	    result = -1; 
      }

    /*
     * if errors, free the segment points and return a bad status.
     */
    if (0 != result)
      {
	if (NULL != *ret_segs)
	  {
	    for (lineCnt = 0; NULL != (*ret_segs)[lineCnt]; lineCnt++)
		free((*ret_segs)[lineCnt]);
	    free(*ret_segs);
	  }
	return _DtCvSTATUS_BAD;
      }

    if (NULL != ret_y1)
	*ret_y1 = minY;
    
    if (NULL != ret_y2)
	*ret_y2 = minY;

    return _DtCvSTATUS_OK;
}
Ejemplo n.º 3
0
BOOL CConvexHullGenerator::Generate(void)
{
	int							iMaxXIndex;
	int							iMinXIndex;
	CHalfSpaceHelper			cHalfSpace;
	int							iFarIndex;
	SFloat3*					psPosition;
	CArrayExtremeTrianglePtr	apcTriangles;
	CExtremeTriangle*			pcTriangle;
	CExtremeTriangle*			pcDeleted;
	SFreeListIterator			sIter;
	CArrayExtremeTrianglePtr	cDeleted;
	CArrayExtremeTrianglePtr	cFixedDeleted;
	int							j;
	SConvexHullHoleEdge			sEdges;
	int							k;
	int							aiIndex[3];
	int							iIndex;
	CExtremeTriangle*			pcSelected;
	CTextFile					cTextFile;
	int							iTriangle;
	float						fMinX;
	float						fMaxX;

	iMaxXIndex = FindMaxX(&fMinX);
	iMinXIndex = FindMinX(&fMaxX);
	iFarIndex = FindFurthestPoint(iMaxXIndex, iMinXIndex);

	if (iFarIndex == -1)
	{
		gcUserError.Set("Could not find a third point generating Convex Hull.");
		return FALSE;
	}

	apcTriangles.Init(2048);

	if (!FindFirstPairTriangles(&apcTriangles, iMaxXIndex, iMinXIndex, iFarIndex))
	{
		gcUserError.Set("Could not find the first triangle pair generating Convex Hull.");
		return FALSE;
	}

	cDeleted.Init(512);
	cFixedDeleted.Init(512);

	for (iTriangle = 0; iTriangle < apcTriangles.NumElements(); iTriangle++)
	{
		pcSelected = *apcTriangles.Get(iTriangle);

		if ((pcSelected == NULL) || (pcSelected->maiVisible.NumElements() == 0))
		{
			continue;
		}

		aiIndex[0] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition);
		aiIndex[1] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition1);
		aiIndex[2] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition2);

		iFarIndex = pcSelected->FindFurthestPoint(mpsPoints, iStride);
		if (iFarIndex == -1)
		{
			gcUserError.Set("Could not find furthest point!");
			return FALSE;
		}

		cDeleted.FakeSetUsedElements(0);  //It's sort of safe to do this.

		psPosition = GetPosition(mpsPoints, iStride, iFarIndex);
		pcTriangle = (CExtremeTriangle*)mcTriangles.StartIteration(&sIter);
		while (pcTriangle)
		{
			if (pcTriangle->maiVisible.NumElements() > 0)
			{
				if (pcTriangle->NotContains(psPosition))
				{
					cDeleted.Add(&pcTriangle);
				}
			}
			pcTriangle = (CExtremeTriangle*)mcTriangles.Iterate(&sIter);
		}
		
		RemoveDiscontiguousTriangles(pcSelected, &cDeleted, &cFixedDeleted);

		for (j = 0; j < cDeleted.NumElements(); j++)
		{
			pcDeleted = *cDeleted.Get(j);
			FindEdges(&sEdges, pcDeleted, &cDeleted);

			for (k = 0; k < sEdges.iNumEdges; k++)
			{
				pcTriangle = AddTriangle(GetPosition(mpsPoints, iStride, sEdges.aaiEdgeIndices[k][0]),
					GetPosition(mpsPoints, iStride, sEdges.aaiEdgeIndices[k][1]),
					GetPosition(mpsPoints, iStride, iFarIndex));

				apcTriangles.Add(&pcTriangle);
				AddPointsFromTriangles(pcTriangle, &cDeleted, iFarIndex);
			}
		}

		for (j = 0; j < cDeleted.NumElements(); j++)
		{
			pcDeleted = *cDeleted.Get(j);
			pcDeleted->Kill();
			mcTriangles.Remove(pcDeleted);

			iIndex = apcTriangles.FindWithIntKey((int)(size_t)pcDeleted, 0);
			*(apcTriangles.Get(iIndex)) = NULL;
		}
	}
	cDeleted.Kill();
	cFixedDeleted.Kill();

	apcTriangles.Kill();

	RemoveSlivers();

	if (mszHullName)
	{
		CChars szTemp;
		szTemp.Init("Writing Hull file [");
		szTemp.Append(mszHullName);
		szTemp.Append("]\n");
		szTemp.Kill();
		cTextFile.Init();
		DumpTriangleObj(&cTextFile.mcText, iTriangle);
		cTextFile.Write(mszHullName);
		cTextFile.Kill();
	}

	return TRUE;
}