Esempio n. 1
0
void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) {
   decodeText(buffer, sizeBuffer);
   if (!*buffer) {
      *shortVersion = '\0';
      return;
   }
   // Handle control codes:
   char *to=buffer;
   int len=strlen(to);
   int IsShortName=0;
   while (len > 0) {
      int l = Utf8CharLen(to);
      unsigned char *p = (unsigned char *)to;
      if (l == 2 && *p == 0xC2) // UTF-8 sequence
         p++;
      if (*p == 0x86 || *p == 0x87) {
         IsShortName += (*p == 0x86) ? 1 : -1;
         memmove(to, to + l, len - l + 1); // we also copy the terminating 0!
         len -= l;
         l = 0;
      }
      if (l && IsShortName) {
         if (l < sizeShortVersion) {
            for (int i = 0; i < l; i++)
                *shortVersion++ = to[i];
            sizeShortVersion -= l;
         }
      }
      to += l;
      len -= l;
   }
   *shortVersion = '\0';
}
Esempio n. 2
0
/**
 * Insert a string into the text buffer. If maxwidth of the Textbuf is zero,
 * we don't care about the visual-length but only about the physical
 * length of the string.
 * @param str String to insert.
 * @param marked Replace the currently marked text with the new text.
 * @param caret Move the caret to this point in the insertion string.
 * @param insert_location Position at which to insert the string.
 * @param replacement_end Replace all characters from #insert_location up to this location with the new string.
 * @return True on successful change of Textbuf, or false otherwise.
 */
