/***************************************************************************** * 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: int AsciiKeyword ( * * Parameters: * p_list The segment list to process for strings. * parent_str The string to append information onto. * This may be NULL. * str_size The malloc'ed size of the parent string. * Includes room for the null byte. If zero * and parent_str is non-null, then memory * must be malloc'ed and parent_str copied * into it. Otherwise, goodStr can just * reuse parent_str. * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static char * AsciiKeyword ( _DtCvSegment *p_list, char *parent_str, int *str_size) { int len = 0; int newLen; char *goodStr; /* * if a starting string has been passed in, use it. */ if (NULL != parent_str) { /* * get the actual byte count. */ len = strlen(parent_str) + 1; /* * is the starting value zero? If so, we have to copy it. */ if (0 == *str_size) { parent_str = strdup(parent_str); if (NULL == parent_str) return NULL; *str_size = len; } } /* * start with the parent_string */ goodStr = parent_str; while (p_list != NULL) { if (_DtCvIsSegString(p_list)) { /* * get the number of characters in the next string. */ newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list), _DtCvIsSegWideChar(p_list)); /* * if this is wide char string, multiply the count by * MB_CUR_MAX to get the maximum number of bytes this * string would take. */ if (_DtCvIsSegWideChar(p_list)) newLen = newLen * MB_CUR_MAX; /* * now add it to our previous size. */ len += newLen; /* * are we starting from scratch? */ if (goodStr == NULL) { /* * include a byte for the end-of-string character. */ len++; /* * malloc the memory */ goodStr = (char *) malloc (len); } else if (*str_size < len) /* does this have to grow? */ goodStr = (char *) realloc (goodStr, len); if (goodStr == NULL) return NULL; /* * remember the absolute size of the memory for the string */ if (*str_size < len) *str_size = len; if (_DtCvIsSegWideChar(p_list)) { /* * back up to the insertion point. */ len -= newLen; /* * transfer */ newLen = wcstombs(&goodStr[len - 1], (wchar_t *) _DtCvStringOfStringSeg(p_list), newLen + 1); if ((size_t) -1 == newLen) return NULL; len += newLen; } else strcpy(&goodStr[len - newLen - 1], (char *) _DtCvStringOfStringSeg(p_list)); } /* * the only containers in an <entry> that should have a non-null * internal pointer should be a sub <entry>. Therefore, if null, * process since it could be a <key>, <sphrase>, etc. */ else if (_DtCvIsSegContainer(p_list) && NULL == _SdlSegEntryInfo(p_list)) { goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr, str_size); if (goodStr == NULL) return NULL; len = strlen(goodStr) + 1; } p_list = p_list->next_seg; } return goodStr; }