示例#1
0
文件: Path.cpp 项目: Advi42/XCSoar
gcc_pure
static Path::const_pointer
LastSeparator(Path::const_pointer path)
{
  const auto *p = StringFindLast(path, _T('/'));
#ifdef WIN32
  const auto *backslash = StringFindLast(path, _T('\\'));
  if (p == nullptr || backslash > p)
    p = backslash;
#endif
  return p;
}
示例#2
0
gcc_pure
static const TCHAR *
LastSeparator(const TCHAR *path)
{
    const auto *p = StringFindLast(path, _T('/'));
#ifdef WIN32
    const auto *backslash = StringFindLast(path, _T('\\'));
    if (p == nullptr || backslash > p)
        p = backslash;
#endif
    return p;
}
示例#3
0
文件: Path.cpp 项目: Advi42/XCSoar
Path::const_pointer
Path::GetExtension() const
{
  auto base = GetBase();
  if (base == nullptr)
    return nullptr;

  assert(!StringIsEmpty(base.c_str()));

  return StringFindLast(base.c_str() + 1, _T('.'));
}
示例#4
0
gcc_pure
static const TCHAR *
BackslashBaseName(const TCHAR *p)
{
  if (DIR_SEPARATOR != '\\') {
    const auto *backslash = StringFindLast(p, _T('\\'));
    if (backslash != NULL)
      p = backslash + 1;
  }

  return BaseName(p);
}
示例#5
0
const TCHAR *
ProfileMap::GetPathBase(const char *key) const
{
  TCHAR buffer[MAX_PATH];
  if (!Get(key, buffer, ARRAY_SIZE(buffer)))
      return nullptr;

  const TCHAR *p = buffer;
  if (DIR_SEPARATOR != '\\') {
    const auto *backslash = StringFindLast(p, _T('\\'));
    if (backslash != NULL)
      p = backslash + 1;
  }

  return BaseName(p);
}
示例#6
0
static bool
ParseRunwayDirection(const TCHAR* src, Runway &dest)
{
  // WELT2000 written files contain a 4-digit runway direction specification
  // at the end of the comment, e.g. "123.50 0927"

  const auto *start = StringFindLast(src, _T(' '));
  if (start)
    start++;
  else
    start = src;

  TCHAR *end;
  int value = _tcstol(start, &end, 10);
  if (start == end || *end != _T('\0') || end - start != 4  )
    return false;

  int a1 = (value / 100) * 10;
  int a2 = (value % 100) * 10;
  if (a1 < 0 || a1 > 360 || a2 < 0 || a2 > 360)
    return false;
  if (a1 == 360)
    a1 = 0;
  if (a2 == 360)
    a2 = 0;

  // TODO: WELT2000 generates quite a few entries where
  //       a) a1 == a2 (accept those) and
  //       b) the angles are neither equal or reciprocal (discard those)
  //       Try finding a logic behind this behaviour.
  if (a1 != a2 && (a1 + 180) % 360 != a2)
    return false;

  dest.SetDirectionDegrees(a1);
  return true;
}
示例#7
0
void
Canvas::DrawFormattedText(PixelRect *rc, const TCHAR *text, unsigned format)
{
  assert(text != nullptr);
#ifndef UNICODE
  assert(ValidateUTF8(text));
#endif

  if (font == nullptr)
    return;

  unsigned skip = font->GetLineSpacing();
  unsigned max_lines = (format & DT_CALCRECT) ? -1 :
                       (rc->bottom - rc->top + skip - 1) / skip;

  size_t len = _tcslen(text);
  TCHAR *duplicated = new TCHAR[len + 1], *p = duplicated;
  unsigned lines = 1;
  for (const TCHAR *i = text; *i != _T('\0'); ++i) {
    TCHAR ch = *i;
    if (ch == _T('\n')) {
      /* explicit line break */

      if (++lines >= max_lines)
        break;

      ch = _T('\0');
    } else if (ch == _T('\r'))
      /* skip */
      continue;
    else if ((unsigned)ch < 0x20)
      /* replace non-printable characters */
      ch = _T(' ');

    *p++ = ch;
  }

  *p = _T('\0');
  len = p - duplicated;

  // simple wordbreak algorithm. looks for single spaces only, no tabs,
  // no grouping of multiple spaces
  if (format & DT_WORDBREAK) {
    for (size_t i = 0; i < len; i += _tcslen(duplicated + i) + 1) {
      PixelSize sz = CalcTextSize(duplicated + i);
      TCHAR *prev_p = nullptr;

      // remove words from behind till line fits or no more space is found
      while (sz.cx > rc->right - rc->left &&
             (p = StringFindLast(duplicated + i, _T(' '))) != nullptr) {
        if (prev_p)
          *prev_p = _T(' ');
        *p = _T('\0');
        prev_p = p;
        sz = CalcTextSize(duplicated + i);
      }

      if (prev_p) {
        lines++;
        if (lines >= max_lines)
          break;
      }
    }
  }

  if (format & DT_CALCRECT) {
    rc->bottom = rc->top + lines * skip;
    delete[] duplicated;
    return;
  }

  int y = (format & DT_VCENTER) && lines < max_lines
    ? (rc->top + rc->bottom - lines * skip) / 2
    : rc->top;
  for (size_t i = 0; i < len; i += _tcslen(duplicated + i) + 1) {
    if (duplicated[i] != _T('\0')) {
      int x;
      if (format & (DT_RIGHT | DT_CENTER)) {
        PixelSize sz = CalcTextSize(duplicated + i);
        x = (format & DT_CENTER) ? (rc->left + rc->right - sz.cx)/2 :
                                    rc->right - sz.cx;  // DT_RIGHT
      } else {  // default is DT_LEFT
        x = rc->left;
      }

      TextAutoClipped(x, y, duplicated + i);

      if (format & DT_UNDERLINE)
        DrawHLine(x, x + CalcTextWidth(duplicated + i),
                  y + font->GetAscentHeight() + 1, text_color);
    }
    y += skip;
    if (y >= rc->bottom)
      break;
  }

  delete[] duplicated;
}