bool Textbuf::InsertString(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
{
	uint16 insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos;
	if (insert_location != NULL) {
		insertpos = insert_location - this->buf;
		if (insertpos > this->bytes) return false;

		if (replacement_end != NULL) {
			this->DeleteText(insertpos, replacement_end - this->buf, str == NULL);
		}
	} else {
		if (marked) this->DiscardMarkedText(str == NULL);
	}

	if (str == NULL) return false;

	uint16 bytes = 0, chars = 0;
	WChar c;
	for (const char *ptr = str; (c = Utf8Consume(&ptr)) != '\0';) {
		if (!IsValidChar(c, this->afilter)) break;

		byte len = Utf8CharLen(c);
		if (this->bytes + bytes + len > this->max_bytes) break;
		if (this->chars + chars + 1   > this->max_chars) break;

		bytes += len;
		chars++;

		/* Move caret if needed. */
		if (ptr == caret) this->caretpos = insertpos + bytes;
	}

	if (bytes == 0) return false;

	if (marked) {
		this->markpos = insertpos;
		this->markend = insertpos + bytes;
	}

	memmove(this->buf + insertpos + bytes, this->buf + insertpos, this->bytes - insertpos);
	memcpy(this->buf + insertpos, str, bytes);

	this->bytes += bytes;
	this->chars += chars;
	if (!marked && caret == NULL) this->caretpos += bytes;
	assert(this->bytes <= this->max_bytes);
	assert(this->chars <= this->max_chars);
	this->buf[this->bytes - 1] = '\0'; // terminating zero

	this->UpdateStringIter();
	this->UpdateWidth();
	this->UpdateCaretPosition();
	this->UpdateMarkedText();

	return true;
}
Esempio n. 3
0
/**
 * Insert a character to a textbuffer. If maxwidth of the Textbuf is zero,
 * we don't care about the visual-length but only about the physical
 * length of the string
 * @param key Character to be inserted
 * @return Return true on successful change of Textbuf, or false otherwise
 */
bool Textbuf::InsertChar(WChar key)
{
	uint16 len = (uint16)Utf8CharLen(key);
	if (this->bytes + len <= this->max_bytes && this->chars + 1 <= this->max_chars) {
		memmove(this->buf + this->caretpos + len, this->buf + this->caretpos, this->bytes - this->caretpos);
		Utf8Encode(this->buf + this->caretpos, key);
		this->chars++;
		this->bytes    += len;
		this->caretpos += len;

		this->UpdateStringIter();
		this->UpdateWidth();
		this->UpdateCaretPosition();
		this->UpdateMarkedText();
		return true;
	}
	return false;
}
Esempio n. 4
0
/**
 * Copy and convert old custom names to UTF-8.
 * They were all stored in a 512 by 32 (200 by 24 for TTO) long string array
 * and are now stored with stations, waypoints and other places with names.
 * @param id the StringID of the custom name to clone.
 * @return the clones custom name.
 */
char *CopyFromOldName(StringID id)
{
	/* Is this name an (old) custom name? */
	if (GB(id, 11, 5) != 15) return NULL;

	if (CheckSavegameVersion(37)) {
		/* Old names were 24/32 characters long, so 128 characters should be
		 * plenty to allow for expansion when converted to UTF-8. */
		char tmp[128];
		uint offs = _savegame_type == SGT_TTO ? 24 * GB(id, 0, 8) : 32 * GB(id, 0, 9);
		const char *strfrom = &_old_name_array[offs];
		char *strto = tmp;

		for (; *strfrom != '\0'; strfrom++) {
			WChar c = (byte)*strfrom;

			/* Map from non-ISO8859-15 characters to UTF-8. */
			switch (c) {
				case 0xA4: c = 0x20AC; break; // Euro
				case 0xA6: c = 0x0160; break; // S with caron
				case 0xA8: c = 0x0161; break; // s with caron
				case 0xB4: c = 0x017D; break; // Z with caron
				case 0xB8: c = 0x017E; break; // z with caron
				case 0xBC: c = 0x0152; break; // OE ligature
				case 0xBD: c = 0x0153; break; // oe ligature
				case 0xBE: c = 0x0178; break; // Y with diaresis
				default: break;
			}

			/* Check character will fit into our buffer. */
			if (strto + Utf8CharLen(c) > lastof(tmp)) break;

			strto += Utf8Encode(strto, c);
		}

		/* Terminate the new string and copy it back to the name array */
		*strto = '\0';

		return strdup(tmp);
	} else {
		/* Name will already be in UTF-8. */
		return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
	}
}
Esempio n. 5
0
/**
 * Copy and convert old custom names to UTF-8.
 * They were all stored in a 512 by 32 (200 by 24 for TTO) long string array
 * and are now stored with stations, waypoints and other places with names.
 * @param id the StringID of the custom name to clone.
 * @return the clones custom name.
 */
char *CopyFromOldName(StringID id)
{
	/* Is this name an (old) custom name? */
	if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return NULL;

	if (IsSavegameVersionBefore(SLV_37)) {
		/* Allow for expansion when converted to UTF-8. */
		char tmp[LEN_OLD_STRINGS * MAX_CHAR_LENGTH];
		uint offs = _savegame_type == SGT_TTO ? LEN_OLD_STRINGS_TTO * GB(id, 0, 8) : LEN_OLD_STRINGS * GB(id, 0, 9);
		const char *strfrom = &_old_name_array[offs];
		char *strto = tmp;

		for (; *strfrom != '\0'; strfrom++) {
			WChar c = (byte)*strfrom;

			/* Map from non-ISO8859-15 characters to UTF-8. */
			switch (c) {
				case 0xA4: c = 0x20AC; break; // Euro
				case 0xA6: c = 0x0160; break; // S with caron
				case 0xA8: c = 0x0161; break; // s with caron
				case 0xB4: c = 0x017D; break; // Z with caron
				case 0xB8: c = 0x017E; break; // z with caron
				case 0xBC: c = 0x0152; break; // OE ligature
				case 0xBD: c = 0x0153; break; // oe ligature
				case 0xBE: c = 0x0178; break; // Y with diaresis
				default: break;
			}

			/* Check character will fit into our buffer. */
			if (strto + Utf8CharLen(c) > lastof(tmp)) break;

			strto += Utf8Encode(strto, c);
		}

		/* Terminate the new string and copy it back to the name array */
		*strto = '\0';

		return stredup(tmp);
	} else {
		/* Name will already be in UTF-8. */
		return stredup(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]);
	}
}
Esempio n. 6
0
File: epg.c Progetto: piotrasd/vdr
static void StripControlCharacters(char *s)
{
  if (s) {
     int len = strlen(s);
     while (len > 0) {
           int l = Utf8CharLen(s);
           uchar *p = (uchar *)s;
           if (l == 2 && *p == 0xC2) // UTF-8 sequence
              p++;
           if (*p == 0x86 || *p == 0x87) {
              memmove(s, p + 1, len - l + 1); // we also copy the terminating 0!
              len -= l;
              l = 0;
              }
           s += l;
           len -= l;
           }
     }
}
Esempio n. 7
0
// originally from libdtv, Copyright Rolf Hakenes <*****@*****.**>
void String::decodeText(char *buffer, int size) {
   const unsigned char *from=data.getData(0);
   char *to=buffer;
   int len=getLength();
   if (len <= 0) {
      *to = '\0';
      return;
   }
   bool singleByte;
   const char *cs = getCharacterTable(from, len, &singleByte);
   if (singleByte && SystemCharacterTableIsSingleByte || !convertCharacterTable((const char *)from, len, to, size, cs)) {
      if (len >= size)
         len = size - 1;
      strncpy(to, (const char *)from, len);
      to[len] = 0;
   }
   else
      len = strlen(to); // might have changed
   // Handle control codes:
   while (len > 0) {
      int l = Utf8CharLen(to);
      if (l <= 2) {
         unsigned char *p = (unsigned char *)to;
         if (l == 2 && *p == 0xC2) // UTF-8 sequence
            p++;
         bool Move = true;
         switch (*p) {
           case 0x8A: *to = '\n'; break;
           case 0xA0: *to = ' ';  break;
           default:   Move = false;
         }
         if (l == 2 && Move) {
            memmove(p, p + 1, len - 1); // we also copy the terminating 0!
            len -= 1;
            l = 1;
         }
      }
      to += l;
      len -= l;
   }
}
Esempio n. 8
0
static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left, int right, int top, int bottom)
{
	CopyInDParam(0, ni->params, lengthof(ni->params));
	StringID str = ni->string_id;

	char buf[512];
	GetString(buf, str, lastof(buf));
	const char *s = buf;

	char buffer[256];
	char *d = buffer;
	const char *last = lastof(buffer);

	for (;;) {
		WChar c = Utf8Consume(&s);
		if (c == 0) {
			break;
		} else if (c == '\n') {
			if (d + 4 >= last) break;
			d[0] = d[1] = d[2] = d[3] = ' ';
			d += 4;
		} else if (IsPrintable(c)) {
			if (d + Utf8CharLen(c) >= last) break;
			d += Utf8Encode(d, c);
		}
	}
	*d = '\0';

	DrawPixelInfo tmp_dpi;
	if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true;

	int width = GetStringBoundingBox(buffer).width;
	int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left);

	DrawPixelInfo *old_dpi = _cur_dpi;
	_cur_dpi = &tmp_dpi;
	DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
	_cur_dpi = old_dpi;

	return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
}
Esempio n. 9
0
/**
 * Update Textbuf type with its actual physical character and screenlength
 * Get the count of characters in the string as well as the width in pixels.
 * Useful when copying in a larger amount of text at once
 */
