⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 richtexthandling.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/** eus_ReplaceRtfSpanText( ***
Purpose is to replace an identified span of rich text with the contents of the 
provided, null-terminated text buffer.

--- parameters & return ------
pt_spn: Input & Output. Pointer to a rich-text span structure which holds the 
	beginning co鰎dinates of the span to be replaced, and optionally, the 
	ending co鰎dinates. If the ul_LEN_TEXT_TO_REPLACE parameter is provided, 
	passed-in ending co鰎dinates are ignored and will be reset according to the 
	dimension of that parameter. Output tells replacement span.
ul_LEN_TXT_TO_REPL: Optional. The length of the text to in the rich-text field 
	to be replaced. Parameter required if null ending co鰎dinates are provided 
	in the pt_spn parameter.
f_TRANSLT_LF: flag specifying whether rich-text linefeed and paragraph markers 
	should be translated to CRLFs when assessing content (TRUE) or not (FALSE)
PC: the replacement text content, null-terminated
pt_ctx: Input & Output. Pointer to tracking information about the operative 
	rich-text field.
RETURN:
	eus_SUCCESS if no errors occurred
	eus_ERR_INVLD_ARG if any passed-in parameter is obviously invalid
	the Notes API error code otherwise

--- suggested enhancement ----
9/6/02 PR: um, code out PDL'd logic

--- revision history ---------
9/6/02 PR
+ implemented replacement-span output
+ listing format adjustment, minor safety improvement, token renaming, 
  documentation adjustment

3/20/00 PR
+ fixed bug wherein content to be preserved in an ending CDTEXT was not being 
  handled properly
+ logic shortening, some by leveraging the new UnlockItem() procedure

9/12/99 PR
+ added support for replacement content in excess of MAXONESEGSIZE
+ documentation adjustment

12/8/98 PR: created			*/
STATUS eus_ReplaceRtfSpanText( CdRecordSpan *const  pt_spn, 
								const DWORD  ul_LEN_TXT_TO_REPL, 
								const BOOL  f_TRANSLT_LF, 
								const char  PC[], 
								RtfTrackingInfo *const  pt_ctx)	{
	CdRecordCursor  t_crsrBgin, t_crsrEnd, t_crsr;
	WORD  us_offstEnd = NULL, us_lenEndPrsrv = NULL;
	BYTE * puc, * puc_bgnSpnCdRec;
	DWORD  ul_lenRepl, ul;
	STATUS  us_err;
	BOOL  f_OneRcrdSpn = FALSE, f_ItmJustLockd;

	//If any of the parameters are obviously invalid, short-circuit with 
	//	general failure. A valid span requires either a content length or a 
	//	valid end cursor.
	if (!( pt_spn && PC && pt_ctx && pt_spn->t_crsrBgin.pt_item && 
										pt_spn->t_crsrBgin.puc_location && 
										(pt_spn->t_crsrEnd.puc_location && 
										pt_spn->t_crsrEnd.pt_item || 
										ul_LEN_TXT_TO_REPL) && 
										(pt_spn->t_crsrBgin.pt_item == 
										pt_spn->t_crsrEnd.pt_item ? 
										pt_spn->t_crsrBgin.puc_location < 
										pt_spn->t_crsrEnd.puc_location : TRUE)))
		return eus_ERR_INVLD_ARG;

	//now that the input seems okay, it's safe to initialize certain local 
	//	variables
	t_crsrBgin = pt_spn->t_crsrBgin;
	puc_bgnSpnCdRec = t_crsrBgin.puc_location;
	t_crsrEnd = pt_spn->t_crsrEnd;
	if (t_crsrEnd.puc_location && *t_crsrEnd.puc_location == muc_SIG_CDTEXT)
		us_offstEnd = pt_spn->us_offstEnd;

	//determine the length of the replacement content, accounting if needed for 
	//	CRLF to rich-text linefeed conversion
	if (f_TRANSLT_LF)
		TranslateCrlfText( PC, NULL, &ul_lenRepl, NULL, NULL);
	else
		ul_lenRepl = strlen( PC);

	//if the passed-in span is marked by offset instead of end cursor, 
	//	determine the appropriate end-cursor configuration
	if (ul_LEN_TXT_TO_REPL && !f_ProcessKnownLengthRtfText( t_crsrBgin, 
										pt_spn->us_offstBgin, 
										ul_LEN_TXT_TO_REPL, f_TRANSLT_LF, 
										pt_ctx, &t_crsrEnd, &us_offstEnd, NULL))
		return !eus_SUCCESS;
	_ASSERTE( t_crsrEnd.puc_location);

	//if a question, determine the length of text to preserve in the ending 
	//	CDTEXT record, and whether we're dealing with a span that involves only 
	//	one CDTEXT record and can be replaced with only one CDTEXT record
	ul = sizeof( CDTEXT) + ul_lenRepl;
	if (*t_crsrEnd.puc_location == muc_SIG_CDTEXT)	{
		us_lenEndPrsrv = t_crsrEnd.us_recLength - (sizeof( CDTEXT) + 
																us_offstEnd);
		f_OneRcrdSpn = *puc_bgnSpnCdRec == muc_SIG_CDTEXT && puc_bgnSpnCdRec == 
									t_crsrEnd.puc_location && ul + 
									pt_spn->us_offstBgin + us_lenEndPrsrv <= 
									mus_LENLIMIT_CDTEXT_REC;
	}

	//if the starting CD record of the span is not virtualized...
	if (t_crsrBgin.pt_item->i_type != mi_VIRTUAL)	{
		//Virtualize up through the CD record preceding the starting CD record 
		//	involved in the span. The actual frontier absolute offset will then 
		//	point to the starting CD record.
		if (us_err = us_VirtualizeThruActualLocation( puc_bgnSpnCdRec, pt_ctx, 
																		NULL))
			return us_err;
	//Else we have to deal with already virtualized content. And that's a lot 
	//	of complicated work.
	}else	{
return !eus_SUCCESS;	//PGP development shortcut
		//if the CD record following the span's ending CD record resides on an 
		//	item different from the item containing the starting CD record...
			//if the item containing the starting CD record is not the last 
			//	virtual item, set the virtuality member of a proxy 
			//	item-tracking structure to a copy of the item structure 
			//	associated with the starting CD record's item but with a null 
			//	next-item pointer

			//if the starting CD record is not the first record in the item...
				//reset the length of the item to point to the end of the CD 
				//	record preceding the starting CD record
			//else reset the length of the item to point to the beginning of 
			//	the item (i.e. no item content at this point)
		//else we need to recast the item bounding the rich-text span
			//in a proxy item-tracking structure, create an initial virtual 
			//	item and initialize it with the content on the item containing 
			//	the starting CD record that precedes the starting record

		//set an internal flag telling this procedure to nullify the beginning 
		//	cursor in the passed-in span structure to indicate its invalidity 
		//	to the caller
	} //if (t_crsrBgin.pt_item->i_type != mi_VIRTUAL)

	//if the starting co鰎dinates of the span to be replaced fall within, not 
	//	at the beginning of, a CDTEXT...
	if (*puc_bgnSpnCdRec == muc_SIG_CDTEXT && pt_spn->us_offstBgin)	{
		WORD  us;
		CdRecordCursor  t_newStart;

		//determine the tentative length of the first replacement CDTEXT as the 
		//	sum of the length of a CDTEXT structure, the length of the content 
		//	which precedes the the beginning of the span in the initial CDTEXT, 
		//	the length of our replacement text, and if the ending co鰎dinates 
		//	of the span fall within the same CDTEXT as the starting co鰎dinates 
		//	do, the length of the content following the end of the span -- 
		//	tentative because the length cannot exceed the length limit we're 
		//	observing on CDTEXT records.
		ul += pt_spn->us_offstBgin;
		if (f_OneRcrdSpn)
			ul += us_lenEndPrsrv;

		//get a pointer at which we can virtualize a CDTEXT CD record of the 
		//	length just determined or of our limit length
		us = ul < mus_LENLIMIT_CDTEXT_REC ? (WORD) ul : mus_LENLIMIT_CDTEXT_REC;
		_ASSERTE( f_OneRcrdSpn ? ul == us : TRUE);
		if (us_err = us_GetVirtualCdRecAppendPointer( pt_ctx, us, &puc))
			return us_err;

		//Virtualize the initial CDTEXT structure that accounts for its 
		//	ultimate length, content included. Utilize the CDTEXT associated 
		//	with the beginning of the rich-text span to preserve the font 
		//	signature.
		memcpy( puc, puc_bgnSpnCdRec, sizeof( CDTEXT));
		((CDTEXT *) puc)->Header.Length = us;

		//virtualize the content that precedes the beginning of the span in the 
		//	initial CDTEXT
		memcpy( puc + sizeof( CDTEXT), puc_bgnSpnCdRec + sizeof( CDTEXT), 
														pt_spn->us_offstBgin);

		//Virtualize the replacement content, initializing the replacement-span 
		//	output along the way.
		t_newStart.puc_location = puc;
		t_newStart.pt_item = pt_ctx->pt_endVirtual;
		t_newStart.us_recLength = us;
		if (us_err = us_AppendTextToVirtuality( PC, ul_lenRepl, f_TRANSLT_LF, 
											&t_newStart, pt_spn->us_offstBgin, 
											NULL, pt_ctx, pt_spn))
			return us_err;

		//if the ending co鰎dinates of the span fall within the same CDTEXT 
		//	that the starting co鰎dinates do...
		if (f_OneRcrdSpn)	{
			//tack on the content following the end of the span
			memcpy( puc + ul - us_lenEndPrsrv, puc_bgnSpnCdRec + sizeof( 
									CDTEXT) + us_offstEnd + 1, us_lenEndPrsrv);

			//set the ending-offset co鰎dinate of the replacement-span output
			pt_spn->us_offstEnd = (WORD) (ul - us_lenEndPrsrv - 
															sizeof( CDTEXT));

			//done with the virtualization of the CDTEXT, update the variable 
			//	that tracks the length of the virtual item being written to
			pt_ctx->pt_endVirtual->ul_length += 
									pt_ctx->pt_endVirtual->ul_length % 2 + ul;
		} //if (f_OneRcrdSpn)
	//else we construct our own CDTEXTs to hold the replacement content
	}else	{
//PGP development shortcut: assuming that the first record in the span is a 
//	CDTEXT. If it's not, return general failure.
if (*puc_bgnSpnCdRec != muc_SIG_CDTEXT)
	return !eus_SUCCESS;

		//Determine a FONTID that we can use in the CDTEXT we need to write. 
		//	Basically, we want the closest CDTEXT before (and including) the 
		//	beginning of the span. If one isn't available, we want the closest 
		//	one after the beginning CD record of the span (even if it's in the 
		//	span). If no CDTEXTs are available at all, we will use the Notes 
		//	default FONTID.

//PGP development shortcut: using the beginning, source CDTEXT's FONTID
		//virtualize the replacement content and note the span of the added 
		//	rich-text
		if (us_err = us_AppendTextToVirtuality( PC, ul_lenRepl, f_TRANSLT_LF, 
									NULL, NULL, ((CDTEXT *) 
									puc_bgnSpnCdRec)->FontID, pt_ctx, pt_spn))
			return us_err;
	} //if (*t_crsrBgin.puc_location == LOBYTE(

	//if some of the content in the CD record pointed to by the ending cursor 
	//	needs to be preserved and we're not working with a one-record span...
	if (!f_OneRcrdSpn && us_lenEndPrsrv)	{
		//get a pointer at which we can virtualize a CDTEXT containing only the 
		//	content to be preserved
		if (us_err = us_GetVirtualCdRecAppendPointer( pt_ctx, sizeof( CDTEXT) + 
														us_lenEndPrsrv, &puc))
			return us_err;

		//virtualize a CDTEXT based on the ending CDTEXT's format but 
		//	containing just the content not included in the specified span
		memcpy( puc, t_crsrEnd.puc_location, sizeof( CDTEXT));
		((CDTEXT *) puc)->Header.Length = sizeof( CDTEXT) + us_lenEndPrsrv;
		memcpy( puc + sizeof( CDTEXT), t_crsrEnd.puc_location + sizeof( 
									CDTEXT) + us_offstEnd + 1, us_lenEndPrsrv);

		//done with the virtualization of the CDTEXT, update the variable that 
		//	tracks the length of the virtual item being written to
		pt_ctx->pt_endVirtual->ul_length += pt_ctx->pt_endVirtual->ul_length % 
										2 + sizeof( CDTEXT) + us_lenEndPrsrv;
	} //if (!f_OneRcrdSpn && us_lenEndPrsrv)

	//if the CD record that follows the original ending CD record is 
	//	virtualized...
	t_crsr = t_crsrEnd;
	AdvanceCdCursor( &t_crsr, pt_ctx, NULL, &f_ItmJustLockd);
	if (t_crsr.pt_item && t_crsr.pt_item->i_type == mi_VIRTUAL)	{
return !eus_SUCCESS;		//PGP development shortcut
		//if that CD record is the first record in its item...
			//restore virtuality by setting the next pointer of the last item 
			//	in the proxy virtuality equal to the item containing this CD 
			//	record that follows the ending CD record
		//else
			//virtualize that CD record following the original ending CD record 
			//	and all ensuing records up to the end of its item

			//set the next pointer of the last proxy item equal to the item 
			//	pointed to by the next pointer of the item we just virtualized
	//else if a following CD record exists (in Actuality)...
	}else if (t_crsr.pt_item)	{
		//reset the actual-frontier absolute offset to the beginning of the CD 
		//	record following the original ending CD record
		pt_ctx->ul_ActualFrontier = ul_GetAbsoluteOffset( 
									t_crsr.puc_location, t_crsr.pt_item, 
									pt_ctx->pt_Actuality);

		//if the item containing the following CD record was just locked in 
		//	memory for the sake of this operation, unlock it now
		if (f_ItmJustLockd)
			UnlockItem( t_crsr.pt_item);
	//else reset the actual-frontier absolute offset to the ultimate length of 
	//	the rich-text field
	}else
		pt_ctx->ul_ActualFrontier = ul_GetAbsoluteOffset( 
									t_crsrEnd.puc_location, 
									t_crsrEnd.pt_item, pt_ctx->pt_Actuality) + 
									t_crsrEnd.us_recLength + 
									t_crsrEnd.us_recLength % 2;

	//if either the original starting CD record or the CD record following the 
	//	original ending CD record was virtualized...
		//if the first item of the proxy virtuality is the same as the original 
		//	item containing the starting CD record...
			//discard the items that fall between the original item containing 
			//	the starting CD record and the item pointed to by the next 
			//	pointer in the last proxy-virtual item
		//else
			//if the original item containing the starting CD record is the 
			//	first virtual item...
				//set the virtuality member of the main item-tracking structure 
				//	to point to the first proxy virtual item
			//else locate in the original virtuality the item whose next 
			//	pointer specifies this original item and reset its next pointer 
			//	to the first proxy virtual item

			//discard the original item and any that follow it up through the 
			//	one pointed to by the next pointer in the last proxy-virtual 
			//	item

	return eus_SUCCESS;
} //eus_ReplaceRtfSpanText(


/** us_AppendTextToVirtuality( ***
Purpose is to append a null-terminated buffer of text content to the current 
virtual rich-text stream. The procedue does not concern itself with paragraph 
styles even though it does break up larg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -