Beispiel #1
0
/*****************************************************************************
 * Function: MarkLinesOutsideBoundary
 *
 *****************************************************************************/
static	void
MarkLinesOutsideBoundary (
    _DtCanvasStruct	*canvas,
    _DtCvUnit		 top_y,
    _DtCvUnit		 top_x,
    _DtCvUnit		 bot_y,
    _DtCvUnit		 bot_x)
{
    int       i;
    _DtCvUnit      maxY;
    _DtCvUnit      minY;
    _DtCvDspLine  *lines = canvas->txt_lst;

    for (i = 0; i < canvas->txt_cnt; i++)
      {
        maxY = lines[i].baseline + lines[i].descent;
	minY = lines[i].baseline - lines[i].ascent;

	/*
	 * is this line outside the boundary?
	 * If so, mark it so it's not processed.
	 */
        if (maxY < top_y || minY > bot_y )
	    _DtCvSetProcessed(lines[i]);

	else
	  {
	    /*
	     * does it straddle the top?
	     */
	    if (_DtCvStraddlesPt(top_y, minY, maxY))
	      {
	        /*
	         * Does it begin before the selection?
	         * If so, mark it so it's not processed.
	         */
	        if (canvas->txt_lst[i].max_x <= top_x)
		    _DtCvSetProcessed(lines[i]);
	      }
	
	    /*
	     * does it straddle the bottom?
	     */
	    if (_DtCvStraddlesPt(bot_y, minY, maxY))
	      {
	        /*
	         * Does it start after the selection?
	         * If so, mark it so it's not processed.
	         */
	        if (StartXOfLine(canvas, lines[i]) >= bot_x)
		    _DtCvSetProcessed(lines[i]);
	      }
          }
      }
}
Beispiel #2
0
/*****************************************************************************
 * Function: BuildLine
 *
 *****************************************************************************/
static int
BuildLine(
    _DtCanvasStruct	*canvas,
    unsigned int	 mask,
    _DtCvUnit		 prev_y,
    _DtCvUnit		 target_x,
    int			 line_idx,
    int			 char_idx,
    int			 copy_cnt,
    _DtCvFlags		 end_flag,
    _DtCvUnit		*ret_x,
    _DtCvUnit		*ret_y,
    _DtCvPointer	*ret_data)
{
    _DtCvUnit		 topY;
    _DtCvUnit		 lastY;
    _DtCvDspLine	*lines = canvas->txt_lst;
    _DtCvStringInfo	 strInfo = { NULL, 0, 1, NULL };

    topY = lines[line_idx].baseline - lines[line_idx].ascent;
    if (topY > prev_y && canvas->virt_functions.build_selection != NULL)
      {
	int   newLines;
	_DtCvUnit  lineSize = canvas->metrics.line_height / 2;
	if (lineSize < 1)
	    lineSize = 1;

	newLines = (topY - prev_y) / lineSize;
	while (newLines > 0)
	  {
	    newLines--;
	    if ((*(canvas->virt_functions.build_selection))(
				canvas->client_data, _DtCvSTRING_TYPE,
				mask, ret_data, 0, 0, _DtCvEND_OF_LINE,
				(_DtCvPointer) &strInfo) != _DtCvSTATUS_OK)
		return -1;
	  }
      }

    *ret_y = 0;
    *ret_x = AddSegmentToData (canvas, mask, target_x, line_idx, char_idx,
					copy_cnt, end_flag, ret_y, ret_data);
    _DtCvSetProcessed(lines[line_idx]);

    if (*ret_x == -1)
	return -1;
    return 0;
}
Beispiel #3
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;
}