예제 #1
0
Document DOMImplementationImp::createHTMLDocument(const std::u16string& title)
{
    try {
        DocumentPtr document = std::make_shared<DocumentImp>();
        document->setContentType(u"text/html");
        DocumentType doctype = createDocumentType(u"html", u"", u"");    // TODO: set node document
        document->appendChild(doctype);
        Element html = document->createElement(u"html");
        document->appendChild(html);
        Element head = document->createElement(u"head");
        html.appendChild(head);
        if (!title.empty()) {
            Element t = document->createElement(u"title");
            head.appendChild(t);
            Text text = document->createTextNode(title);
            t.appendChild(text);
        }
        Element body = document->createElement(u"body");
        html.appendChild(body);
        // TODO: Step 8.
        return document;
    } catch (...) {
        return nullptr;
    }
}
예제 #2
0
void KMX_Environment::Load(std::u16string const & key, std::u16string const & value) {
  assert(!key.empty());

  if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_PLATFORM)) {
    _platform = value;
  }
  else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUT)) {
    _baseLayout = value;
  }
  else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTALT)) {
    _baseLayoutAlt = value;
  }
  else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_SIMULATEALTGR)) {
    _simulateAltGr = value == u"1";
  }
  else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_CAPSLOCK)) {
    _capsLock = value == u"1";
  }
  else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT)) {
    _baseLayoutGivesCtrlRAltForRAlt = value == u"1";
  }
  else {
    // Unsupported key
    assert(false);
  }
}
예제 #3
0
파일: customstyle.cpp 프로젝트: Try/Tempest
void CustomStyle::draw(Painter &p, const std::u16string &text, Style::TextElement elt,
                       const WidgetState& st, const Rect &r, const Style::Extra &extra) const {
  const Margin& m = extra.margin;


  p.setFont (font);
  p.translate(r.x,r.y);

  const Sprite& icon = iconSprite(extra.icon,st,r);
  int dX=0;

  if( !icon.size().isEmpty() && elt!=TE_CheckboxTitle ){
    p.setColor(Color(1.f));
    p.setTexture( icon );
    if( text.empty() ) {
      p.drawRect( (r.w-icon.w())/2, (r.h-icon.h())/2, icon.w(), icon.h() );
      } else {
      p.drawRect( m.left, (r.h-icon.h())/2, icon.w(), icon.h() );
      }
    }

  switch( elt ){
    case TE_LabelTitle:
    case TE_CheckboxTitle:
      p.setColor(Color(0,0,0,1));
      break;
    default:
      p.setColor(extra.fontColor);
    }

  const Size txtSz=extra.font.textSize(text);
  p.drawText( m.left+dX+(r.w-dX-m.xMargin()-txtSz.w)/2, (r.h-txtSz.h)/2, r.w-m.xMargin(), txtSz.h, text, AlignBottom );

  p.translate(-r.x,-r.y);
  }
void MediaListImp::setMediaText(const std::u16string& mediaText)
{
    clear();
    if (!mediaText.empty()) {
        CSSParser parser;
        *this = *parser.parseMediaList(mediaText);
    }
}
예제 #5
0
bool UTF16ToUTF8(const std::u16string& utf16, std::string& outUtf8)
{
    if (utf16.empty())
    {
        outUtf8.clear();
        return true;
    }

    return llvm::convertUTF16ToUTF8String(utf16, outUtf8);
}
예제 #6
0
void LineEdit::IntValidator::erase(std::u16string &string,
                                   size_t &scursor,
                                   size_t &ecursor) const {
  Validator::erase(string,scursor,ecursor);
  if(string.size()==1 && string[0]=='-')
    string[0] = '0';

  if(string.empty())
    string.push_back('0');
  }
bool HTMLElementImp::toUnsigned(std::u16string& value)
{
    stripLeadingAndTrailingWhitespace(value);
    if (value.empty())
        return false;
    const char16_t* s = value.c_str();
    while (*s) {
        if (!isDigit(*s))
            return false;
        ++s;
    }
    return true;
}
    void WordSuggest::suggest(std::u16string input, Dictionary const * pDictionary, std::u16string& rBestSuggestion)
    {
        // Clear up
        mSuggestions.clear();
        mThresholds.clear();

        // Fallback for suggestion
        rBestSuggestion = u"";

        // Only do something when there is input
        if (!input.empty())
        {
            // Decide whether word should start with big letter
            bool startsWithUpperCase = false;
            char16_t lowerCaseLetter = input[0];
            if (toLower(lowerCaseLetter))
            {
                startsWithUpperCase = lowerCaseLetter != input[0];
            }

            // Ask for suggestions
            std::vector<std::u16string> suggestions = pDictionary->similarWords(input, startsWithUpperCase);
            uint i = 0;
            for (const std::u16string& rSuggestion : suggestions)
            {
                mSuggestions.push_back(std::move(mpAssetManager->createTextSimple(mFontSize, 1, rSuggestion)));

                // Only add maximal allowed number of suggestions
                if (++i >= WORD_SUGGEST_MAX_SUGGESTIONS)
                {
                    break;
                }
            }

            // Save best suggestion
            if (!suggestions.empty())
            {
                // First one is best
                rBestSuggestion = suggestions[0];
            }

            // Prepare thresholds
            mThresholds.resize(mSuggestions.size(), LerpValue(0));

            // Transform and position the suggestions initially
            transformSuggestions();
            positionSuggestions();
        }
    }