void Textbuf::UpdateSize()
{
	const char *buf = this->buf;

	this->chars = this->bytes = 1; // terminating zero

	WChar c;
	while ((c = Utf8Consume(&buf)) != '\0') {
		this->bytes += Utf8CharLen(c);
		this->chars++;
	}
	assert(this->bytes <= this->max_bytes);
	assert(this->chars <= this->max_chars);

	this->caretpos = this->bytes - 1;
	this->UpdateStringIter();
	this->UpdateWidth();
	this->UpdateMarkedText();

	this->UpdateCaretPosition();
}
Esempio n. 10
0
/**
 * Convert to OpenTTD's encoding from that of the local environment.
 * When the project is built in UNICODE, the system codepage is irrelevant and
 * the input string is wide. In ANSI mode, the string is in the
 * local codepage which we'll convert to wide-char, and then to UTF-8.
 * OpenTTD internal encoding is UTF8.
 * The returned value's contents can only be guaranteed until the next call to
 * this function. So if the value is needed for anything else, use convert_from_fs
 * @param name pointer to a valid string that will be converted (local, or wide)
 * @return pointer to the converted string; if failed string is of zero-length
 * @see the current code-page comes from video\win32_v.cpp, event-notification
 * WM_INPUTLANGCHANGE
 */
const char *FS2OTTD(const TCHAR *name)
{
	static char utf8_buf[512];
#if defined(UNICODE)
	return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
#else
	char *s = utf8_buf;

	for (; *name != '\0'; name++) {
		wchar_t w;
		int len = MultiByteToWideChar(_codepage, 0, name, 1, &w, 1);
		if (len != 1) {
			DEBUG(misc, 0, "[utf8] M2W error converting '%c'. Errno %lu", *name, GetLastError());
			continue;
		}

		if (s + Utf8CharLen(w) >= lastof(utf8_buf)) break;
		s += Utf8Encode(s, w);
	}

	*s = '\0';
	return utf8_buf;
#endif /* UNICODE */
}
Esempio n. 11
0
		int GetInternalCharLength(WChar c) const
		{
			/* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */
			return Utf8CharLen(c) < 4 ? 1 : 2;
		}