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

📄 usplib.c

📁 支持Unicode及Uniscribe的多语言输入的文本编辑器源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
			uspData->widthList	 = realloc(uspData->widthList,	 uspData->glyphAllocLen * sizeof(int));
			uspData->svaList     = realloc(uspData->svaList,	 uspData->glyphAllocLen * sizeof(SCRIPT_VISATTR));
		}

		//
		//	Convert the unicode-text into an array of glyphs
		//
		hr = ScriptShape(
			hdc,
			&uspFont->scriptCache, 
			wrunstr, 
			itemRun->len, 
			uspData->glyphAllocLen - uspData->glyphCount, 
			&itemRun->analysis, 
			uspData->glyphList		+ itemRun->glyphPos,
			uspData->clusterList	+ itemRun->charPos,		// already allocated in UspAnalyze
			uspData->svaList		+ itemRun->glyphPos,
			&itemRun->glyphCount
			);
	
		// no glyphs in the font - try again
		if(hr == USP_E_SCRIPT_NOT_IN_FONT)
		{
			itemRun->analysis.eScript = SCRIPT_UNDEFINED;
		}
		// unknown failure
		else if(hr != S_OK && hr != E_OUTOFMEMORY)
		{
			SelectObject(hdc, holdFont);
			return FALSE;
		}

	} while(hr != S_OK);

	// expand the glyph-list to include this item-run
	uspData->glyphCount += itemRun->glyphCount;


	//
	//	Generate glyph advance-widths for this run
	//
	ScriptPlace(
		hdc,
		&uspFont->scriptCache,
		uspData->glyphList	+ itemRun->glyphPos,
		itemRun->glyphCount,
		uspData->svaList	+ itemRun->glyphPos,
		&itemRun->analysis, 
		uspData->widthList	+ itemRun->glyphPos,
		uspData->offsetList	+ itemRun->glyphPos,
		&abc
		);

	// 
	//	Control-characters require special handling
	//
	if(itemRun->ctrl && itemRun->chcode != '\t')
	{
		// chcode is only valid for control-characters
		int chwidth = CtrlCharWidth(uspFont, hdc, itemRun->chcode);
		
		uspData->widthList[itemRun->glyphPos]	= chwidth;
		itemRun->width							= chwidth;
	}
	else
	{
		// remember the item-run width
		itemRun->width = abc.abcA + abc.abcB + abc.abcC;
	}

	// restore the font
	SelectObject(hdc, holdFont);
	return TRUE;
}

//
//	Remember the selection-state of an ITEM_RUN:
//
//	0 - no characters selected
//  1 - all characters selected
//  2 - some characters selected
//
//	This is a useful optimization used for drawing - under some
//  circumstances, an ITEM_RUN can be skipped if it's neighbouring
//  runs share the same selection-state
//
static
void IdentifyRunSelections(USPDATA *uspData, ITEM_RUN *itemRun)
{
	int c;
	int numsel = 0;
	
	// analyze run to see which characters are selected
	for(c = itemRun->charPos; c < itemRun->charPos + itemRun->len; c++)
		if(uspData->attrList[c].sel)
			numsel++;

	// set the selection state accordingly
	if(numsel == 0)					itemRun->selstate = 0;
	else if(numsel == itemRun->len)	itemRun->selstate = 1;
	else							itemRun->selstate = 2;
}

//
//	Update the USPDATA with a new attribute-run-list.
//
//	The font-information stored in ATTR::font is ignored, as are
//  the ::ctrl and ::eol flags
//
VOID WINAPI UspApplyAttributes(USPDATA *uspData, ATTR *attrRunList)
{
	int i, a, c=0;

	//
	//	'Flatten' the user-supplied attribute-run-list to an array
	//	of single ATTR structures, each 1-unit long.
	//
	for(a = 0, i = 0; i < uspData->stringLen; i++)
	{
		uspData->attrList[i]		= attrRunList[a];
		uspData->attrList[i].len	= 1;

		if(++c == attrRunList[a].len)
		{
			a++;
			c = 0;
		}
	}

	//	Identify the selection state of each run (none,all,partial)
	for(i = 0; i < uspData->itemRunCount; i++)
	{
		IdentifyRunSelections(uspData, &uspData->itemRunList[i]);
	}
}