예제 #9
0
void LineEdit::IntValidator::insert(std::u16string &string,
                                    size_t &cursor, size_t &ecursor,
                                    char16_t data) const {
  if( cursor==0 ){
    if(!string.empty() && string[0]=='-')
      return;

    if(data=='-' && !(string.size()>=1 && string[0]=='0')){
      Validator::insert(string,cursor,ecursor,data);
      return;
      }

    if(data=='0' && ((string.size()==1 && string[0]=='-') || string.size()==0)){
      Validator::insert(string,cursor,ecursor,data);
      return;
      }

    if(('1'<=data && data<='9') || data=='-'){
      Validator::insert(string,cursor,ecursor,data);
      return;
      }
    return;
    }

  const size_t pos = cursor-1;
  if( data=='0'
      && !(pos<string.size() && string[pos]=='-')
      && !(string.size()==1 && string[0]=='0') ){
    Validator::insert(string,cursor,ecursor,data);
    return;
    }

  if('1'<=data && data<='9'){
    if(string.size()==1 && string[0]=='0'){
      string.clear();
      cursor  = 0;
      ecursor = cursor;
      }
    Validator::insert(string,cursor,ecursor,data);
    return;
    }
  }
bool convertUTF16ToUTF8String(const std::u16string& utf16, std::string &Out) {
  assert(Out.empty());

  // Avoid OOB by returning early on empty input.
  if (utf16.empty())
    return true;

  const UTF16 *Src = reinterpret_cast<const UTF16 *>(utf16.data());
  const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(utf16.data() + utf16.length());

  // Byteswap if necessary.
  std::vector<UTF16> ByteSwapped;
  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
    ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
    for (size_t I = 0, E = ByteSwapped.size(); I != E; ++I)
      ByteSwapped[I] = SwapByteOrder_16(ByteSwapped[I]);
    Src = &ByteSwapped[0];
    SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1;
  }

  // Skip the BOM for conversion.
  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_NATIVE)
    Src++;

  // Just allocate enough space up front.  We'll shrink it later.
  Out.resize(utf16.length() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
  UTF8 *Dst = reinterpret_cast<UTF8 *>(&Out[0]);
  UTF8 *DstEnd = Dst + Out.size();

  ConversionResult CR =
      ConvertUTF16toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
  assert(CR != targetExhausted);

  if (CR != conversionOK) {
    Out.clear();
    return false;
  }

  Out.resize(reinterpret_cast<char *>(Dst) - &Out[0]);
  return true;
}
    std::vector<TextFlow::Word> TextFlow::calculateFitWord(std::u16string content, int maxPixelWidth, float scale) const
    {
        // Calculate word from content
        Word word = calculateWord(content, scale);

        // End of recursion
        if ((content.size() == 1 && word.pixelWidth > maxPixelWidth) || content.empty())
        {
            // Return empty vector as signal of failure
            return std::vector<Word>();
        }
        else if (word.pixelWidth <= maxPixelWidth)
        {
            // If word length is ok, just return it
            return std::vector<Word>(1, word);
        }
        else
        {
            // Word is too wide and content longer than 1, split it!
            int length = (int)content.size();
            int left = length / 2;
            int right = length - left;

            // Combine results from recursive call
            std::vector<Word> leftWord = calculateFitWord(content.substr(0, left), maxPixelWidth, scale);
            std::vector<Word> rightWord = calculateFitWord(content.substr(left+1, right), maxPixelWidth, scale);

            // If one or more of both are empty, forget it
            if (leftWord.empty() || rightWord.empty())
            {
                return std::vector<Word>();
            }
            else
            {
                std::vector<Word> words(leftWord);
                words.insert(words.end(), rightWord.begin(), rightWord.end());
                return words;
            }
        }
    }
