diff options
Diffstat (limited to 'win32/PlatWin.cxx')
| -rw-r--r-- | win32/PlatWin.cxx | 66 | 
1 files changed, 33 insertions, 33 deletions
| diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 631c38ab5..f1d73c2d6 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -1593,40 +1593,44 @@ XYPOSITION SurfaceD2D::WidthText(Font &font_, const char *s, int len) {  void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) {  	SetFont(font_); -	int fit = 0; +	if (!pIDWriteFactory || !pTextFormat) { +		// SetFont failed or no access to DirectWrite so give up. +		return; +	}  	const TextWide tbuf(s, len, unicodeMode, codePageText);  	TextPositions poses(tbuf.tlen); -	fit = tbuf.tlen; +	// Initialize poses for safety. +	std::fill(poses.buffer, poses.buffer + tbuf.tlen, 0.0f); +	// Create a layout +	IDWriteTextLayout *pTextLayout = 0; +	const HRESULT hrCreate = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout); +	if (!SUCCEEDED(hrCreate)) { +		return; +	}  	const int clusters = 1000;  	DWRITE_CLUSTER_METRICS clusterMetrics[clusters];  	UINT32 count = 0; -	if (pIDWriteFactory && pTextFormat) { -		SetFont(font_); -		// Create a layout -		IDWriteTextLayout *pTextLayout = 0; -		const HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout); -		if (!SUCCEEDED(hr)) -			return; -		if (!SUCCEEDED(pTextLayout->GetClusterMetrics(clusterMetrics, clusters, &count))) -			return; -		// A cluster may be more than one WCHAR, such as for "ffi" which is a ligature in the Candara font -		FLOAT position = 0.0f; -		size_t ti=0; -		for (size_t ci=0; ci<count; ci++) { -			for (size_t inCluster=0; inCluster<clusterMetrics[ci].length; inCluster++) { -				poses.buffer[ti++] = position + clusterMetrics[ci].width * (inCluster + 1) / clusterMetrics[ci].length; -			} -			position += clusterMetrics[ci].width; +	const HRESULT hrGetCluster = pTextLayout->GetClusterMetrics(clusterMetrics, clusters, &count); +	pTextLayout->Release(); +	if (!SUCCEEDED(hrGetCluster)) { +		return; +	} +	// A cluster may be more than one WCHAR, such as for "ffi" which is a ligature in the Candara font +	FLOAT position = 0.0f; +	size_t ti=0; +	for (size_t ci=0; ci<count; ci++) { +		for (size_t inCluster=0; inCluster<clusterMetrics[ci].length; inCluster++) { +			poses.buffer[ti++] = position + clusterMetrics[ci].width * (inCluster + 1) / clusterMetrics[ci].length;  		} -		PLATFORM_ASSERT(ti == static_cast<size_t>(tbuf.tlen)); -		pTextLayout->Release(); +		position += clusterMetrics[ci].width;  	} +	PLATFORM_ASSERT(ti == static_cast<size_t>(tbuf.tlen));  	if (unicodeMode) {  		// Map the widths given for UTF-16 characters back onto the UTF-8 input string  		int ui=0;  		const unsigned char *us = reinterpret_cast<const unsigned char *>(s);  		int i=0; -		while (ui<fit) { +		while (ui<tbuf.tlen) {  			const unsigned char uch = us[i];  			unsigned int lenChar = 1;  			if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { @@ -1650,26 +1654,22 @@ void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *  		}  	} else if (codePageText == 0) { -		// One character per position +		// One char per position  		PLATFORM_ASSERT(len == tbuf.tlen); -		for (size_t kk=0; kk<static_cast<size_t>(len); kk++) { +		for (int kk=0; kk<tbuf.tlen; kk++) {  			positions[kk] = poses.buffer[kk];  		}  	} else { -		// May be more than one byte per position -		unsigned int ui = 0; -		FLOAT position = 0.0f; -		for (int i=0; i<len;) { -			if (ui < count) -				position = poses.buffer[ui]; +		// May be one or two bytes per position +		int ui = 0; +		for (int i=0; i<len && ui<tbuf.tlen;) { +			positions[i] = poses.buffer[ui];  			if (Platform::IsDBCSLeadByte(codePageText, s[i])) { -				positions[i] = position; -				positions[i+1] = position; +				positions[i+1] = poses.buffer[ui];  				i += 2;  			} else { -				positions[i] = position;  				i++;  			} | 
