예제 #1
0
void VConTextPart::SetLen(unsigned anLen, unsigned FontWidth)
{
	_ASSERTE(anLen>0 && anLen<=0xFFFF);
	Length = anLen;

	// May this part be shrinked freely?
	if (Flags & TRF_TextSpacing)
	{
		Flags |= TRF_SizeFree;
	}
	else if ((Flags & TRF_TextPseudograph) && isCharPseudoFree(*Chars))
	{
		wchar_t wc = *Chars; bool bDiffers = false;
		for (unsigned i = 1; i < Length; i++)
		{
			if (Chars[i] != wc)
			{
				bDiffers = true; break;
			}
		}
		if (!bDiffers)
			Flags |= TRF_SizeFree;
	}

	unsigned FontWidth2 = 2*FontWidth;

	const CharAttr* pca = Attrs;
	TextCharType* pcf = CharFlags;
	unsigned* pcw = CharWidth;

	// Preliminary character widths estimation

	if (Flags & TRF_SizeFree)
	{
		// spaces, horizontal lines (frames), etc. They may be shrinked freely
		for (unsigned left = anLen; left--; pca++, pcf++)
		{
			*pcw = FontWidth; // if non-shrinked
			*pcf = TCF_WidthFree;
		}
	}
	else
	{
		//WARNING: We rely here on pca->Flags2, but not on self evaluated data?
		for (unsigned left = anLen; left--; pca++, pcf++, pcw++)
		{
			if (pca->Flags2 & (CharAttr2_NonSpacing|CharAttr2_Combining))
			{
				// zero-width
				*pcw = 0;
				*pcf = TCF_WidthZero;
			}
			else if (pca->Flags2 & CharAttr2_DoubleSpaced)
			{
				*pcw = FontWidth2;
				*pcf = TCF_WidthDouble;
			}
			else
			{
				*pcw = FontWidth;
				*pcf = TCF_WidthNormal;
			}
		}
	}
}
예제 #2
0
void VConTextPart::Done(uint anLen, uint FontWidth)
{
	_ASSERTE(anLen>0 && FontWidth>0);
	Length = anLen;
	TotalWidth = MinWidth = 0;

	// May this part be shrinked freely?
	if (Flags & TRF_TextSpacing)
	{
		Flags |= TRF_SizeFree;
	}
	else if ((Flags & TRF_TextPseudograph) && isCharPseudoFree(*Chars))
	{
		wchar_t wc = *Chars; bool bDiffers = false;
		for (uint i = 1; i < Length; i++)
		{
			if (Chars[i] != wc)
			{
				bDiffers = true; break;
			}
		}
		if (!bDiffers)
			Flags |= TRF_SizeFree;
	}

	// Helper - double cell characters
	uint FontWidth2 = 2*FontWidth;
	uint FontWidth2M = FontWidth2 * DEF_DOUBLE_MUL / DEF_DOUBLE_DIV;
	uint FontWidthM = FontWidth * DEF_SINGLE_MUL / DEF_SINGLE_DIV;

	const wchar_t* pch = Chars;
	const CharAttr* pca = Attrs;
	TextCharType* pcf = CharFlags;
	uint* pcw = CharWidth;

	ZeroStruct(AllWidths);

	//TODO: Continuous spaces must be processed separately

	if (Flags & TRF_SizeFree)
	{
		VConTextPartWidth& aw = AllWidths[TCF_WidthFree];
		for (uint left = anLen; left--; pch++, pca++, pcf++, pcw++)
		{
			_ASSERTE(!(pca->Flags2 & (CharAttr2_NonSpacing|CharAttr2_Combining|CharAttr2_DoubleSpaced)));
			*pcw = FontWidth; // if non-shrinked
			*pcf = TCF_WidthFree;
			TotalWidth += FontWidth;
			aw.Count++;
			aw.Width += FontWidth;
		}
		aw.MinWidth += FontWidth;
	}
	else
	{
		for (uint left = anLen; left--; pch++, pca++, pcf++, pcw++)
		{
			if (pca->Flags2 & (CharAttr2_NonSpacing|CharAttr2_Combining))
			{
				// zero-width
				*pcw = 0;
				*pcf = TCF_WidthZero;
				VConTextPartWidth& aw = AllWidths[TCF_WidthZero];
				aw.Count++; // Informational
			}
			else if (pca->Flags2 & CharAttr2_DoubleSpaced)
			{
				*pcw = FontWidth2;
				*pcf = TCF_WidthDouble;
				TotalWidth += FontWidth2;
				// Even double-width space have to be same width as ‘normal’ CJK glyph
				MinWidth += FontWidth2M;
				VConTextPartWidth& aw = AllWidths[TCF_WidthDouble];
				aw.Count++;
				aw.Width += FontWidth2;
				aw.MinWidth += FontWidth2M;
			}
			else /*if (gpSet->isMonospace
					|| (gpSet->isFixFarBorders && isCharAltFont(ch))
					|| (gpSet->isEnhanceGraphics && isCharProgress(ch))
					)*/
			{
				//TODO: Caller must process fonts and set "real" character widths for proportinal fonts
				*pcw = FontWidth;
				*pcf = TCF_WidthNormal;
				VConTextPartWidth& aw = AllWidths[TCF_WidthNormal];
				aw.Count++;
				aw.Width += FontWidth;
				aw.MinWidth += FontWidthM;
			}
		}
	}

	TotalWidth = AllWidths[TCF_WidthFree].Width
		+  AllWidths[TCF_WidthNormal].Width
		+  AllWidths[TCF_WidthDouble].Width
		;
	MinWidth = AllWidths[TCF_WidthFree].MinWidth
		+  AllWidths[TCF_WidthNormal].MinWidth
		+  AllWidths[TCF_WidthDouble].MinWidth
		;
}