bool HTMLElementImp::toPxOrPercentage(std::u16string& value)
{
    stripLeadingAndTrailingWhitespace(value);
    if (value.empty())
        return false;
    const char16_t* s = value.c_str();
    while (*s) {
        if (*s == '%')
            break;
        if (!isDigit(*s))
            return false;
        ++s;
    }
    if (!*s) {
        value += u"px";
        return true;
    }
    assert(*s == '%');
    if (!s[1] && 1 < value.length())
        return true;
    return false;
}
    bool TextFlow::insertFitWord(std::vector<TextFlow::Word>& rWords, const std::u16string& rContent, int maxPixelWidth, float scale) const
    {
        // Do nothing if input is empty
        if (rContent.empty())
        {
            return true;
        }

        std::vector<Word> newWords = calculateFitWord(rContent, maxPixelWidth, scale);

        // Check, whether call was successful
        if (newWords.empty())
        {
            // Was not successful, so return false
            return false;
        }
        else
        {
            // Insert new words and return true
            rWords.insert(rWords.end(), newWords.begin(), newWords.end());
            return true;
        }
    }
예제 #14
0
void RenderString::CreateRenderCharacters(const std::u16string& newString) {
	if (!newString.empty() && mFont) {
		int advanceAccum = 0; // the accumulated horizontal advance for the current line
		int kerningAccum = 0; // the accumulated kerning offset for the current line
		int lineOffset = 0; // the vertical offset of the current line
		int lineHeight = mFont->GetLineHeight(); // retrieve and store the new line offset
		
		if (!mString.empty() && !mRenderChars.empty()) { // if we already have characters entered...
			if (mString.back() == u'\n') { // if the last character entered was a new line...
				lineOffset = mRenderChars.back().mLineHeight + lineHeight; // adjust the line offset for following characters
			}
			else {
				// laod the states of the accumulators from the previous characters entered
				advanceAccum = mRenderChars.back().mAdvanceAccum;
				kerningAccum = mRenderChars.back().mKerningAccum;
				lineOffset = mRenderChars.back().mLineHeight;
				
				kerningAccum += mFont->GetKerning(mString.back(), newString.front()); // adjust the kerning offset for the new character
			}
		}
		
		for (unsigned int i = 0u; i < newString.size(); ++i) {
			char16_t codePoint = newString.at(i);
			
			if (codePoint == u'\n') { // if the current character is a new line...
				advanceAccum = 0; // reset the horizontal advance
				kerningAccum = 0; // reset the kerning offset
				lineOffset += lineHeight; // increment the vertical offset by the new line height
				continue; // go to the next character
			}
			
			try {
				const FontBase::Glyph& glyph = mFont->GetGlyph(codePoint); // get the glyph object for the current character
				Shape shape = glyph.mBaseShape; // get the glyph shape from the glyph object
				float height = 0.0f; // the height of the glyph shape used for positional offsetting
				
				{
					const std::vector<glm::vec2>& bbox = shape.GetLocalBoundingBox(); // get the bounding box of the glyph
					if (!bbox.empty()) { // if the bounding box is valid...
						height = bbox.at(2).y - bbox.at(0).y; // calculate the height of the glyph shape
					}
				}
				
				shape.SetPosition(glm::vec2((advanceAccum + kerningAccum) + glyph.mBearing.x,
						((mFont->GetBearingMax().y - glyph.mBearing.y) - mFont->GetBearingMax().y) + lineOffset)); // position the glyph shape
				
				{ // update the local bounding box
					// get the bounding box of the newly added character
					std::vector<glm::vec2> bbox = shape.GetGlobalBoundingBox();
					
					if (bbox.size() > 3) { // if the bounding box is valid...
						mTopLeft.x = std::min(bbox.at(0).x, mTopLeft.x);
						mTopLeft.y = std::min(bbox.at(0).y, mTopLeft.y);
						
						mBottomRight.x = std::max(bbox.at(2).x, mBottomRight.x);
						mBottomRight.y = std::max(bbox.at(2).y, mBottomRight.y);
					}
				}
				
				advanceAccum += glyph.mAdvance; // increment the horizontal advance accumulator by the current glyph's advance metric
				if (i != newString.size() - 1) { // if this is not the final character in the string...
					kerningAccum += mFont->GetKerning(codePoint, newString.at(i + 1)); // increment the kerning offset by the kerning value of this and the next character
				}
				
				mRenderChars.push_back({std::move(shape), advanceAccum, kerningAccum, lineOffset,
						mTopLeft, mBottomRight});
			} catch(std::exception& e) {
				std::cout << "unknown codepoint: " << codePoint << std::endl;
			}
		}
		
		// update the full sized (not yet scaled) local bounding box
		glm::vec2 dimensions = mBottomRight - mTopLeft;
		mLocalBoundingBoxFull.clear();
		mLocalBoundingBoxFull.emplace_back(0.0f, 0.0f);
		mLocalBoundingBoxFull.emplace_back(dimensions.x, 0.0f);
		mLocalBoundingBoxFull.emplace_back(dimensions.x, dimensions.y);
		mLocalBoundingBoxFull.emplace_back(0.0f, dimensions.y);
	}
}