//
//	Update USPDATA with new selection information - only modify
//	the ATTR::sel values within our internal attribute-list
//  (i.e. leave all other text styles untouched)
//
VOID WINAPI UspApplySelection(USPDATA *uspData, int selStart, int selEnd)
{
	int i,p;

	if(selStart >= selEnd)
	{
		int t = selStart;
		selStart = selEnd;
		selEnd   = t;
	}

	for(i = 0; i < uspData->itemRunCount; i++)
	{
		ITEM_RUN *itemRun = &uspData->itemRunList[i];

		for(p = itemRun->charPos; p < itemRun->charPos + itemRun->len; p++)
			uspData->attrList[p].sel = (p >= selStart && p < selEnd);

		IdentifyRunSelections(uspData, itemRun);
	}
}

//
//	Initialize the USPDATA line-state with a new text-string,
//  and an optional attribute-run-list. We reuse any previously
//  allocated arrays in the USPDATA structure, minimizing heap-access
//
//	*attrRunList can be NULL, in which case the line of text is initialized
//	with the default Windows text-colours and with font#0.
//	Otherwise, attrRunList is expected to describe a range of text the
//	same length as the text-input buffer.
//
//	*uspFontList can also be NULL, in which case the currently selected font
//	is used to shape the text. This same font *must* be reselected into
//	the device context when UspTextOut is called.
//
//	Any change to the fonts in uspFontList requires UspAnalyze to be called again.
//
BOOL WINAPI UspAnalyze (
		USPDATA			* uspData, 
		HDC				  hdc, 
		WCHAR			* wstr, 
		int				  wlen, 
		ATTR			* attrRunList, 
		UINT			  flags, 
		USPFONT			* uspFontList,
		SCRIPT_CONTROL	* scriptControl,
		SCRIPT_STATE	* scriptState,
		SCRIPT_TABDEF   * scriptTabdef
	)
{
	ATTR	defAttr;
	int		itemRunAllocLen;
	int		i;

	if(uspData == 0)
		return FALSE;

	// reset the lists
	uspData->itemRunCount	= 0;
	uspData->glyphCount		= 0;
	uspData->uspFontList	= uspFontList;
	uspData->stringLen		= wlen;

	// nothing to do?
	if(wstr == 0 || wlen == 0)
		return TRUE;

	// remember current allocation-size of itemRunList
	itemRunAllocLen = uspData->itemRunAllocLen;

	// use the default font if no user-supplied list
	if(uspFontList == 0)
	{
		uspData->defaultFont.hFont = 0;
		uspData->uspFontList = &uspData->defaultFont;
	}

	//
	// if no attributes specified then default to a single span
	// covering the entire length of the text
	//
	if(attrRunList == 0)
	{
		// create the default attribute
		defAttr.fg		= GetSysColor(COLOR_WINDOWTEXT);
		defAttr.bg		= GetSysColor(COLOR_WINDOW);
		defAttr.font	= 0;
		defAttr.sel		= 0;
		defAttr.ctrl	= 0;
		defAttr.eol		= 0;
		defAttr.len		= wlen;

		attrRunList		= &defAttr;
	}

	//
	//	Build a list of runs by calling ScriptItemize and merging
	//  those spans with the attribute-list. When BuildMergedItemRunList
	//  returns, the itemRunList array has been stored in uspData
	//
	if(!BuildMergedItemRunList(
				uspData,
				wstr, 
				wlen, 
				attrRunList,
				scriptControl,
				scriptState)
		)
	{
		return FALSE;
	}
 
	//	reallocate BIDI-arrays if item-run-list changed size
	if(itemRunAllocLen < uspData->itemRunAllocLen)
	{
		uspData->bidiLevels	= realloc(uspData->bidiLevels, uspData->itemRunAllocLen * sizeof(BYTE));
		uspData->visualToLogicalList = realloc(uspData->visualToLogicalList, uspData->itemRunAllocLen * sizeof(int));
	}

	//	Analyze the resulting runlist and build the BIDI-level array	
	if(!BuildVisualMapping( uspData->itemRunList, 
							uspData->itemRunCount, 
							uspData->bidiLevels,
							uspData->visualToLogicalList)
			)
	{
		return FALSE;
	}

	// Rellocate logical cluster+attribute arrays prior to shaping
	if(uspData->stringAllocLen < wlen)
	{
		uspData->stringAllocLen = wlen;
		uspData->clusterList	= realloc(uspData->clusterList,	wlen * sizeof(WORD));
		uspData->attrList		= realloc(uspData->attrList,	wlen * sizeof(ATTR));
		uspData->breakList		= realloc(uspData->breakList,	wlen * sizeof(SCRIPT_LOGATTR));
	}

	// Generate the word-break information in logical order
	for(i = 0; i < uspData->itemRunCount; i++)
	{
		ITEM_RUN *itemRun = &uspData->itemRunList[i];

		ScriptBreak(
				wstr + itemRun->charPos, 
				itemRun->len, 
				&itemRun->analysis, 
				uspData->breakList + itemRun->charPos
			);
	}

	// Perform shaping + generate glyph data
	for(i = 0; i < uspData->itemRunCount; i++)
	{
		ITEM_RUN *itemRun = GetItemRun(uspData, i);//;//&uspData->itemRunList[i];	//

		ShapeAndPlaceItemRun(
				uspData, 
				itemRun, 
				hdc, 
				wstr + itemRun->charPos
			);
	}

	//
	// locate tab-characters and expand the corresponding glyph-widths appropriately.
	// this must happen after *all* shaping/widths have been generated
	//
	if(scriptTabdef)
	{
		if(ExpandTabs(uspData, wstr, wlen, scriptTabdef))
		{
			// modify the SCRIPT_LOGATTR list to make tabs whitespace
			for(i = 0; i < wlen; i++)
			{
				if(wstr[i] == '\t')
					uspData->breakList[i].fWhiteSpace = TRUE;
			}
		}
		else
		{
			return FALSE;
		}
	}


	//
	//	Keep a flattened copy of the attribute-run-list, but 
	//	with one element per character rather than larger runs.
	//
	UspApplyAttributes(uspData, attrRunList);

	return TRUE;
}

