Пример #1
0
void CGUITextLayout::AppendToUTF32(const CStdStringW &utf16, character_t colStyle, vecText &utf32)
{
  // NOTE: Assumes a single line of text
  utf32.reserve(utf32.size() + utf16.size());
  for (unsigned int i = 0; i < utf16.size(); i++)
    utf32.push_back(utf16[i] | colStyle);
}
Пример #2
0
void TestDocReader::TestTOCFields()
{
	DocReader dr;
	dr.OpenFile(TEST_TOC_DOC);

	CStdStringW sGot = dr.GetMainDocumentText();
	CStdStringW sExp = L"Table of Contents\rTable of Contents\t1\rNote\t4\rAppendix B – Calculation of font (FTC) and language (LID)\t178\r\r";

	for (unsigned int i=0; i<(x64_int_cast)sGot.size(); i++)
	{
		switch (sGot[i])
		{
		case 19:
			OutputDebugString(_T("<start>"));
			break;
		case 20:
			OutputDebugString(_T("<result>"));
			break;
		case 21:
			OutputDebugString(_T("<end>"));
			break;
		default:
			{
				CStdStringW s = sGot.Mid(i,1);
				OutputDebugString(CStdString(s));
			}
		}
	}

	assertTest(sGot.Left(sExp.length()) == sExp);
}
Пример #3
0
void CKeyboardLayoutConfiguration::readByteMapFromXML(const TiXmlElement* pXMLMap, map<BYTE, WCHAR>& charToCharMap, const char* mapRootElement)
{
  if (pXMLMap && !pXMLMap->NoChildren())
  { // map keys
    const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
    while (pEntry)
    {
      CStdString strInHex = XMLUtils::GetAttribute(pEntry, "inhex");
      CStdString strOutChar = XMLUtils::GetAttribute(pEntry, "outchar");
      if (!strInHex.empty() && !strOutChar.empty())
      {
        CStdString hexValue = strInHex;
        CStdStringW toStr;
        g_charsetConverter.utf8ToW(strOutChar, toStr);

        int from;
        if (sscanf(hexValue.c_str(), "%x", (unsigned int *)&from))
        {
          if (from != 0) // eats nearly any typing error as 0: catch it:
          {
            if (from < 256)
            {
              if (toStr.size()==1)
              {
                    charToCharMap.insert(pair<BYTE, WCHAR>(from, toStr[0]));
                    CLog::Log(LOGDEBUG, "insert map entry from %d to %c ", from, toStr[0]);
              }
              else
              {
                CLog::Log(LOGERROR, "String to %ls does not have the expected length of >=1", toStr.c_str());
              }
            }
            else
            {
              CLog::Log(LOGERROR, "From value %d was greater than 255! ", from);
            }
          }
          else
          {
            CLog::Log(LOGERROR, "Scanned from-value %d as 0 probably a (typing?) error! ", from);
          }
        }
        else
        {
            CLog::Log(LOGERROR, "Could not scan from-value %s (was no valid hex value) ", hexValue.c_str());
        }
      }
      else
      {
        CLog::Log(LOGERROR, "map entry misses attribute <inhex> or <outchar> or content of them");
      }
      pEntry = pEntry->NextSiblingElement();
    }
  }
  else
  {
    CLog::Log(LOGERROR, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
  }
}
Пример #4
0
void CHTMLUtil::ConvertHTMLToW(const CStdStringW& strHTML, CStdStringW& strStripped)
{
  if (strHTML.size() == 0)
  {
    strStripped.Empty();
    return ;
  }
  int iPos = 0;
  strStripped = strHTML;
  while (mappings[iPos].html)
  {
    strStripped.Replace(mappings[iPos].html,CStdStringW(1, mappings[iPos].w));
    iPos++;
  }

  iPos = strStripped.Find(L"&#");
  while (iPos > 0 && iPos < (int)strStripped.size()-4)
  {
    int iStart = iPos + 1;
    iPos += 2;
    CStdStringW num;
    int base = 10;
    if (strStripped[iPos+1] == L'x')
    {
      base = 16;
      iPos++;
    }

    int i=iPos;
    while ( iPos < (int)strStripped.size() && 
           (base==16?iswxdigit(strStripped[iPos]):iswdigit(strStripped[iPos])))
      iPos++; 

    num = strStripped.Mid(i,iPos-i);
    wchar_t val = (wchar_t)wcstol(num.c_str(),NULL,base);
    if (base == 10)
      num.Format(L"&#%ls;",num.c_str());
    else
      num.Format(L"&#x%ls;",num.c_str());

    strStripped.Replace(num,CStdStringW(1,val));
    iPos = strStripped.Find(L"&#", iStart);
  }
}
Пример #5
0
// BidiTransform is used to handle RTL text flipping in the string
void CGUITextLayout::BidiTransform(vector<CGUIString> &lines, bool forceLTRReadingOrder)
{
  for (unsigned int i=0; i<lines.size(); i++)
  {
    CGUIString &line = lines[i];

    // reserve enough space in the flipped text
    vecText flippedText;
    flippedText.reserve(line.m_text.size());

    character_t sectionStyle = 0xffff0000; // impossible to achieve
    CStdStringW sectionText;
    for (vecText::iterator it = line.m_text.begin(); it != line.m_text.end(); ++it)
    {
      character_t style = *it & 0xffff0000;
      if (style != sectionStyle)
      {
        if (!sectionText.IsEmpty())
        { // style has changed, bidi flip text
          CStdStringW sectionFlipped = BidiFlip(sectionText, forceLTRReadingOrder);
          for (unsigned int j = 0; j < sectionFlipped.size(); j++)
            flippedText.push_back(sectionStyle | sectionFlipped[j]);
        }
        sectionStyle = style;
        sectionText.clear();
      }
      sectionText.push_back( (wchar_t)(*it & 0xffff) );
    }

    // handle the last section
    if (!sectionText.IsEmpty())
    {
      CStdStringW sectionFlipped = BidiFlip(sectionText, forceLTRReadingOrder);
      for (unsigned int j = 0; j < sectionFlipped.size(); j++)
        flippedText.push_back(sectionStyle | sectionFlipped[j]);
    }

    // replace the original line with the proccessed one
    lines[i] = CGUIString(flippedText.begin(), flippedText.end(), line.m_carriageReturn);
  }
}
void CGUIDialogKeyboardGeneric::InputText(const CStdString& aTextString)
{
  CStdStringW newStr;
  g_charsetConverter.utf8ToW(aTextString, newStr);
  if (!newStr.empty())
  {
    m_strEditing.clear();
    m_iEditingOffset = 0;
    m_strEdit.insert(GetCursorPos(), newStr);
    UpdateLabel();
    MoveCursor(newStr.size());
  }
}
Пример #7
0
void CKeyboardLayoutConfiguration::readCharMapFromXML(const TiXmlElement* pXMLMap, map<WCHAR, WCHAR>& charToCharMap, const char* mapRootElement)
{
  if (pXMLMap && !pXMLMap->NoChildren())
  { // map keys
    const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
    while (pEntry)
    {
      CStdString strInChar = XMLUtils::GetAttribute(pEntry, "inchar");
      CStdString strOutChar = XMLUtils::GetAttribute(pEntry, "outchar");
      if (!strInChar.empty() && !strOutChar.empty())
      {
        CStdStringW fromStr;
        g_charsetConverter.utf8ToW(strInChar, fromStr);
        CStdStringW toStr;
        g_charsetConverter.utf8ToW(strOutChar, toStr);
        if (fromStr.size()==1 && toStr.size()==1)
        {
          charToCharMap.insert(pair<WCHAR, WCHAR>(fromStr[0], toStr[0]));
          CLog::Log(LOGDEBUG, "insert map entry from %c to %c ", fromStr[0], toStr[0]);
        }
        else
        {
          CLog::Log(LOGERROR, "String from %ls or to %ls does not have the expected length of 1", fromStr.c_str(), toStr.c_str());
        }
      }
      else
      {
        CLog::Log(LOGERROR, "map entry misses attribute <inchar> or <outchar> or content of them");
      }
      pEntry = pEntry->NextSiblingElement();
    }
  }
  else
  {
    CLog::Log(LOGDEBUG, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
  }
}
Пример #8
0
void CRssReader::AddString(CStdStringW aString, int aColour, int iFeed)
{
  if (m_rtlText)
    m_strFeed[iFeed] = aString + m_strFeed[iFeed];
  else
    m_strFeed[iFeed] += aString;

  size_t nStringLength = aString.size();

  for (size_t i = 0;i < nStringLength;i++)
    aString[i] = (CHAR) (48 + aColour);

  if (m_rtlText)
    m_strColors[iFeed] = aString + m_strColors[iFeed];
  else
    m_strColors[iFeed] += aString;
}
Пример #9
0
bool CWIN32Util::IsUsbDevice(const CStdStringW &strWdrive)
{
  if (strWdrive.size() < 2)
    return false;

  CStdStringW strWDevicePath = StringUtils::Format(L"\\\\.\\%s",strWdrive.substr(0, 2).c_str());

  HANDLE deviceHandle = CreateFileW(
    strWDevicePath.c_str(),
   0,                // no access to the drive
   FILE_SHARE_READ | // share mode
   FILE_SHARE_WRITE,
   NULL,             // default security attributes
   OPEN_EXISTING,    // disposition
   0,                // file attributes
   NULL);            // do not copy file attributes

  if(deviceHandle == INVALID_HANDLE_VALUE)
    return false;

  // setup query
  STORAGE_PROPERTY_QUERY query;
  memset(&query, 0, sizeof(query));
  query.PropertyId = StorageDeviceProperty;
  query.QueryType = PropertyStandardQuery;

  // issue query
  DWORD bytes;
  STORAGE_DEVICE_DESCRIPTOR devd;
  STORAGE_BUS_TYPE busType = BusTypeUnknown;

  if (DeviceIoControl(deviceHandle,
   IOCTL_STORAGE_QUERY_PROPERTY,
   &query, sizeof(query),
   &devd, sizeof(devd),
   &bytes, NULL))
  {
   busType = devd.BusType;
  }

  CloseHandle(deviceHandle);

  return BusTypeUsb == busType;
 }
Пример #10
0
void TestDocReader::TestCommentsWithTrackChanges()
{
	DocReader dr;
	dr.OpenFile(TEST_COMMENTS_TC_DOC);

	CStdStringW sExp = L"Lots of the - the only actual change from this story is that the w3 file appear next to the revolving document,";
	sExp += " not in a dms folder, plus it create dms \05folders where there isn't one already.\r";
	sExp += "QA IanX> 2X integration sheets received 03/10/03\05. No visable change\05, change \05is to development tests only.\r";

	CStdStringW sGot = dr.GetMainDocumentText();

	for (unsigned int i=0; i<(x64_int_cast)sExp.size(); i++)
	{
		OutputDebugString(CStdString(sGot.substr(i,1)));
		assertTest(sGot[i] == sExp[i]);
	}

	assertTest(dr.GetMainDocumentText() == sExp);
}
Пример #11
0
void TestDocReader::TestAMoreCompicatedDocumentWithDeletedTextAndFastSaves()
{
	DocReader dr;
	dr.OpenFile(TEST_COMPLEX_FS_DOC);

	CStdStringW sExp = L"Marbles Reunited shows those pictures removed from Greece last  year by Lord Elgin next to those which remained in Athens. \r";
	sExp += "The London marbles are shown in colour while the others are depicted in white. \r";
	sExp += "The exhibition was shown at the Houses of Parliament earlier in the year. \r";
	sExp += "The marbles, ancient sculptures which once adorned the Parthenon in Athens, have been held in the Parthenon since 1811. \r\r";
	sExp += "A whole new paragraph after first fast save. A whole new paragraph after first fast save. A whole new paragraph after first fast save. A whole new paragraph after first fast save.\r";
	sExp += "\"However, this ws that this is not the case\". \r";
	sExp += "Other are using the forthcoming athletics, due to be held in Greece next millenium, to raise the question of ownership.\r\r";

	CStdStringW sGot = dr.GetMainDocumentText();

	for (unsigned int i=0; i<(x64_int_cast)sExp.size(); i++)
	{
//		OutputDebugString(CStdString(sGot.substr(i,1)));
		assertTest(sGot[i] == sExp[i]);
	}

	assertTest(dr.GetMainDocumentText() == sExp);
}
Пример #12
0
void TestDocReader::TestTabChanges()
{
	DocReader dr;
	dr.OpenFile(TEST_TABS_TC_DOC);

	CStdStringW sExp = L"\t\t\t\t\t\t\t\t\t\tABC\t1.23\tDEF\tGHI\tFFF\r";
	sExp += "Abc\t222.23\t\t\t\t\tdef\tghi\tddd\r";
	sExp += "Aaa\t10.87	b\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcb\tccc\txxx\r";
	sExp += "Ddd\t1.44994\t\t\t\t\t\t\r";
	sExp += "ABC\t1.23	DEF	GHI	aaa\t\t\t\r";
	sExp += "Abc\t222.\t\t\txxx\r";
	sExp += "Aaa\t10.87\tbcb\tccc\tzzz\r";
	sExp += "Ddd\t1.44994\teEEee\tfffLeft\tright\r";
	sExp += "Left\tRIGHT\r";

	CStdStringW sGot = dr.GetMainDocumentText();
	for (unsigned int i=0; i<(x64_int_cast)sExp.size(); i++)
	{
		OutputDebugString(CStdString(sGot.substr(i,1)));
		assertTest(sGot[i] == sExp[i]);
	}

	assertTest(dr.GetMainDocumentText() == sExp);
}
Пример #13
0
void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, color_t defaultColor, vecColors &colors, vecText &parsedText)
{
  // run through the string, searching for:
  // [B] or [/B] -> toggle bold on and off
  // [I] or [/I] -> toggle italics on and off
  // [COLOR ffab007f] or [/COLOR] -> toggle color on and off
  // [CAPS <option>] or [/CAPS] -> toggle capatilization on and off

  uint32_t currentStyle = defaultStyle; // start with the default font's style
  color_t currentColor = 0;

  colors.push_back(defaultColor);
  stack<color_t> colorStack;
  colorStack.push(0);

  // these aren't independent, but that's probably not too much of an issue
  // eg [UPPERCASE]Glah[LOWERCASE]FReD[/LOWERCASE]Georeg[/UPPERCASE] will work (lower case >> upper case)
  // but [LOWERCASE]Glah[UPPERCASE]FReD[/UPPERCASE]Georeg[/LOWERCASE] won't

  int startPos = 0;
  size_t pos = text.Find(L'[');
  while (pos != CStdString::npos && pos + 1 < text.size())
  {
    uint32_t newStyle = 0;
    color_t newColor = currentColor;
    bool colorTagChange = false;
    bool newLine = false;
    // have a [ - check if it's an ON or OFF switch
    bool on(true);
    int endPos = pos++; // finish of string
    if (text[pos] == L'/')
    {
      on = false;
      pos++;
    }
    // check for each type
    if (text.Mid(pos,2) == L"B]")
    { // bold - finish the current text block and assign the bold state
      pos += 2;
      if ((on && text.Find(L"[/B]",pos) >= 0) ||          // check for a matching end point
         (!on && (currentStyle & FONT_STYLE_BOLD)))       // or matching start point
        newStyle = FONT_STYLE_BOLD;
    }
    else if (text.Mid(pos,2) == L"I]")
    { // italics
      pos += 2;
      if ((on && text.Find(L"[/I]",pos) >= 0) ||          // check for a matching end point
         (!on && (currentStyle & FONT_STYLE_ITALICS)))    // or matching start point
        newStyle = FONT_STYLE_ITALICS;
    }
    else if (text.Mid(pos,10) == L"UPPERCASE]")
    {
      pos += 10;
      if ((on && text.Find(L"[/UPPERCASE]",pos) >= 0) ||  // check for a matching end point
         (!on && (currentStyle & FONT_STYLE_UPPERCASE)))  // or matching start point
        newStyle = FONT_STYLE_UPPERCASE;
    }
    else if (text.Mid(pos,10) == L"LOWERCASE]")
    {
      pos += 10;
      if ((on && text.Find(L"[/LOWERCASE]",pos) >= 0) ||  // check for a matching end point
         (!on && (currentStyle & FONT_STYLE_LOWERCASE)))  // or matching start point
        newStyle = FONT_STYLE_LOWERCASE;
    }
    else if (text.Mid(pos,3) == L"CR]" && on)
    {
      newLine = true;
      pos += 3;
    }
    else if (text.Mid(pos,5) == L"COLOR")
    { // color
      size_t finish = text.Find(L']', pos + 5);
      if (on && finish != CStdString::npos && (size_t)text.Find(L"[/COLOR]",finish) != CStdString::npos)
      {
        color_t color = g_colorManager.GetColor(text.Mid(pos + 5, finish - pos - 5));
        vecColors::const_iterator it = std::find(colors.begin(), colors.end(), color);
        if (it == colors.end())
        { // create new color
          if (colors.size() <= 0xFF)
          {
            newColor = colors.size();
            colors.push_back(color);
          }
          else // we have only 8 bits for color index, fallback to first color if reach max.
            newColor = 0;
        }
        else
          // reuse existing color
          newColor = it - colors.begin();
        colorStack.push(newColor);
        colorTagChange = true;
      }
      else if (!on && finish == pos + 5 && colorStack.size() > 1)
      { // revert to previous color
        colorStack.pop();
        newColor = colorStack.top();
        colorTagChange = true;
      }
      if (finish != CStdString::npos)
        pos = finish + 1;
    }

    if (newStyle || colorTagChange || newLine)
    { // we have a new style or a new color, so format up the previous segment
      CStdStringW subText = text.Mid(startPos, endPos - startPos);
      if (currentStyle & FONT_STYLE_UPPERCASE)
        subText.ToUpper();
      if (currentStyle & FONT_STYLE_LOWERCASE)
        subText.ToLower();
      AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText);
      if (newLine)
        parsedText.push_back(L'\n');

      // and switch to the new style
      startPos = pos;
      currentColor = newColor;
      if (on)
        currentStyle |= newStyle;
      else
        currentStyle &= ~newStyle;
    }
    pos = text.Find(L'[',pos);
  }
  // now grab the remainder of the string
  CStdStringW subText = text.Mid(startPos, text.GetLength() - startPos);
  if (currentStyle & FONT_STYLE_UPPERCASE)
    subText.ToUpper();
  if (currentStyle & FONT_STYLE_LOWERCASE)
    subText.ToLower();
  AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText);
}
Пример #14
0
void CWIN32Util::GetDrivesByType(VECSOURCES &localDrives, Drive_Types eDriveType, bool bonlywithmedia)
{
  WCHAR* pcBuffer= NULL;
  DWORD dwStrLength= GetLogicalDriveStringsW( 0, pcBuffer );
  if( dwStrLength != 0 )
  {
    CMediaSource share;

    dwStrLength+= 1;
    pcBuffer= new WCHAR [dwStrLength];
    GetLogicalDriveStringsW( dwStrLength, pcBuffer );

    int iPos= 0;
    WCHAR cVolumeName[100];
    do{
      int nResult = 0;
      cVolumeName[0]= L'\0';

      CStdStringW strWdrive = pcBuffer + iPos;

      UINT uDriveType= GetDriveTypeW( strWdrive.c_str()  );
      // don't use GetVolumeInformation on fdd's as the floppy controller may be enabled in Bios but
      // no floppy HW is attached which causes huge delays.
      if(strWdrive.size() >= 2 && strWdrive.substr(0,2) != L"A:" && strWdrive.substr(0,2) != L"B:")
        nResult= GetVolumeInformationW( strWdrive.c_str() , cVolumeName, 100, 0, 0, 0, NULL, 25);
      if(nResult == 0 && bonlywithmedia)
      {
        iPos += (wcslen( pcBuffer + iPos) + 1 );
        continue;
      }

      // usb hard drives are reported as DRIVE_FIXED and won't be returned by queries with REMOVABLE_DRIVES set
      // so test for usb hard drives
      /*if(uDriveType == DRIVE_FIXED)
      {
        if(IsUsbDevice(strWdrive))
          uDriveType = DRIVE_REMOVABLE;
      }*/

      share.strPath= share.strName= "";

      bool bUseDCD= false;
      if( uDriveType > DRIVE_UNKNOWN &&
        (( eDriveType == ALL_DRIVES && (uDriveType == DRIVE_FIXED || uDriveType == DRIVE_REMOTE || uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE )) ||
         ( eDriveType == LOCAL_DRIVES && (uDriveType == DRIVE_FIXED || uDriveType == DRIVE_REMOTE)) ||
         ( eDriveType == REMOVABLE_DRIVES && ( uDriveType == DRIVE_REMOVABLE )) ||
         ( eDriveType == DVD_DRIVES && ( uDriveType == DRIVE_CDROM ))))
      {
        //share.strPath = strWdrive;
        g_charsetConverter.wToUTF8(strWdrive, share.strPath);
        if( cVolumeName[0] != L'\0' )
          g_charsetConverter.wToUTF8(cVolumeName, share.strName);
        if( uDriveType == DRIVE_CDROM && nResult)
        {
          // Has to be the same as auto mounted devices
          share.strStatus = share.strName;
          share.strName = share.strPath;
          share.m_iDriveType= CMediaSource::SOURCE_TYPE_LOCAL;
          bUseDCD= true;
        }
        else
        {
          // Lets show it, like Windows explorer do... TODO: sorting should depend on driver letter
          switch(uDriveType)
          {
          case DRIVE_CDROM:
            share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), g_localizeStrings.Get(218).c_str());
            break;
          case DRIVE_REMOVABLE:
            if(share.strName.empty())
              share.strName = StringUtils::Format( "%s (%s)", g_localizeStrings.Get(437).c_str(), share.strPath.c_str());
            break;
          case DRIVE_UNKNOWN:
            share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), g_localizeStrings.Get(13205).c_str());
            break;
          default:
            if(share.strName.empty())
              share.strName = share.strPath;
            else
              share.strName = StringUtils::Format( "%s (%s)", share.strPath.c_str(), share.strName.c_str());
            break;
          }
        }
        StringUtils::Replace(share.strName, ":\\", ":");
        StringUtils::Replace(share.strPath, ":\\", ":");
        share.m_ignore= true;
        if( !bUseDCD )
        {
          share.m_iDriveType= (
           ( uDriveType == DRIVE_FIXED  )    ? CMediaSource::SOURCE_TYPE_LOCAL :
           ( uDriveType == DRIVE_REMOTE )    ? CMediaSource::SOURCE_TYPE_REMOTE :
           ( uDriveType == DRIVE_CDROM  )    ? CMediaSource::SOURCE_TYPE_DVD :
           ( uDriveType == DRIVE_REMOVABLE ) ? CMediaSource::SOURCE_TYPE_REMOVABLE :
             CMediaSource::SOURCE_TYPE_UNKNOWN );
        }

        AddOrReplace(localDrives, share);
      }
      iPos += (wcslen( pcBuffer + iPos) + 1 );
    } while( wcslen( pcBuffer + iPos ) > 0 );
    delete[] pcBuffer;
  }
}
Пример #15
0
void CGUITextLayout::ParseText(const CStdStringW &text, uint32_t defaultStyle, vecColors &colors, vecText &parsedText)
{
  // run through the string, searching for:
  // [B] or [/B] -> toggle bold on and off
  // [I] or [/I] -> toggle italics on and off
  // [COLOR ffab007f] or [/COLOR] -> toggle color on and off
  // [CAPS <option>] or [/CAPS] -> toggle capatilization on and off

//  uint32_t currentStyle = defaultStyle; // start with the default font's style
//  color_t currentColor = 0;

  stack<color_t> colorStack;
  colorStack.push(0);

  // these aren't independent, but that's probably not too much of an issue
  // eg [UPPERCASE]Glah[LOWERCASE]FReD[/LOWERCASE]Georeg[/UPPERCASE] will work (lower case >> upper case)
  // but [LOWERCASE]Glah[UPPERCASE]FReD[/UPPERCASE]Georeg[/LOWERCASE] won't
#define FONT_STYLE_UPPERCASE 4
#define FONT_STYLE_LOWERCASE 8

  int boldCounter = 0;
  int italicsCoutner = 0;
  int upperCounter = 0;
  int lowerCounter = 0;
  color_t color = 0;

  int startPos = 0;
  size_t pos = text.Find(L'[');
  while (pos != CStdString::npos && pos + 1 < text.size())
  {
    int style = 0;

    if (pos - startPos > 0)
    {
      if (boldCounter)
        style |= FONT_STYLE_BOLD;

      if (italicsCoutner)
        style |= FONT_STYLE_ITALICS;

      CStdStringW subText = text.Mid(startPos, pos - startPos);

      if (upperCounter)
      {
#if defined(_LINUX) && !defined(__APPLE__)
        std::transform(subText.begin(), subText.end(), subText.begin(),
                       (gunichar(*)(gunichar)) g_unichar_toupper);
#else
        subText.ToUpper();
#endif
      }

      if (lowerCounter)
      {
#if defined(_LINUX) && !defined(__APPLE__)
        std::transform(subText.begin(), subText.end(), subText.begin(),
                       (gunichar(*)(gunichar)) g_unichar_tolower);
#else
        subText.ToLower();
#endif
      }

      AppendToUTF32(subText, ((style & 3) << 24) | (color << 16), parsedText);

      startPos = pos;
    }

    // have a [ - check if it's an ON or OFF switch
    bool ignoreTag = false;
    ++pos;

    bool on = true;
    if (text[pos] == L'/')
    {
      on = false;
      pos++;
    }

    // check for each type
    if (text.Mid(pos,2) == L"B]")
    { // bold - finish the current text block and assign the bold state
      pos += 2;
      on ? ++boldCounter : --boldCounter;
    }
    else if (text.Mid(pos,2) == L"I]")
    { // italics
      pos += 2;
      on ? ++italicsCoutner : --italicsCoutner;
    }
    else if (text.Mid(pos,10) == L"UPPERCASE]")
    {
      pos += 10;
      on ? ++upperCounter : --upperCounter;
    }
    else if (text.Mid(pos,10) == L"LOWERCASE]")
    {
      pos += 10;
      on ? ++lowerCounter : --lowerCounter;
    }
    else if (text.Mid(pos,3) == L"CR]" && on)
    {
      pos += 3;
      parsedText.push_back(L'\n');
    }
    else if (text.Mid(pos,5) == L"COLOR")
    { // color
      size_t finish = text.Find(L']', pos + 5);
      if (on && finish != CStdString::npos && (size_t) text.Find(L"[/COLOR]",finish) != CStdString::npos)
      { // create new color
        color = colors.size();
        colors.push_back(g_colorManager.GetColor(text.Mid(pos + 5, finish - pos - 5)));
        colorStack.push(color);
      }
      else if (!on && finish == pos + 5 && colorStack.size() > 1)
      { // revert to previous color
        colorStack.pop();
        color = colorStack.top();
      }
      pos = finish + 1;
    }
    else
    {
      ignoreTag = true;
    }

    if (!ignoreTag)
    {
      startPos = pos;
    }

    pos = text.Find(L'[',pos);
  }

  // now grab the remainder of the string
  CStdStringW subText = text.Mid(startPos, text.GetLength() - startPos);
  int style = 0;
  if (upperCounter)
  {
#if defined(_LINUX) && !defined(__APPLE__)
        std::transform(subText.begin(), subText.end(), subText.begin(),
                       (gunichar(*)(gunichar)) g_unichar_toupper);
#else
        subText.ToUpper();
#endif
  }

  if (lowerCounter)
  {
#if defined(_LINUX) && !defined(__APPLE__)
    std::transform(subText.begin(), subText.end(), subText.begin(),
                   (gunichar(*)(gunichar)) g_unichar_tolower);
#else
    subText.ToLower();
#endif
  }

  if (boldCounter)
    style |= FONT_STYLE_BOLD;
  if (italicsCoutner)
    style |= FONT_STYLE_ITALICS;
  AppendToUTF32(subText, ((style & 3) << 24) | (color << 16), parsedText);
}
Пример #16
0
void CGUITextLayout::ParseText(const CStdStringW &text, DWORD defaultStyle, vector<DWORD> &colors, vector<DWORD> &parsedText)
{
  // run through the string, searching for:
  // [B] or [/B] -> toggle bold on and off
  // [I] or [/I] -> toggle italics on and off
  // [COLOR ffab007f] or [/COLOR] -> toggle color on and off
  // [CAPS <option>] or [/CAPS] -> toggle capatilization on and off

  DWORD currentStyle = defaultStyle; // start with the default font's style
  DWORD currentColor = 0;

  stack<DWORD> colorStack;
  colorStack.push(0);

  // these aren't independent, but that's probably not too much of an issue
  // eg [UPPERCASE]Glah[LOWERCASE]FReD[/LOWERCASE]Georeg[/UPPERCASE] will work (lower case >> upper case)
  // but [LOWERCASE]Glah[UPPERCASE]FReD[/UPPERCASE]Georeg[/LOWERCASE] won't
#define FONT_STYLE_UPPERCASE 4
#define FONT_STYLE_LOWERCASE 8

  int startPos = 0;
  size_t pos = text.Find(L'[');
  while (pos != CStdString::npos && pos + 1 < text.size())
  {
    DWORD newStyle = 0;
    DWORD newColor = currentColor;
    bool newLine = false;
    // have a [ - check if it's an ON or OFF switch
    bool on(true);
    int endPos = pos++; // finish of string
    if (text[pos] == L'/')
    {
      on = false;
      pos++;
    }
    // check for each type
    if (text.Mid(pos,2) == L"B]")
    { // bold - finish the current text block and assign the bold state
      newStyle = FONT_STYLE_BOLD;
      pos += 2;
    }
    else if (text.Mid(pos,2) == L"I]")
    { // italics
      newStyle = FONT_STYLE_ITALICS;
      pos += 2;
    }
    else if (text.Mid(pos,10) == L"UPPERCASE]")
    {
      newStyle = FONT_STYLE_UPPERCASE;
      pos += 10;
    }
    else if (text.Mid(pos,10) == L"LOWERCASE]")
    {
      newStyle = FONT_STYLE_LOWERCASE;
      pos += 10;
    }
    else if (text.Mid(pos,3) == L"CR]" && on)
    {
      newLine = true;
      pos += 3;
    }
    else if (text.Mid(pos,5) == L"COLOR")
    { // color
      size_t finish = text.Find(L']', pos + 5);
      if (on && finish != CStdString::npos)
      { // create new color
        newColor = colors.size();
        colors.push_back(g_colorManager.GetColor(text.Mid(pos + 5, finish - pos - 5)));
        colorStack.push(newColor);
      }
      else if (!on && finish == pos + 5)
      { // revert to previous color
        if (colorStack.size() > 1)
          colorStack.pop();
        newColor = colorStack.top();
      }
      pos = finish + 1;
    }

    if (newStyle || newColor != currentColor || newLine)
    { // we have a new style or a new color, so format up the previous segment
      CStdStringW subText = text.Mid(startPos, endPos - startPos);
      if (currentStyle & FONT_STYLE_UPPERCASE)
        subText.ToUpper();
      if (currentStyle & FONT_STYLE_LOWERCASE)
        subText.ToLower();
      AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText);
      if (newLine)
        parsedText.push_back(L'\n');

      // and switch to the new style
      startPos = pos;
      currentColor = newColor;
      if (on)
        currentStyle |= newStyle;
      else
        currentStyle &= ~newStyle;
    }
    pos = text.Find(L'[',pos);
  }
  // now grab the remainder of the string
  CStdStringW subText = text.Mid(startPos, text.GetLength() - startPos);
  if (currentStyle & FONT_STYLE_UPPERCASE)
    subText.ToUpper();
  if (currentStyle & FONT_STYLE_LOWERCASE)
    subText.ToLower();
  AppendToUTF32(subText, ((currentStyle & 3) << 24) | (currentColor << 16), parsedText);
}