1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: Selection.c /main/22 1996/11/12 11:44:48 cde-hp $ */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: Selection.c
- **
- ** Project: Cde DtHelp
- **
- ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
- **
- ** (c) Copyright 1993, 1994 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994 International Business Machines Corp.
- ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994 Novell, Inc.
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*
- * system includes
- */
- #include <stdlib.h>
- #include <string.h>
- /*
- * Canvas Engine includes
- */
- #include "CanvasP.h"
- #include "CanvasSegP.h"
- /*
- * private includes
- */
- #include "CanvasI.h"
- #include "CvStringI.h"
- #include "LayoutUtilI.h"
- #include "SelectionI.h"
- #include "VirtFuncsI.h"
- #ifdef NLS16
- #endif
- /******** Private Function Declarations ********/
- static void AdjustSelection (
- _DtCanvasStruct *canvas,
- _DtCvSelectData next);
- static int GetSelectedText(
- _DtCanvasStruct *canvas,
- _DtCvSelectData start,
- _DtCvSelectData end,
- unsigned int mask,
- _DtCvPointer *ret_data);
- /******** End Private Function Declarations ********/
- /******** Private Defines ********/
- #define GROW_SIZE 5
- /******** End Private Defines ********/
- /******** Macros ********/
- #define Equal(a,b) (a.y == b.y && a.x == b.x)
- #define LessThan(a,b) ((a.y < b.y) || (a.y == b.y && a.x < b.x))
- #define GreaterThan(a,b) ((a.y > b.y) || (a.y == b.y && a.x > b.x))
- #define LessThanEq(a,b) (Equal(a,b) || LessThan(a,b))
- #define GreaterThanEq(a,b) (Equal(a,b) || GreaterThan(a,b))
- #define InRegion(top,bot,min,max) ((min) <= (bot) && (top) <= (max))
- /******** End Macros ********/
- /******** Private Variable Declarations ********/
- static const _DtCvSelectData defaultSelect = { -1, -1, -1, -1};
- /******** End Private Variable Declarations ********/
- /******************************************************************************
- * Private Functions
- ******************************************************************************/
- /******************************************************************************
- * Function: StartXOfLine
- *
- * Purpose: Determine the start of a line, takes into consideration
- * the traversal and link before values. The 'x' returned is
- * exactly where the text/graphic is to be placed on the canvas.
- *****************************************************************************/
- static _DtCvUnit
- StartXOfLine(
- _DtCanvasStruct *canvas,
- _DtCvDspLine line)
- {
- _DtCvValue lastLinkVisible = FALSE;
- int lnkInd = -1;
- _DtCvUnit xPos;
- _DtCvSegmentI *pSeg;
- xPos = _DtCvGetStartXOfLine(&line, &pSeg);
- return (_DtCvAdvanceXOfLine( canvas, pSeg, xPos,
- &lnkInd, &lastLinkVisible));
- } /* End StartXOfLine */
- /*****************************************************************************
- * Function: SearchForClosestLine
- *
- * Purpose: Initializes the 'new' structure with information indicating
- * what line is closest to the target_y.
- * next->y Set to target_y if no line straddles it.
- * Otherwise, it will be set to the minimum
- * y of all lines straddling the target_y.
- * next->x Set to target_x if no line straddles
- * target_y or if target_x is before the
- * first line straddling target_y.
- * next->line_idx Set to -1 if no line straddles target_y.
- * Otherwise, set to the first line that
- * straddles target_x or is the minimum x
- * that is greater than target_x of all the
- * lines straddling target_x.
- * next->char_idx Set to -1 if no straddles target_y.
- * Otherwise, set to the character that
- * resides at target_x if target_x is in
- * the middle of the line. Set to zero if
- * target_x is before the line, and set to
- * the line count if target_x is after the
- * line.
- *
- *****************************************************************************/
- static void
- SearchForClosestLine (
- _DtCanvasStruct *canvas,
- _DtCvUnit target_x,
- _DtCvUnit target_y,
- _DtCvSelectData *next)
- {
- int i;
- int maxI = 0;
- _DtCvUnit lineY;
- _DtCvUnit endX;
- _DtCvUnit begX;
- _DtCvUnit maxX = -1;
- _DtCvDspLine *lines = canvas->txt_lst;
- *next = defaultSelect;
- for (i = 0; i < canvas->txt_cnt; i++)
- {
- /*
- * get the maximum y of the line
- * if it straddles the target y, process it.
- */
- lineY = lines[i].baseline + lines[i].descent;
- if (_DtCvStraddlesPt(target_y,lines[i].baseline-lines[i].ascent,lineY))
- {
- /*
- * Is this the minimum y of all the maximum y values of the
- * line straddling the target y?
- */
- if (next->y == -1 || next->y > lineY)
- next->y = lineY;
- /*
- * Get the maximum X position of the line.
- * If this is the maximum X of all the lines straddling
- * the target y, remember it.
- */
- endX = canvas->txt_lst[i].max_x;
- if (maxX < endX && endX < target_x)
- {
- maxX = endX;
- maxI = i;
- }
- /*
- * Does this line straddle the x?
- */
- begX = StartXOfLine(canvas, lines[i]);
- if (_DtCvStraddlesPt(target_x, begX, endX))
- {
- next->line_idx = i;
- next->char_idx = _DtCvGetCharIdx(canvas,lines[i],target_x);
- }
- }
- }
- /*
- * remember what the target x was for this line. If the target x is
- * less than the start of the line, then the selection process will
- * highlight the space before the line. If its in the middle, it
- * will just highlight starting at the character. If it's after the
- * end, the rest will be cut off at the end of the line.
- */
- next->x = target_x;
- /*
- * If we found a line straddling the target y, but it does not
- * straddle the target_x, check max x for the correct info.
- */
- if (next->line_idx == -1 && maxX > -1)
- {
- next->line_idx = maxI;
- next->char_idx = lines[maxI].length;
- }
- /*
- * didn't find a line straddling the target_y, set y.
- */
- if (next->y == -1)
- next->y = target_y;
- }
- /*****************************************************************************
- * 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]);
- }
- }
- }
- }
- /*****************************************************************************
- * Function: AdjustSelection
- *
- *****************************************************************************/
- static void
- AdjustSelection (
- _DtCanvasStruct *canvas,
- _DtCvSelectData next)
- {
- _DtCvSelectData start = canvas->select_start;
- _DtCvSelectData end = canvas->select_end;
- if (!(Equal(next, end)))
- {
- if (next.line_idx != -1 && next.line_idx == canvas->select_end.line_idx
- &&
- next.char_idx != -1 && next.char_idx == canvas->select_end.char_idx)
- return;
- if (GreaterThan(next, end))
- {
- if (LessThanEq(start, end))
- _DtCvDrawAreaWithFlags (canvas, end, next,
- 0, _DtCvSELECTED_FLAG,
- _DtCvBAD_TYPE, NULL);
- else if (GreaterThanEq(start, next))
- _DtCvDrawAreaWithFlags (canvas, end, next,
- _DtCvSELECTED_FLAG, 0,
- _DtCvBAD_TYPE, NULL);
- else /* end < start < next */
- {
- _DtCvDrawAreaWithFlags (canvas, end , start,
- _DtCvSELECTED_FLAG, 0,
- _DtCvBAD_TYPE, NULL);
- _DtCvDrawAreaWithFlags (canvas, start, next ,
- 0, _DtCvSELECTED_FLAG,
- _DtCvBAD_TYPE, NULL);
- }
- }
- else /* if (next < end) */
- {
- if (LessThanEq(start, next))
- _DtCvDrawAreaWithFlags (canvas, next, end,
- _DtCvSELECTED_FLAG, 0,
- _DtCvBAD_TYPE, NULL);
- else if (GreaterThanEq(start, end))
- _DtCvDrawAreaWithFlags (canvas, next, end,
- 0, _DtCvSELECTED_FLAG,
- _DtCvBAD_TYPE, NULL);
- else /* next < start < end */
- {
- _DtCvDrawAreaWithFlags (canvas, start, end ,
- _DtCvSELECTED_FLAG, 0,
- _DtCvBAD_TYPE, NULL);
- _DtCvDrawAreaWithFlags (canvas, next , start,
- 0, _DtCvSELECTED_FLAG,
- _DtCvBAD_TYPE, NULL);
- }
- }
- }
- canvas->select_end = next;
- }
- /*****************************************************************************
- * Function: SkipOtherLines
- *
- *****************************************************************************/
- static void
- SkipOtherLines(
- _DtCvDspLine *lines,
- int max_cnt,
- int idx,
- _DtCvUnit target_y,
- int *ret_idx)
- {
- while (idx < max_cnt && _DtCvIsNotProcessed(lines[idx]) &&
- lines[idx].baseline - lines[idx].ascent > target_y)
- idx++;
- *ret_idx = idx;
- }
- /*****************************************************************************
- * Function: CheckAndSwitchPoints
- *
- *****************************************************************************/
- static int
- CheckAndSwitchPoints(
- _DtCvSelectData *pt1,
- _DtCvSelectData *pt2)
- {
- _DtCvSelectData temp;
- if (pt1->y > pt2->y || (pt1->y == pt2->y && pt1->x > pt2->x))
- {
- temp = *pt2;
- *pt2 = *pt1;
- *pt1 = temp;
- }
- }
- /*****************************************************************************
- * Function: AddSegmentToData
- *
- *****************************************************************************/
- static _DtCvUnit
- AddSegmentToData(
- _DtCanvasStruct *canvas,
- unsigned int mask,
- _DtCvUnit start_x,
- int line_idx,
- int char_idx,
- int copy_cnt,
- _DtCvFlags end_flag,
- _DtCvUnit *ret_y,
- _DtCvPointer *ret_data)
- {
- _DtCvDspLine line = canvas->txt_lst[line_idx];
- int result = _DtCvSTATUS_OK;
- int count = line.length;
- int start = line.byte_index;
- int lnkInd = -1;
- int cnt;
- int len;
- _DtCvUnit segWidth;
- _DtCvUnit xPos = line.text_x;
- void *pChar;
- _DtCvSegmentI *pSeg = line.seg_ptr;
- _DtCvFlags flag = 0;
- _DtCvValue done = False;
- _DtCvValue lastLinkVisible = FALSE;
- _DtCvStringInfo strInfo;
- xPos = _DtCvGetStartXOfLine(&line, &pSeg);
- while (done == False && char_idx)
- {
- /*
- * advance past the link and traversal info
- */
- xPos = _DtCvAdvanceXOfLine(canvas, pSeg, xPos,
- &lnkInd, &lastLinkVisible);
- /*
- * advance the pointer by the width
- */
- _DtCvGetWidthOfSegment(canvas, pSeg, start, count,
- &cnt, &segWidth, NULL);
- if (cnt < char_idx)
- {
- xPos += segWidth;
- pSeg = pSeg->next_disp;
- count -= cnt;
- char_idx -= cnt;
- start = 0;
- }
- else
- {
- _DtCvGetWidthOfSegment(canvas, pSeg, start, char_idx,
- &cnt, &segWidth, NULL);
- xPos += segWidth;
- start += cnt;
- count -= cnt;
- done = True;
- }
- }
- if (start_x > xPos)
- start_x = xPos;
- while (_DtCvSTATUS_OK == result && pSeg != NULL && copy_cnt > 0)
- {
- /*
- * advance past the link and traversal info
- */
- xPos = _DtCvAdvanceXOfLine(canvas, pSeg, xPos,
- &lnkInd, &lastLinkVisible);
- switch (_DtCvPrimaryTypeOfSeg(pSeg))
- {
- case _DtCvSTRING:
- pChar = _DtCvStrPtr(_DtCvStringOfStringSeg(pSeg),
- _DtCvIsSegWideChar(pSeg), start);
- len = _DtCvStrLen (pChar, _DtCvIsSegWideChar(pSeg));
- if (len > copy_cnt)
- len = copy_cnt;
- segWidth = _DtCvGetStringWidth(canvas, pSeg, pChar, len);
- if (copy_cnt == len)
- flag = end_flag;
- strInfo.string = pChar;
- strInfo.byte_len = len;
- strInfo.wc = _DtCvIsSegWideChar(pSeg);
- strInfo.font_ptr = _DtCvFontOfStringSeg(pSeg);
- if (canvas->virt_functions.build_selection != NULL)
- result = (*(canvas->virt_functions.build_selection))(
- canvas->client_data,
- _DtCvSTRING_TYPE,
- mask,
- ret_data,
- xPos - start_x,
- segWidth,
- flag,
- (_DtCvPointer) &strInfo);
- if (_DtCvSTATUS_OK == result)
- {
- if (line.baseline + line.descent > *ret_y)
- *ret_y = line.baseline + line.descent;
- start_x = xPos + segWidth;
- }
- else if (_DtCvSTATUS_NONE == result)
- result = _DtCvSTATUS_OK;
- xPos += segWidth;
- copy_cnt -= len;
- start = 0;
- break;
- case _DtCvREGION:
- if (copy_cnt == 1)
- flag = end_flag;
- if (canvas->virt_functions.build_selection != NULL)
- result = (*(canvas->virt_functions.build_selection))(
- canvas->client_data,
- _DtCvREGION_TYPE,
- mask,
- ret_data,
- xPos - start_x,
- _DtCvWidthOfRegionSeg(pSeg),
- flag,
- _DtCvInfoOfRegionSeg(pSeg));
- if (_DtCvSTATUS_OK == result)
- {
- if (line.baseline + line.descent > *ret_y)
- *ret_y = line.baseline + line.descent;
- start_x = xPos + segWidth;
- }
- else if (_DtCvSTATUS_NONE == result)
- result = _DtCvSTATUS_OK;
- copy_cnt--;
- xPos += _DtCvWidthOfRegionSeg(pSeg);
- break;
- }
- pSeg = pSeg->next_disp;
- }
- if (result != _DtCvSTATUS_OK)
- return -1;
- return start_x;
- }
- /*****************************************************************************
- * 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;
- _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;
- }
- /*****************************************************************************
- * Function: FindMinX
- *
- *****************************************************************************/
- static int
- FindMinX (
- _DtCvDspLine *lines,
- int txt_cnt,
- _DtCvUnit target_y,
- int *ret_line)
- {
- int i;
- int cnt = 0;
- _DtCvUnit curMin = -1;
- _DtCvUnit curX;
- for (i = 0; i < txt_cnt; i++)
- {
- if (_DtCvIsNotProcessed(lines[i]))
- {
- if (lines[i].baseline - lines[i].ascent < target_y &&
- target_y <= lines[i].baseline + lines[i].descent)
- {
- cnt++;
- curX = lines[i].text_x;
- if (curMin == -1 || curMin > curX)
- {
- curMin = curX;
- *ret_line = i;
- }
- }
- }
- }
- return cnt;
- }
- /*****************************************************************************
- * Function: FindNextMinY
- *
- *****************************************************************************/
- static _DtCvValue
- FindNextMinY(
- _DtCvDspLine *lines,
- int max_cnt,
- _DtCvUnit target_y,
- _DtCvUnit *ret_y)
- {
- int i = 0;
- _DtCvUnit maxY;
- _DtCvValue found = False;
- while (i < max_cnt)
- {
- if (_DtCvIsNotProcessed(lines[i]))
- {
- maxY = lines[i].baseline + lines[i].descent;
- if (target_y == -1 || maxY < target_y)
- {
- found = True;
- target_y = maxY;
- }
- SkipOtherLines (lines, max_cnt, i+1, target_y, &i);
- }
- else
- i++;
- }
- *ret_y = target_y;
- return found;
- }
- /*****************************************************************************
- * 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 */
- /*****************************************************************************
- * 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;
- }
- /******************************************************************************
- * Semi-Public Functions
- ******************************************************************************/
- /*****************************************************************************
- * Function: _DtCvDrawAreaWithFlags
- *
- *****************************************************************************/
- void
- _DtCvDrawAreaWithFlags (
- _DtCanvasStruct *canvas,
- _DtCvSelectData start,
- _DtCvSelectData end,
- _DtCvFlags old_flags,
- _DtCvFlags new_flags,
- _DtCvElemType trav_type,
- _DtCvPointer trav_data)
- {
- int i;
- int len;
- int count;
- int startChar;
- int lnkInd;
- _DtCvUnit dstX;
- _DtCvUnit topY;
- _DtCvUnit botY;
- _DtCvUnit superWidth;
- _DtCvUnit subWidth;
- _DtCvUnit superY;
- _DtCvUnit subY;
- _DtCvUnit scriptX;
- _DtCvUnit segWidth;
- _DtCvSegmentI *pSeg;
- _DtCvValue lstLinkVis;
- _DtCvValue lstWasSuper;
- _DtCvValue lstWasSub;
- _DtCvValue trimmed;
- _DtCvFlags flagMask = old_flags | new_flags;
- _DtCvFlags endFlag = flagMask & _DtCvTRAVERSAL_END;
- _DtCvDspLine *lines = canvas->txt_lst;
- /*
- * now use the flagMask to determine what else to look for.
- * I.e. if flagMask has _DtCvMARK_FLAG set, then it becomes
- * set to _DtCvSELECTED_FLAG and visa versa.
- */
- flagMask ^= (_DtCvSELECTED_FLAG | _DtCvMARK_FLAG);
- /*
- * strip the end flag from the other flags
- */
- new_flags &= ~(_DtCvTRAVERSAL_END);
- old_flags &= ~(_DtCvTRAVERSAL_END);
- if (Equal(start, end))
- return;
- for (i = 0; i < canvas->txt_cnt; i++)
- {
- topY = lines[i].baseline - lines[i].ascent;
- botY = lines[i].baseline + lines[i].descent;
- if (InRegion(topY, botY, start.y, end.y))
- {
- /*
- * get the start of the text.
- */
- lstLinkVis = False;
- lstWasSuper = False;
- lstWasSub = False;
- lnkInd = -1;
- dstX = _DtCvGetStartXOfLine(&(lines[i]), &pSeg);
- startChar = lines[i].byte_index;
- count = lines[i].length;
- while (pSeg != NULL && _DtCvIsSegNoop(pSeg))
- {
- startChar = 0;
- pSeg = pSeg->next_disp;
- }
- /*
- * advance the starting point
- */
- dstX = _DtCvAdvanceXOfLine(canvas, pSeg, dstX,
- &lnkInd, &lstLinkVis);
- /*
- * take into account super/sub scripting
- */
- dstX = _DtCvAdjustForSuperSub(canvas, pSeg, dstX, &scriptX,
- &superWidth, &superY, &subWidth, &subY,
- &lstWasSuper, &lstWasSub);
- /*
- * set this flag so that the first pass of 'while (cnt > 0)'
- * doesn't do it again.
- */
- trimmed = True;
- if (_DtCvStraddlesPt(start.y, topY, botY))
- {
- /*
- * skip this item?
- * I.E. is this line before the start or after the end?
- */
- if (canvas->txt_lst[i].max_x < start.x ||
- (end.y == start.y && end.x <= dstX) )
- continue;
- /*
- * does this line start the mark/selection?
- */
- if (i == start.line_idx && start.x >= dstX)
- {
- int cnt = start.char_idx;
- while (cnt > 0)
- {
- if (trimmed == False)
- {
- /*
- * advance the starting point
- */
- dstX = _DtCvAdvanceXOfLine(canvas, pSeg, dstX,
- &lnkInd, &lstLinkVis);
- /*
- * take into account super/sub scripting
- */
- dstX = _DtCvAdjustForSuperSub(canvas,
- pSeg, dstX, &scriptX,
- &superWidth, &superY, &subWidth, &subY,
- &lstWasSuper, &lstWasSub);
- }
- /*
- * take into account the length of the segment
- */
- _DtCvGetWidthOfSegment(canvas, pSeg,
- startChar , cnt,
- &len, &segWidth, &trimmed);
- dstX += segWidth;
- startChar += len;
- if (trimmed == False)
- {
- startChar = 0;
- pSeg = pSeg->next_disp;
- }
- trimmed = False;
- cnt -= len;
- }
- count -= start.char_idx;
- }
- /*
- * otherwise this line is after the line that starts
- * the mark/selection. Stick with its start x.
- */
- }
- /*
- * does this straddle the end point?
- */
- if (_DtCvStraddlesPt(end.y, topY, botY))
- {
- /*
- * does this start after the end of the mark/selection?
- * if so, skip.
- */
- if (end.x <= dstX)
- continue;
- /*
- * Does this segment end after the end of the mark/selection?
- * If so, trim how much gets highlighted.
- */
- if (canvas->txt_lst[i].max_x > end.x)
- count -= (lines[i].length - end.char_idx);
- }
- /*
- * while there is something to draw (un)mark/selected.
- */
- old_flags = old_flags | _DtCvMARK_BEGIN;
- new_flags = new_flags | _DtCvMARK_BEGIN;
- while (count > 0)
- {
- /*
- * the original count to render
- */
- len = count;
- /*
- * check for other marks and selection.
- */
- _DtCvCheckLineMarks(canvas, i, startChar - lines[i].byte_index,
- count, dstX, flagMask,
- &len, &old_flags, &new_flags);
- /*
- * if this is the last segment(s) of the (un)mark/selection
- * set the end flags.
- */
- if (len == count)
- {
- new_flags |= (endFlag | _DtCvLINK_END | _DtCvMARK_END);
- old_flags |= (endFlag | _DtCvLINK_END | _DtCvMARK_END);
- }
- /*
- * draw the segments that are marked/unmarked.
- */
- dstX = _DtCvDrawSegments(canvas, lines[i],
- pSeg, startChar , len, &lnkInd,
- dstX, dstX, &scriptX,
- &superWidth, &superY, &subWidth, &subY,
- &lstWasSub, &lstWasSuper,
- &lstLinkVis, old_flags, new_flags,
- trav_type, trav_data);
- /*
- * modify the count by the length processed
- */
- count -= len;
- /*
- * did this do the entire length? If not, set the
- * indexes ahead and do again.
- */
- if (count > 0)
- _DtCvSkipLineChars(canvas, pSeg, startChar , count + len,
- len, &startChar , &pSeg);
- /*
- * strip the any begin flags.
- */
- _DtCvRemoveBeginFlags(old_flags);
- _DtCvRemoveBeginFlags(new_flags);
- }
- }
- }
- }
- /*****************************************************************************
- * Function: _DtCanvasGetSelectionPoints()
- *
- * Purpose: Retrieve the segments making up the selection.
- *
- *****************************************************************************/
- _DtCvStatus
- _DtCvGetMarkSegs (
- _DtCanvasStruct *canvas,
- _DtCvPointInfo ***ret_info)
- {
- int i;
- *ret_info = NULL;
- for (i = 0; i < canvas->mark_cnt; i++)
- {
- _DtCvPointInfo *nxtInfo;
- /*
- * allocate mark information structure
- */
- nxtInfo = (_DtCvPointInfo *) malloc (sizeof(_DtCvPointInfo));
- if (NULL == nxtInfo)
- return _DtCvSTATUS_BAD;
- nxtInfo->client_data = canvas->marks[i].client_data;
- if (_DtCvSTATUS_BAD == GetSegsInArea(canvas, &(canvas->marks[i].beg),
- &(canvas->marks[i].end),
- &(nxtInfo->segs),
- NULL, NULL))
- return _DtCvSTATUS_BAD;
- *ret_info = (_DtCvPointInfo **) _DtCvAddPtrToArray((void **) *ret_info,
- (void *) nxtInfo);
- if (NULL == *ret_info)
- return _DtCvSTATUS_BAD;
- }
- return _DtCvSTATUS_OK;
- }
- /******************************************************************************
- * Public Functions
- ******************************************************************************/
- /*****************************************************************************
- * Function: _DtCanvasGetSelection()
- *
- * Purpose: Indicate the end point for a selection.
- *
- *****************************************************************************/
- _DtCvStatus
- _DtCanvasGetSelection (
- _DtCvHandle canvas_handle,
- unsigned int mask,
- _DtCvPointer *ret_select)
- {
- _DtCanvasStruct *canvas = (_DtCanvasStruct *) canvas_handle;
- *ret_select = NULL;
- return(GetSelectedText(canvas, canvas->select_start, canvas->select_end,
- mask, ret_select));
- }
- /*****************************************************************************
- * Function: _DtCanvasProcessSelection()
- *
- * Purpose: Indicate an new point for a selection.
- *
- *****************************************************************************/
- void
- _DtCanvasProcessSelection (
- _DtCvHandle canvas_handle,
- _DtCvUnit x,
- _DtCvUnit y,
- _DtCvSelectMode mode)
- {
- _DtCanvasStruct *canvas = (_DtCanvasStruct *) canvas_handle;
- _DtCvSelectData temp;
- switch (mode)
- {
- case _DtCvSELECTION_CLEAR:
- CheckAndSwitchPoints(&(canvas->select_start),
- &(canvas->select_end));
- case _DtCvSELECTION_START:
- _DtCvDrawAreaWithFlags(canvas, canvas->select_start,
- canvas->select_end,
- _DtCvSELECTED_FLAG, 0,
- _DtCvBAD_TYPE, NULL);
- canvas->select_start = defaultSelect;
- if (mode == _DtCvSELECTION_START)
- SearchForClosestLine(canvas, x, y, &(canvas->select_start));
- canvas->select_end = canvas->select_start;
- break;
- case _DtCvSELECTION_END:
- case _DtCvSELECTION_UPDATE:
- SearchForClosestLine(canvas, x, y, &temp);
- AdjustSelection (canvas, temp);
- if (mode == _DtCvSELECTION_END)
- CheckAndSwitchPoints(&(canvas->select_start),
- &(canvas->select_end));
- break;
- }
- }
- /*****************************************************************************
- * Function: _DtCanvasGetSelectionPoints()
- *
- * Purpose: Retrieve the segments making up the selection.
- *
- *****************************************************************************/
- _DtCvStatus
- _DtCanvasGetSelectionPoints (
- _DtCvHandle canvas_handle,
- _DtCvSegPts ***ret_segs,
- _DtCvUnit *ret_y1,
- _DtCvUnit *ret_y2)
- {
- _DtCanvasStruct *canvas = (_DtCanvasStruct *) canvas_handle;
- return (GetSegsInArea(canvas, &(canvas->select_start),
- &(canvas->select_end), ret_segs, ret_y1, ret_y2));
- }
- /*****************************************************************************
- * Function: _DtCanvasActivatePts()
- *
- * Purpose: Activate the points given.
- *
- *****************************************************************************/
- _DtCvStatus
- _DtCanvasActivatePts (
- _DtCvHandle canvas_handle,
- unsigned int mask,
- _DtCvPointInfo *info,
- _DtCvUnit *ret_y1,
- _DtCvUnit *ret_y2)
- {
- int markIdx;
- _DtCanvasStruct *canvas = (_DtCanvasStruct *) canvas_handle;
- _DtCvSelectData startSel = defaultSelect;
- _DtCvSelectData endSel = defaultSelect;
- _DtCvFlags flag;
- _DtCvSegmentI *firstSeg;
- #define REQUIRE_SEGS \
- (_DtCvACTIVATE_MARK | _DtCvACTIVATE_SELECTION)
- /*
- * check to see if there is anything to do
- */
- if (0 == mask)
- return _DtCvSTATUS_NONE;
- if ((mask & _DtCvACTIVATE_MARK) && (mask & _DtCvDEACTIVATE))
- return _DtCvSTATUS_BAD;
- /*
- * Convert the segments into starting and ending positions.
- */
- if (((mask & _DtCvDEACTIVATE) && NULL == info->client_data)
- || (mask & REQUIRE_SEGS))
- {
- if (NULL == info || NULL == info->segs ||
- _DtCvSTATUS_BAD == _DtCvCvtSegsToPts(canvas, info->segs,
- &startSel, &endSel,
- ret_y1, ret_y2, &firstSeg))
- return _DtCvSTATUS_BAD;
- }
- /*
- * Activate as a selection
- */
- if (mask & _DtCvACTIVATE_SELECTION)
- {
- _DtCanvasProcessSelection (canvas_handle, 0, 0, _DtCvSELECTION_CLEAR);
- canvas->select_start = startSel;
- canvas->select_end = endSel;
- _DtCvDrawAreaWithFlags (canvas, startSel, endSel,
- 0, _DtCvSELECTED_FLAG,
- _DtCvBAD_TYPE, NULL);
- }
- /*
- * Activate as a mark
- */
- if (mask & _DtCvACTIVATE_MARK)
- {
- int travIdx;
- _DtCvUnit x;
- _DtCvUnit y;
- _DtCvUnit width;
- _DtCvUnit height;
- markIdx = _DtCvAddToMarkList(canvas, info->client_data,
- _DtCvIsMarkMaskOn(mask), &startSel, &endSel);
- if (-1 == markIdx)
- return _DtCvSTATUS_BAD;
- /*
- * now put the mark in the traversal list and merge it into the
- * proper place.
- */
- travIdx = _DtCvGetNextTravEntry(canvas);
- if (-1 == travIdx
- || 0 != _DtCvSetTravEntryInfo(canvas, travIdx,
- _DtCvTraversalMark, firstSeg,
- markIdx, _DtCvTRUE)
- || 0 != _DtCvCalcMarkPos(canvas, markIdx,
- &x, &y, &width, &height)
- || 0 != _DtCvSetTravEntryPos(canvas, travIdx,
- x, y, width, height))
- return _DtCvSTATUS_BAD;
- _DtCvSortTraversalList(canvas, _DtCvTRUE);
- /*
- * draw these segments marked.
- */
- flag = _DtCvMARK_FLAG;
- if (_DtCvTRUE == canvas->marks[markIdx].on)
- flag |= _DtCvMARK_ON;
- _DtCvDrawAreaWithFlags (canvas, startSel, endSel,
- 0, flag,
- _DtCvBAD_TYPE, NULL);
- }
- /*
- * Clear the mark flag.
- */
- else if (mask & _DtCvDEACTIVATE)
- {
- int travIdx;
- /*
- * is there anything to deacivate?
- */
- if (NULL == canvas->marks || 0 == canvas->mark_cnt)
- return _DtCvSTATUS_BAD;
- /*
- * was client data specified? If so, then look for it and ignore
- * the segment data.
- */
- markIdx = 0;
- if (NULL != info->client_data)
- {
- while (markIdx < canvas->mark_cnt &&
- canvas->marks[markIdx].client_data != info->client_data)
- markIdx++;
- /*
- * initialize the selection points
- */
- if (markIdx < canvas->mark_cnt)
- {
- startSel = canvas->marks[markIdx].beg;
- endSel = canvas->marks[markIdx].end;
- }
- }
- /*
- * look for the marked set using the segments.
- */
- else
- {
- while (markIdx < canvas->mark_cnt
- && startSel.line_idx != canvas->marks[markIdx].beg.line_idx
- && startSel.char_idx != canvas->marks[markIdx].beg.char_idx
- && endSel.line_idx != canvas->marks[markIdx].end.line_idx
- && endSel.line_idx != canvas->marks[markIdx].end.char_idx)
- markIdx++;
- }
- if (markIdx >= canvas->mark_cnt)
- return _DtCvSTATUS_BAD;
- /*
- * draw these segments unmarked.
- */
- flag = _DtCvMARK_FLAG;
- if (_DtCvTRUE == canvas->marks[markIdx].on)
- flag |= _DtCvMARK_ON;
- canvas->marks[markIdx].on = _DtCvFALSE;
- _DtCvDrawAreaWithFlags (canvas, startSel, endSel, flag, 0,
- _DtCvBAD_TYPE, NULL);
- /*
- * remove the mark from the traversal list
- *
- * first find the traversal entry of the mark and adjust any
- * traversal mark index values to reflect that the mark
- * list is about to shrink by 1.
- */
- for (travIdx = 0; _DtCvTraversalMark != canvas->trav_lst[travIdx].type
- || markIdx != canvas->trav_lst[travIdx].idx; travIdx++)
- {
- /*
- * is this mark after the one being removed?
- * if so, decrease its index because it's about to move.
- */
- if (_DtCvTraversalMark == canvas->trav_lst[travIdx].type &&
- markIdx < canvas->trav_lst[travIdx].idx)
- canvas->trav_lst[travIdx].idx--;
- }
- /*
- * move the list of traversal entries to eliminate the mark entry.
- */
- while (travIdx + 1 < canvas->trav_cnt)
- {
- canvas->trav_lst[travIdx] = canvas->trav_lst[travIdx + 1];
- /*
- * is this a mark after the one being removed?
- * if so, decrease it's index because it's about to move.
- */
- if (_DtCvTraversalMark == canvas->trav_lst[travIdx].type &&
- markIdx < canvas->trav_lst[travIdx].idx)
- canvas->trav_lst[travIdx].idx--;
- travIdx++;
- }
- /*
- * update the traversal count and back up to the previous traversal
- * if the mark was at the end of the traversal list.
- */
- canvas->trav_cnt--;
- if (canvas->cur_trav >= canvas->trav_cnt)
- canvas->cur_trav--;
- /*
- * move the list of marks up
- */
- while (markIdx + 1 < canvas->mark_cnt)
- {
- canvas->marks[markIdx] = canvas->marks[markIdx + 1];
- markIdx++;
- }
- canvas->mark_cnt--;
- }
- else if ((_DtCvACTIVATE_MARK_ON | _DtCvACTIVATE_MARK_OFF) & mask)
- {
- markIdx = 0;
- if (NULL != info && NULL != info->client_data)
- {
- while (markIdx < canvas->mark_cnt &&
- canvas->marks[markIdx].client_data != info->client_data)
- markIdx++;
- /*
- * was a mark with this client data found?
- */
- if (markIdx >= canvas->mark_cnt)
- return _DtCvSTATUS_BAD;
- }
- else
- {
- /*
- * are there any traversals? Is the current one sitting on a mark?
- */
- if (0 == canvas->trav_cnt || -1 == canvas->cur_trav ||
- _DtCvTraversalMark != canvas->trav_lst[canvas->cur_trav].type)
- return _DtCvSTATUS_BAD;
- /*
- * get the mark index
- */
- markIdx = canvas->trav_lst[canvas->cur_trav].idx;
- }
- /*
- * is this different than what it is set at now? If not, do nothing.
- */
- if (_DtCvIsMarkMaskOn(mask) == canvas->marks[markIdx].on)
- return _DtCvSTATUS_NONE;
- /*
- * set to mask value.
- */
- canvas->marks[markIdx].on = _DtCvIsMarkMaskOn(mask);
- /*
- * set the flags correctly.
- */
- flag = _DtCvMARK_FLAG;
- if (_DtCvTRUE == canvas->marks[markIdx].on)
- flag |= _DtCvMARK_ON;
- if (_DtCvTRUE == canvas->trav_on &&
- markIdx == canvas->trav_lst[canvas->cur_trav].idx)
- flag |= _DtCvTRAVERSAL_FLAG;
- /*
- * draw the mark opposite what it was
- */
- _DtCvDrawAreaWithFlags (canvas, canvas->marks[markIdx].beg,
- canvas->marks[markIdx].end,
- (flag ^ _DtCvMARK_ON), flag,
- _DtCvBAD_TYPE, NULL);
- }
- return _DtCvSTATUS_OK;
- }
- /*****************************************************************************
- * Function: _DtCanvasGetMarkPositions()
- *
- * Purpose: Return the position in the canvas of the marks.
- *
- *****************************************************************************/
- _DtCvStatus
- _DtCanvasGetMarkPositions (
- _DtCvHandle canvas_handle,
- _DtCvMarkPos ***ret_pos)
- {
- int i;
- _DtCanvasStruct *canvas = (_DtCanvasStruct *) canvas_handle;
- _DtCvMarkPos *nextPos;
- _DtCvMarkData *markLst = canvas->marks;
- *ret_pos = NULL;
- if (0 == canvas->mark_cnt)
- return _DtCvSTATUS_NONE;
- for (i = 0; i < canvas->mark_cnt; i++, markLst++)
- {
- /*
- * malloc memory for the information
- */
- nextPos = (_DtCvMarkPos *) malloc (sizeof(_DtCvMarkPos));
- if (NULL == nextPos)
- return _DtCvSTATUS_BAD;
- /*
- * client data and baselines
- */
- nextPos->client_data = markLst->client_data;
- nextPos->baseline1 = canvas->txt_lst[markLst->beg.line_idx].baseline;
- nextPos->baseline2 = canvas->txt_lst[markLst->end.line_idx].baseline;
- /*
- * top left corner
- */
- nextPos->x1 = markLst->beg.x;
- nextPos->y1 = nextPos->baseline1 -
- canvas->txt_lst[markLst->beg.line_idx].ascent;
- /*
- * bottom right corner
- */
- nextPos->x2 = markLst->end.x;
- nextPos->y2 = nextPos->baseline2 +
- canvas->txt_lst[markLst->end.line_idx].descent;
- *ret_pos = (_DtCvMarkPos **) _DtCvAddPtrToArray((void **) *ret_pos,
- (void *) nextPos);
- if (NULL == *ret_pos)
- return _DtCvSTATUS_BAD;
- }
- return _DtCvSTATUS_OK;
- }
|