//
//	Create the control structure
//
USPDATA * WINAPI UspAllocate()
{
	USPDATA *uspData = malloc(sizeof(USPDATA));

	if(uspData)
	{
		// set all members to zero including run-counts etc
		memset(uspData, 0, sizeof(USPDATA));

		uspData->selFG = GetSysColor(COLOR_HIGHLIGHTTEXT);
		uspData->selBG = GetSysColor(COLOR_HIGHLIGHT);
	}
		
	return uspData;
}

//
//	Free everything
//
VOID WINAPI UspFree(USPDATA *uspData)
{
	if(uspData)
	{
		// free the script-cache (will be NULL if a user-supplied fontlist was specified)
		ScriptFreeCache(&uspData->defaultFont.scriptCache);

		// free the glyph-buffers
		free(uspData->glyphList);
		free(uspData->svaList);
		free(uspData->widthList);
		free(uspData->offsetList);
		
		// free the item-run buffers
		free(uspData->itemRunList);
		free(uspData->visualToLogicalList);
		free(uspData->bidiLevels);
		free(uspData->tempItemList);
		
		// free the logical character-buffers
		free(uspData->clusterList);
		free(uspData->attrList);

		// free the control structure
		free(uspData);
	}
}

BOOL WINAPI UspGetSize(USPDATA *uspData, SIZE * size)
{
	int i;
	
	size->cx = 0;
	size->cy = 0;

	for(i = 0; i < uspData->itemRunCount; i++)
	{
		size->cx += uspData->itemRunList[i].width;
	}

	return TRUE;
}

SCRIPT_LOGATTR * WINAPI UspGetLogAttr(USPDATA *uspData)
{
	if(uspData && uspData->breakList)
	{
		return uspData->breakList;
	}
	else
	{
		return NULL;
	}
}

BOOL WINAPI UspBuildAttr (
		ATTR	  *	attr,
		COLORREF    colfg,	
		COLORREF    colbg,
		int			len,
		int			font,
		int			sel,
		int			ctrl,
		int			eol
	)
{
	if(attr == 0)
		return FALSE;

	attr->fg		= colfg;
	attr->bg		= colbg;
	attr->len		= len;
	attr->font		= font;
	attr->sel		= sel;
	attr->ctrl		= ctrl;
	attr->eol		= eol;
	attr->reserved	= 0;

	return TRUE;
}

⌨️ 快捷键说明

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