size_t ConvertFromUTF8(const wxCharBuffer& utf8_buff, const wxMBConv& conv, wxWCharBuffer& wchar_buff, size_t& wchar_buff_len, wxCharBuffer& dest_buff, size_t& dest_buff_len, size_t char_len) { // static // Calculate length of conversion to widechar size_t wchar_len = wxConvUTF8.MB2WC(NULL, utf8_buff, 0); if (wchar_len == (size_t)-1) return (size_t)-1; // invalid conversion // Extend widechar buffer if needed if (wchar_buff_len < wchar_len + sizeof(wxChar)) { wchar_buff_len = wchar_len + sizeof(wxChar); wchar_buff = wxWCharBuffer(wchar_buff_len); } // Convert to widechar wchar_len = wxConvUTF8.MB2WC(wchar_buff.data(), utf8_buff, wchar_buff_len); if (wchar_len == (size_t)-1) return (size_t)-1; // invalid conversion // Calculate length of conversion to dest encoding size_t dest_len = conv.WC2MB(NULL, wchar_buff, 0); if (dest_len == (size_t)-1) return (size_t)-1; // invalid conversion // Extend dest buffer if needed if (dest_buff_len < dest_len + char_len) { dest_buff_len = dest_len + char_len; dest_buff = wxCharBuffer(dest_buff_len); } // Convert to dest encoding dest_len = conv.WC2MB(dest_buff.data(), wchar_buff, dest_buff_len); if (dest_len == (size_t)-1) return (size_t)-1; // invalid conversion return dest_len; }
size_t ConvertToUTF8(const char* source, const size_t source_len, const wxMBConv& conv, wxCharBuffer& temp_buff, size_t& temp_buff_len, wxWCharBuffer& wchar_buff, size_t& wchar_buff_len, wxCharBuffer& utf8_buff, size_t& utf8_buff_len, size_t char_len) { // static // We have to copy the source string to a temporary buffer so that we can // make it null terminated. if (temp_buff_len < source_len+char_len) { temp_buff_len = source_len+char_len; temp_buff = wxCharBuffer(temp_buff_len); } memcpy(temp_buff.data(), source, source_len); for (unsigned int i = 0; i < char_len; ++i) temp_buff.data()[source_len+i] = '\0'; // Calculate length of conversion to widechar size_t wchar_len = conv.MB2WC(NULL, temp_buff, 0); if (wchar_len == (size_t)-1) return (size_t)-1; // invalid conversion // Extend widechar buffer if needed if (wchar_buff_len < wchar_len + sizeof(wxChar)) { wchar_buff_len = wchar_len + sizeof(wxChar); wchar_buff = wxWCharBuffer(wchar_buff_len); } // Convert to widechar wchar_len = conv.MB2WC(wchar_buff.data(), temp_buff, wchar_buff_len); if (wchar_len == (size_t)-1) return (size_t)-1; // invalid conversion // Calculate length of conversion to UTF-8 size_t utf8_len = wxConvUTF8.WC2MB(NULL, wchar_buff, 0); if (utf8_len == (size_t)-1) return (size_t)-1; // invalid conversion // Extend UTF-8 buffer if needed if (utf8_buff_len < utf8_len) { utf8_buff_len = utf8_len + 1; utf8_buff = wxCharBuffer(utf8_buff_len); } // Convert to UTF-8 utf8_len = wxConvUTF8.WC2MB(utf8_buff.data(), wchar_buff, utf8_buff_len); if (utf8_len == (size_t)-1) return (size_t)-1; // invalid conversion return utf8_len; }
unsigned int FixedLine::SetLine(unsigned int startpos, unsigned int endpos, bool cache) { m_docLen = m_doc.GetLength(); #ifdef __WXDEBUG__ wxASSERT(!m_inSetLine); // re-entrancy check m_inSetLine = true; wxASSERT(startpos >= 0 && startpos < m_docLen); wxASSERT(endpos > startpos && endpos <= m_docLen); if (startpos > 0) { wxChar c; cxLOCKDOC_READ(m_doc) c = doc.GetChar(startpos - 1); cxENDLOCK wxASSERT(c == wxT('\n')); } if (endpos < m_docLen) { wxChar c; cxLOCKDOC_READ(m_doc) c = doc.GetChar(endpos - 1); cxENDLOCK wxASSERT(c == wxT('\n')); } #endif if (!cache || startpos != textstart || endpos != textend) { textstart = startpos; textend = endpos; m_lineLen = endpos - startpos; // Check if we need to resize line buffer if (m_lineBufferLen < m_lineLen) { m_lineBufferLen = m_lineLen; m_lineBuffer = wxCharBuffer(m_lineBufferLen); // wxCharBuffer allocs room for & adds nullbyte at len } // Cache the current line in lineBuffer (as UTF-8) cxLOCKDOC_READ(m_doc) doc.GetTextPart(textstart, textend, (unsigned char*)m_lineBuffer.data()); cxENDLOCK // Style the lines m_sr.Init(textstart, textend); for (vector<Styler*>::iterator si = m_stylers.begin(); si != m_stylers.end(); ++si) { (*si)->Style(m_sr); } m_extents.clear(); m_extents.reserve(m_lineLen); unsigned int xpos = 0; unsigned int lastpos = 0; unsigned int style_start = 0; int fontStyle = m_sr.GetFontStyle(0); char* dbi = m_lineBuffer.data(); // Build list of text extends (totalling) compensating for tabs and styles // There is one extent per byte in the text. In utf8 chars composed out of multiple // bytes, they will all have same value. for (unsigned int style_id = 0; style_id < m_sr.GetStyleCount(); ++style_id) { const unsigned int style_end = m_sr.GetStyleEnd(style_id) - textstart; // Ignore zero length styles if (style_start == style_end) continue; // Check for style change if (m_sr.GetFontStyle(style_id) != fontStyle) { if (style_start > lastpos) { m_sr.ApplyFontStyle(fontStyle); // Get extends for current segment m_extsBuf.clear(); const unsigned int seg_len = style_start-lastpos; const wxString text(dbi+lastpos, wxConvUTF8, seg_len); dc.GetPartialTextExtents(text, m_extsBuf); wxASSERT(!text.empty() && m_extsBuf.size() == text.size()); // Add to main list adjusted for offset unsigned int extpos = 0; unsigned int offset = xpos; for (unsigned int i = lastpos; i < style_start; ++i) { if ((dbi[i] & 0xC0) == 0x80) m_extents.push_back(xpos); // Only count first byte of UTF-8 multibyte chars else if (dbi[i] == '\t') { // Add tab extend xpos = ((xpos / tabwidth)+1) * tabwidth; // GetTabPoint(xpos); offset += xpos - (m_extsBuf[extpos] + offset); m_extents.push_back(xpos); ++extpos; } else { xpos = m_extsBuf[extpos] + offset; m_extents.push_back(xpos); ++extpos; } } // Small hack to make lines that end with italics not cut off the edge of the last character if (fontStyle &= wxFONTFLAG_ITALIC) { m_extents.back() += 2; xpos = m_extents.back(); } } lastpos = style_start; fontStyle = m_sr.GetFontStyle(style_id); } style_start = style_end; } // Add extends for last segment if (lastpos < m_lineLen) { m_sr.ApplyFontStyle(fontStyle); // Get extends for current segment m_extsBuf.clear(); const unsigned int seg_len = m_lineLen-lastpos; const wxString text(dbi+lastpos, wxConvUTF8, seg_len); dc.GetPartialTextExtents(text, m_extsBuf); wxASSERT(!text.empty() && m_extsBuf.size() == text.size()); // Add to main list adjusted for offset unsigned int extpos = 0; unsigned int offset = xpos; for (unsigned int i = lastpos; i < m_lineLen; ++i) { if ((dbi[i] & 0xC0) == 0x80) m_extents.push_back(xpos); // Only count first byte of UTF-8 multibyte chars else if (dbi[i] == '\t') { // Add tab extend xpos = ((xpos / tabwidth)+1) * tabwidth; // GetTabPoint(xpos); offset += xpos - (m_extsBuf[extpos] + offset); m_extents.push_back(xpos); ++extpos; } else { xpos = m_extsBuf[extpos] + offset; m_extents.push_back(xpos); ++extpos; } } } wxASSERT(m_extents.size() == m_lineLen); BreakLine(); } else if (width != old_width) { wxASSERT(m_extents.size() == m_lineLen); BreakLine(); } #ifdef __WXDEBUG__ m_inSetLine = false; // re-entrancy check #endif return (m_wrapMode == cxWRAP_NONE) ? m_lineWidth : height; }