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; } } } }
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 ; }